001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.heap;
042:
043: import java.util.ArrayList;
044: import java.util.Collection;
045: import java.util.HashMap;
046: import java.util.Iterator;
047: import java.util.List;
048: import java.util.Map;
049:
050: /**
051: *
052: * @author Tomas Hurka
053: */
054: class ClassDumpSegment extends TagBounds {
055: //~ Instance fields ----------------------------------------------------------------------------------------------------------
056:
057: HprofHeap hprofHeap;
058: Map /*<JavaClass represeting array,Integer - allInstanceSize>*/arrayMap;
059: final int classIDOffset;
060: final int classLoaderIDOffset;
061: final int constantPoolSizeOffset;
062: final int fieldNameIDOffset;
063: final int fieldSize;
064: final int fieldTypeOffset;
065: final int fieldValueOffset;
066: final int instanceSizeOffset;
067: final int minimumInstanceSize;
068: final int protectionDomainIDOffset;
069: final int reserved1;
070: final int reserver2;
071: final int signersID;
072: final int stackTraceSerialNumberOffset;
073: final int super ClassIDOffset;
074: ClassDump java_lang_Class;
075: private List /*<JavaClass>*/classes;
076: private Map /*<Byte,JavaClass>*/primitiveArrayMap;
077:
078: //~ Constructors -------------------------------------------------------------------------------------------------------------
079:
080: ClassDumpSegment(HprofHeap heap, long start, long end) {
081: super (HprofHeap.CLASS_DUMP, start, end);
082:
083: int idSize = heap.dumpBuffer.getIDSize();
084: hprofHeap = heap;
085: // initialize offsets
086: classIDOffset = 1;
087: stackTraceSerialNumberOffset = classIDOffset + idSize;
088: super ClassIDOffset = stackTraceSerialNumberOffset + 4;
089: classLoaderIDOffset = super ClassIDOffset + idSize;
090: signersID = classLoaderIDOffset + idSize;
091: protectionDomainIDOffset = signersID + idSize;
092: reserved1 = protectionDomainIDOffset + idSize;
093: reserver2 = reserved1 + idSize;
094: instanceSizeOffset = reserver2 + idSize;
095: constantPoolSizeOffset = instanceSizeOffset + 4;
096:
097: fieldNameIDOffset = 0;
098: fieldTypeOffset = fieldNameIDOffset + idSize;
099: fieldValueOffset = fieldTypeOffset + 1;
100:
101: fieldSize = fieldTypeOffset + 1;
102:
103: minimumInstanceSize = 2 * idSize;
104: }
105:
106: //~ Methods ------------------------------------------------------------------------------------------------------------------
107:
108: ClassDump getClassDumpByID(long classObjectID) {
109: if (classObjectID == 0) {
110: return null;
111: }
112:
113: LongMap.Entry entry = hprofHeap.idToOffsetMap
114: .get(classObjectID);
115:
116: if (entry != null) {
117: try {
118: return (ClassDump) classes.get(entry.getIndex() - 1);
119: } catch (ArrayIndexOutOfBoundsException ex) { // classObjectID do not reffer to ClassDump, its instance number is > classes.size()
120:
121: return null;
122: } catch (ClassCastException ex) { // classObjectID do not reffer to ClassDump
123:
124: return null;
125: }
126: }
127:
128: return null;
129: }
130:
131: JavaClass getJavaClassByName(String fqn) {
132: Iterator classIt = classes.iterator();
133:
134: while (classIt.hasNext()) {
135: ClassDump cls = (ClassDump) classIt.next();
136:
137: if (fqn.equals(cls.getName())) {
138: return cls;
139: }
140: }
141:
142: return null;
143: }
144:
145: int getMinimumInstanceSize() {
146: return minimumInstanceSize;
147: }
148:
149: ClassDump getPrimitiveArrayClass(byte type) {
150: ClassDump primitiveArray = (ClassDump) primitiveArrayMap
151: .get(Integer.valueOf(type));
152:
153: if (primitiveArray == null) {
154: throw new IllegalArgumentException("Invalid type " + type); // NOI18N
155: }
156:
157: return primitiveArray;
158: }
159:
160: Map getClassIdToClassMap() {
161: Map map = new HashMap(classes.size() * 4 / 3);
162: Iterator classIt = classes.iterator();
163:
164: while (classIt.hasNext()) {
165: ClassDump cls = (ClassDump) classIt.next();
166:
167: map.put(new Long(cls.getJavaClassId()), cls);
168: }
169: return map;
170: }
171:
172: void addInstanceSize(ClassDump cls, int tag, long instanceOffset) {
173: if ((tag == HprofHeap.OBJECT_ARRAY_DUMP)
174: || (tag == HprofHeap.PRIMITIVE_ARRAY_DUMP)) {
175: Integer sizeInt = (Integer) arrayMap.get(cls);
176: int size = 0;
177: HprofByteBuffer dumpBuffer = hprofHeap.dumpBuffer;
178: int idSize = dumpBuffer.getIDSize();
179: long elementsOffset = instanceOffset + 1 + idSize + 4;
180:
181: if (sizeInt != null) {
182: size = sizeInt.intValue();
183: }
184:
185: int elements = dumpBuffer.getInt(elementsOffset);
186: int elSize;
187:
188: if (tag == HprofHeap.PRIMITIVE_ARRAY_DUMP) {
189: elSize = hprofHeap.getValueSize(dumpBuffer
190: .get(elementsOffset + 4));
191: } else {
192: elSize = idSize;
193: }
194:
195: size += (getMinimumInstanceSize() + (elements * elSize));
196: arrayMap.put(cls, Integer.valueOf(size));
197: }
198: }
199:
200: List /*<JavaClass>*/createClassCollection() {
201: if (classes != null) {
202: return classes;
203: }
204:
205: classes = new ArrayList /*<JavaClass>*/(1000);
206:
207: long[] offset = new long[] { startOffset };
208:
209: while (offset[0] < endOffset) {
210: long start = offset[0];
211: int tag = hprofHeap.readDumpTag(offset);
212:
213: if (tag == HprofHeap.CLASS_DUMP) {
214: ClassDump classDump = new ClassDump(this , start);
215: long classId = classDump.getJavaClassId();
216:
217: classes.add(classDump);
218: hprofHeap.idToOffsetMap.put(classId, start);
219: hprofHeap.idToOffsetMap.get(classId).setIndex(
220: classes.size());
221: }
222: }
223:
224: hprofHeap.getLoadClassSegment().setLoadClassOffsets();
225: arrayMap = new HashMap(classes.size() / 15);
226: extractSpecialClasses();
227:
228: return classes;
229: }
230:
231: List findStaticReferencesFor(long instanceId) {
232: List refs = new ArrayList();
233: Iterator classIt = classes.iterator();
234:
235: while (classIt.hasNext()) {
236: ClassDump cls = (ClassDump) classIt.next();
237:
238: cls.findStaticReferencesFor(instanceId, refs);
239: }
240:
241: return refs;
242: }
243:
244: private void extractSpecialClasses() {
245: primitiveArrayMap = new HashMap();
246:
247: Iterator classIt = classes.iterator();
248:
249: while (classIt.hasNext()) {
250: ClassDump jcls = (ClassDump) classIt.next();
251: String vmName = jcls.getLoadClass().getVMName();
252: Integer typeObj = null;
253:
254: if (vmName.equals("[Z")) { // NOI18N
255: typeObj = Integer.valueOf(HprofHeap.BOOLEAN);
256: } else if (vmName.equals("[C")) { // NOI18N
257: typeObj = Integer.valueOf(HprofHeap.CHAR);
258: } else if (vmName.equals("[F")) { // NOI18N
259: typeObj = Integer.valueOf(HprofHeap.FLOAT);
260: } else if (vmName.equals("[D")) { // NOI18N
261: typeObj = Integer.valueOf(HprofHeap.DOUBLE);
262: } else if (vmName.equals("[B")) { // NOI18N
263: typeObj = Integer.valueOf(HprofHeap.BYTE);
264: } else if (vmName.equals("[S")) { // NOI18N
265: typeObj = Integer.valueOf(HprofHeap.SHORT);
266: } else if (vmName.equals("[I")) { // NOI18N
267: typeObj = Integer.valueOf(HprofHeap.INT);
268: } else if (vmName.equals("[J")) { // NOI18N
269: typeObj = Integer.valueOf(HprofHeap.LONG);
270: } else if (vmName.equals("java/lang/Class")) { // NOI18N
271: java_lang_Class = jcls;
272: } else if (vmName.equals("boolean[]")) { // NOI18N
273: typeObj = Integer.valueOf(HprofHeap.BOOLEAN);
274: } else if (vmName.equals("char[]")) { // NOI18N
275: typeObj = Integer.valueOf(HprofHeap.CHAR);
276: } else if (vmName.equals("float[]")) { // NOI18N
277: typeObj = Integer.valueOf(HprofHeap.FLOAT);
278: } else if (vmName.equals("double[]")) { // NOI18N
279: typeObj = Integer.valueOf(HprofHeap.DOUBLE);
280: } else if (vmName.equals("byte[]")) { // NOI18N
281: typeObj = Integer.valueOf(HprofHeap.BYTE);
282: } else if (vmName.equals("short[]")) { // NOI18N
283: typeObj = Integer.valueOf(HprofHeap.SHORT);
284: } else if (vmName.equals("int[]")) { // NOI18N
285: typeObj = Integer.valueOf(HprofHeap.INT);
286: } else if (vmName.equals("long[]")) { // NOI18N
287: typeObj = Integer.valueOf(HprofHeap.LONG);
288: } else if (vmName.equals("java.lang.Class")) { // NOI18N
289: java_lang_Class = jcls;
290: }
291:
292: if (typeObj != null) {
293: primitiveArrayMap.put(typeObj, jcls);
294: }
295: }
296: }
297: }
|