private static long headerSize(BasicType type) { if (Universe.elementTypeShouldBeAligned(type)) { return alignObjectSize(headerSizeInBytes()) / VM.getVM().getHeapWordSize(); } else { return headerSizeInBytes() / VM.getVM().getHeapWordSize(); } }
private long lengthOffsetInBytes() { if (lengthOffsetInBytes != 0) { return lengthOffsetInBytes; } if (VM.getVM().isCompressedOopsEnabled()) { lengthOffsetInBytes = typeSize - VM.getVM().getIntSize(); } else { lengthOffsetInBytes = typeSize; } return lengthOffsetInBytes; }
private static long headerSizeInBytes() { if (headerSize != 0) { return headerSize; } if (VM.getVM().isCompressedOopsEnabled()) { headerSize = typeSize; } else { headerSize = VM.getVM().alignUp(typeSize + VM.getVM().getIntSize(), VM.getVM().getHeapWordSize()); } return headerSize; }
// "size helper" == instance size in words public long getSizeHelper() { int lh = getLayoutHelper(); if (Assert.ASSERTS_ENABLED) { Assert.that(lh > 0, "layout helper initialized for instance class"); } return lh / VM.getVM().getAddressSize(); }
public void forEachObject(Object[] args) { boolean subtypes = true; Klass kls = null; Callable func = null; switch (args.length) { case 3: { Object b = args[2]; if (b != null && b instanceof Boolean) { subtypes = ((Boolean) b).booleanValue(); } } case 2: { Object k = args[1]; if (k == null) return; if (k instanceof JSJavaKlass) { kls = ((JSJavaKlass) k).getKlass(); } else if (k instanceof String) { kls = SystemDictionaryHelper.findInstanceKlass((String) k); if (kls == null) return; } } case 1: { Object f = args[0]; if (f != null && f instanceof Callable) { func = (Callable) f; } else { // unknown target - just return return; } } break; default: return; } final Callable finalFunc = func; HeapVisitor visitor = new DefaultHeapVisitor() { public boolean doObj(Oop oop) { JSJavaObject jo = factory.newJSJavaObject(oop); if (jo != null) { try { finalFunc.call(new Object[] {jo}); } catch (ScriptException exp) { throw new RuntimeException(exp); } } return false; } }; ObjectHeap heap = VM.getVM().getObjectHeap(); if (kls == null) { kls = SystemDictionaryHelper.findInstanceKlass("java.lang.Object"); } heap.iterateObjectsOfKlass(visitor, kls, subtypes); }
static { VM.registerVMInitializedObserver( new Observer() { public void update(Observable o, Object data) { initialize(VM.getVM().getTypeDataBase()); } }); }
private static void initialize(TypeDataBase db) { Type type = db.lookupType("oopDesc"); if (VM.getVM().isCompressedOopsEnabled()) { klassField = type.getNarrowOopField("_metadata._compressed_klass"); } else { klassField = type.getOopField("_metadata._klass"); } }
/** Convenience routine taking Strings; lookup is done in SymbolTable. */ public Method findMethod(String name, String sig) { SymbolTable syms = VM.getVM().getSymbolTable(); Symbol nameSym = syms.probe(name); Symbol sigSym = syms.probe(sig); if (nameSym == null || sigSym == null) { return null; } return findMethod(nameSym, sigSym); }
private void iterateOops( final InstanceKlass ik, final ObjectVisitor visitor, boolean includeSubtypes) { ObjectHeap oh = VM.getVM().getObjectHeap(); oh.iterateObjectsOfKlass( new HeapVisitor() { boolean filterExists; public void prologue(long usedSize) { filterExists = getScriptEngine().get("filter") != null; } public boolean doObj(Oop obj) { dispatchObject(obj, visitor, filterExists); return false; } public void epilogue() {} }, ik, includeSubtypes); }
public static boolean oopLooksValid(OopHandle oop) { if (oop == null) { return false; } if (!VM.getVM().getUniverse().isIn(oop)) { return false; } try { for (int i = 0; i < 4; ++i) { OopHandle next = klassField.getValue(oop); if (next == null) { return false; } if (next.equals(oop)) { return true; } oop = next; } return false; } catch (AddressException e) { return false; } }
// Creates new field from index in fields TypeArray private Field newField(int index) { TypeArray fields = getFields(); short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET); FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex)); if (type.isOop()) { if (VM.getVM().isCompressedOopsEnabled()) { return new NarrowOopField(this, index); } else { return new OopField(this, index); } } if (type.isByte()) { return new ByteField(this, index); } if (type.isChar()) { return new CharField(this, index); } if (type.isDouble()) { return new DoubleField(this, index); } if (type.isFloat()) { return new FloatField(this, index); } if (type.isInt()) { return new IntField(this, index); } if (type.isLong()) { return new LongField(this, index); } if (type.isShort()) { return new ShortField(this, index); } if (type.isBoolean()) { return new BooleanField(this, index); } throw new RuntimeException("Illegal field type at index " + index); }
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { Type type = db.lookupType("methodOopDesc"); constMethod = new OopField(type.getOopField("_constMethod"), 0); constants = new OopField(type.getOopField("_constants"), 0); methodSize = new CIntField(type.getCIntegerField("_method_size"), 0); maxStack = new CIntField(type.getCIntegerField("_max_stack"), 0); maxLocals = new CIntField(type.getCIntegerField("_max_locals"), 0); sizeOfParameters = new CIntField(type.getCIntegerField("_size_of_parameters"), 0); accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0); code = type.getAddressField("_code"); vtableIndex = new CIntField(type.getCIntegerField("_vtable_index"), 0); if (!VM.getVM().isCore()) { invocationCounter = new CIntField(type.getCIntegerField("_invocation_counter"), 0); } bytecodeOffset = type.getSize(); /* interpreterEntry = type.getAddressField("_interpreter_entry"); fromCompiledCodeEntryPoint = type.getAddressField("_from_compiled_code_entry_point"); */ objectInitializerName = null; classInitializerName = null; }
private static Symbol javaLangCloneableName() { if (javaLangCloneableName == null) { javaLangCloneableName = VM.getVM().getSymbolTable().probe("java/lang/Cloneable"); } return javaLangCloneableName; }
private long getUsed() { return VM.getVM().getUniverse().heap().used(); }
private static Symbol objectInitializerName() { if (objectInitializerName == null) { objectInitializerName = VM.getVM().getSymbolTable().probe("<init>"); } return objectInitializerName; }
// Accessors for declared fields public long getLength() { boolean isUnsigned = true; return this.getHandle() .getCIntegerAt(lengthOffsetInBytes(), VM.getVM().getIntSize(), isUnsigned); }
private static Symbol classInitializerName() { if (classInitializerName == null) { classInitializerName = VM.getVM().getSymbolTable().probe("<clinit>"); } return classInitializerName; }
public long getInvocationCounter() { if (Assert.ASSERTS_ENABLED) { Assert.that(!VM.getVM().isCore(), "must not be used in core build"); } return invocationCounter.getValue(this); }
public static long baseOffsetInBytes(BasicType type) { return headerSize(type) * VM.getVM().getHeapWordSize(); }
private long getCapacity() { return VM.getVM().getUniverse().heap().capacity(); }
private static Symbol javaLangObjectName() { if (javaLangObjectName == null) { javaLangObjectName = VM.getVM().getSymbolTable().probe("java/lang/Object"); } return javaLangObjectName; }
private static Symbol javaIoSerializableName() { if (javaIoSerializableName == null) { javaIoSerializableName = VM.getVM().getSymbolTable().probe("java/io/Serializable"); } return javaIoSerializableName; }
/** Runs the analysis algorithm */ public void run() { if (VM.getVM().getRevPtrs() != null) { return; // Assume already done } VM vm = VM.getVM(); rp = new ReversePtrs(); vm.setRevPtrs(rp); Universe universe = vm.getUniverse(); CollectedHeap collHeap = universe.heap(); usedSize = collHeap.used(); visitedSize = 0; // Note that an experiment to iterate the heap linearly rather // than in recursive-descent order has been done. It turns out // that the recursive-descent algorithm is nearly twice as fast // due to the fact that it scans only live objects and (currently) // only a fraction of the perm gen, namely the static fields // contained in instanceKlasses. (Iterating the heap linearly // would also change the semantics of the result so that // ReversePtrs.get() would return a non-null value even for dead // objects.) Nonetheless, the reverse pointer computation is still // quite slow and optimization in field iteration of objects // should be done. if (progressThunk != null) { // Get it started progressThunk.heapIterationFractionUpdate(0); } // Allocate mark bits for heap markBits = new MarkBits(collHeap); // Get a hold of the object heap heap = vm.getObjectHeap(); // Do each thread's roots for (JavaThread thread = VM.getVM().getThreads().first(); thread != null; thread = thread.next()) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); String threadDesc = " in thread \"" + thread.getThreadName() + "\" (id " + bos.toString() + ")"; doStack(thread, new RootVisitor("Stack root" + threadDesc)); doJNIHandleBlock(thread.activeHandles(), new RootVisitor("JNI handle root" + threadDesc)); } // Do global JNI handles JNIHandles handles = VM.getVM().getJNIHandles(); doJNIHandleBlock(handles.globalHandles(), new RootVisitor("Global JNI handle root")); doJNIHandleBlock(handles.weakGlobalHandles(), new RootVisitor("Weak global JNI handle root")); // Do Java-level static fields SystemDictionary sysDict = VM.getVM().getSystemDictionary(); sysDict.allClassesDo( new SystemDictionary.ClassVisitor() { public void visit(Klass k) { if (k instanceof InstanceKlass) { final InstanceKlass ik = (InstanceKlass) k; ik.iterateStaticFields( new DefaultOopVisitor() { public void doOop(OopField field, boolean isVMField) { Oop next = field.getValue(getObj()); NamedFieldIdentifier nfi = new NamedFieldIdentifier( "Static field \"" + field.getID().getName() + "\" in class \"" + ik.getName().asString() + "\""); LivenessPathElement lp = new LivenessPathElement(null, nfi); rp.put(lp, next); try { markAndTraverse(next); } catch (AddressException e) { System.err.print( "RevPtrs analysis: WARNING: AddressException at 0x" + Long.toHexString(e.getAddress()) + " while traversing static fields of InstanceKlass "); ik.printValueOn(System.err); System.err.println(); } catch (UnknownOopException e) { System.err.println( "RevPtrs analysis: WARNING: UnknownOopException while " + "traversing static fields of InstanceKlass "); ik.printValueOn(System.err); System.err.println(); } } }); } } }); if (progressThunk != null) { progressThunk.heapIterationComplete(); } // Clear out markBits markBits = null; }
public Klass getJavaSuper() { SystemDictionary sysDict = VM.getVM().getSystemDictionary(); return sysDict.getObjectKlass(); }
public void forEachClass(Object[] args) { boolean withLoader = false; Callable func = null; switch (args.length) { case 2: { Object b = args[1]; if (b instanceof Boolean) { withLoader = ((Boolean) b).booleanValue(); } } case 1: { Object f = args[0]; if (f instanceof Callable) { func = (Callable) f; } else { return; } } break; default: return; } final Callable finalFunc = func; SystemDictionary sysDict = VM.getVM().getSystemDictionary(); if (withLoader) { sysDict.classesDo( new SystemDictionary.ClassAndLoaderVisitor() { public void visit(Klass kls, Oop loader) { JSJavaKlass jk = factory.newJSJavaKlass(kls); if (jk == null) { return; } JSJavaObject k = jk.getJSJavaClass(); JSJavaObject l = factory.newJSJavaObject(loader); if (k != null) { if (k != null) { try { finalFunc.call(new Object[] {k, l}); } catch (ScriptException exp) { throw new RuntimeException(exp); } } } } }); } else { sysDict.classesDo( new SystemDictionary.ClassVisitor() { public void visit(Klass kls) { JSJavaKlass jk = factory.newJSJavaKlass(kls); if (jk == null) { return; } JSJavaClass k = jk.getJSJavaClass(); if (k != null) { if (k != null) { try { finalFunc.call(new Object[] {k}); } catch (ScriptException exp) { throw new RuntimeException(exp); } } } } }); } }