# HG changeset patch # User trims # Date 1296804385 28800 # Node ID ae4b185f2ed14af7bab610738c333840598cdcc4 # Parent 6ecdca5709dff14a4117b63c696d7335a806dcfa# Parent 3582bf76420e440f9d58d5bf6c9221a704c066ec Merge diff -r 6ecdca5709df -r ae4b185f2ed1 .hgtags --- a/.hgtags Thu Feb 03 17:22:06 2011 -0800 +++ b/.hgtags Thu Feb 03 23:26:25 2011 -0800 @@ -143,5 +143,6 @@ e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 jdk7-b125 4c851c931d001a882cab809aaf3a55371b919244 jdk7-b126 e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 hs20-b06 +d535bf4c12355a2897e918da9f8910c0aceec4fb hs20-b07 102466e70debc4b907afbd7624e34ddb1aafee9f jdk7-b127 9a5762f448595794d449a8e17342abd81a3fadaf jdk7-b128 diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java --- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Thu Feb 03 23:26:25 2011 -0800 @@ -428,6 +428,36 @@ } } }, + new Command("symbol", "symbol address", false) { + public void doit(Tokens t) { + if (t.countTokens() != 1) { + usage(); + } else { + Address a = VM.getVM().getDebugger().parseAddress(t.nextToken()); + Symbol.create(a).printValueOn(out); + out.println(); + } + } + }, + new Command("symboltable", "symboltable name", false) { + public void doit(Tokens t) { + if (t.countTokens() != 1) { + usage(); + } else { + out.println(SymbolTable.getTheTable().probe(t.nextToken())); + } + } + }, + new Command("symboldump", "symboldump", false) { + public void doit(Tokens t) { + SymbolTable.getTheTable().symbolsDo(new SymbolTable.SymbolVisitor() { + public void visit(Symbol sym) { + sym.printValueOn(out); + out.println(); + } + }); + } + }, new Command("flags", "flags [ flag ]", false) { public void doit(Tokens t) { int tokens = t.countTokens(); @@ -629,17 +659,6 @@ } } }, - new Command("symbol", "symbol name", false) { - public void doit(Tokens t) { - if (t.countTokens() != 1) { - usage(); - } else { - String symbol = t.nextToken(); - Address a = lookup(symbol); - out.println(symbol + " = " + a); - } - } - }, new Command("printstatics", "printstatics [ type ]", false) { public void doit(Tokens t) { if (t.countTokens() > 1) { @@ -1262,6 +1281,9 @@ this.err = err; for (int i = 0; i < commandList.length; i++) { Command c = commandList[i]; + if (commands.get(c.name) != null) { + throw new InternalError(c.name + " has multiple definitions"); + } commands.put(c.name, c); } if (debugger.isAttached()) { diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java --- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Thu Feb 03 23:26:25 2011 -0800 @@ -89,6 +89,37 @@ readVMLongConstants(); } + public Type lookupType(String cTypeName, boolean throwException) { + Type fieldType = super.lookupType(cTypeName, false); + if (fieldType == null && cTypeName.startsWith("const ")) { + fieldType = (BasicType)lookupType(cTypeName.substring(6), false); + } + if (fieldType == null && cTypeName.endsWith(" const")) { + fieldType = (BasicType)lookupType(cTypeName.substring(0, cTypeName.length() - 6), false); + } + if (fieldType == null) { + if (cTypeName.startsWith("GrowableArray<") && cTypeName.endsWith(">*")) { + String ttype = cTypeName.substring("GrowableArray<".length(), + cTypeName.length() - 2); + Type templateType = lookupType(ttype, false); + if (templateType == null && typeNameIsPointerType(ttype)) { + templateType = recursiveCreateBasicPointerType(ttype); + } + if (templateType == null) { + lookupOrFail(ttype); + } + fieldType = recursiveCreateBasicPointerType(cTypeName); + } + } + if (fieldType == null && typeNameIsPointerType(cTypeName)) { + fieldType = recursiveCreateBasicPointerType(cTypeName); + } + if (fieldType == null && throwException) { + super.lookupType(cTypeName, true); + } + return fieldType; + } + private void readVMTypes() { // Get the variables we need in order to traverse the VMTypeEntry[] long typeEntryTypeNameOffset; @@ -250,7 +281,7 @@ BasicType containingType = lookupOrFail(typeName); // The field's Type must already be in the database -- no exceptions - BasicType fieldType = lookupOrFail(typeString); + BasicType fieldType = (BasicType)lookupType(typeString); // Create field by type createField(containingType, fieldName, fieldType, @@ -442,10 +473,17 @@ workarounds due to incomplete information in the VMStructs database. */ private BasicPointerType recursiveCreateBasicPointerType(String typeName) { + BasicPointerType result = (BasicPointerType)super.lookupType(typeName, false); + if (result != null) { + return result; + } String targetTypeName = typeName.substring(0, typeName.lastIndexOf('*')).trim(); Type targetType = null; if (typeNameIsPointerType(targetTypeName)) { - targetType = recursiveCreateBasicPointerType(targetTypeName); + targetType = lookupType(targetTypeName, false); + if (targetType == null) { + targetType = recursiveCreateBasicPointerType(targetTypeName); + } } else { targetType = lookupType(targetTypeName, false); if (targetType == null) { @@ -466,6 +504,20 @@ BasicType basicTargetType = createBasicType(targetTypeName, false, true, true); basicTargetType.setSize(1); targetType = basicTargetType; + } else if (targetTypeName.startsWith("GrowableArray<")) { + BasicType basicTargetType = createBasicType(targetTypeName, false, false, false); + + // transfer fields from GenericGrowableArray to template instance + BasicType generic = lookupOrFail("GenericGrowableArray"); + basicTargetType.setSize(generic.getSize()); + Iterator fields = generic.getFields(); + while (fields.hasNext()) { + Field f = (Field)fields.next(); + basicTargetType.addField(internalCreateField(basicTargetType, f.getName(), + f.getType(), f.isStatic(), + f.getOffset(), null)); + } + targetType = basicTargetType; } else { if (DEBUG) { System.err.println("WARNING: missing target type \"" + targetTypeName + "\" for pointer type \"" + typeName + "\""); @@ -474,7 +526,10 @@ } } } - return new BasicPointerType(this, typeName, targetType); + result = new BasicPointerType(this, typeName, targetType); + result.setSize(UNINITIALIZED_SIZE); + addType(result); + return result; } private boolean typeNameIsPointerType(String typeName) { diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java Thu Feb 03 23:26:25 2011 -0800 @@ -112,7 +112,7 @@ } // return Symbol (if unresolved) or Klass (if resolved) - public Oop getKlass() { + public Object getKlass() { if (Assert.ASSERTS_ENABLED) { Assert.that(isKlassConstant(), "not a klass literal"); } @@ -121,11 +121,11 @@ // decide based on the oop type. ConstantPool cpool = method().getConstants(); int cpIndex = index(); - Oop oop = cpool.getObjAt(cpIndex); - if (oop.isKlass()) { - return (Klass) oop; - } else if (oop.isSymbol()) { - return (Symbol) oop; + ConstantPool.CPSlot oop = cpool.getSlotAt(cpIndex); + if (oop.isOop()) { + return (Klass) oop.getOop(); + } else if (oop.isMetaData()) { + return oop.getSymbol(); } else { throw new RuntimeException("should not reach here"); } @@ -165,12 +165,12 @@ // tag change from 'unresolved' to 'string' does not happen atomically. // We just look at the object at the corresponding index and // decide based on the oop type. - Oop obj = cpool.getObjAt(cpIndex); - if (obj.isSymbol()) { - Symbol sym = (Symbol) obj; - return ""; - } else if (obj.isInstance()) { - return ""; + ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex); + if (obj.isMetaData()) { + Symbol sym = obj.getSymbol(); + return ""; + } else if (obj.isOop()) { + return ""; } else { throw new RuntimeException("should not reach here"); } @@ -178,13 +178,13 @@ // tag change from 'unresolved' to 'klass' does not happen atomically. // We just look at the object at the corresponding index and // decide based on the oop type. - Oop obj = cpool.getObjAt(cpIndex); - if (obj.isKlass()) { - Klass k = (Klass) obj; - return ""; - } else if (obj.isSymbol()) { - Symbol sym = (Symbol) obj; - return ""; + ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex); + if (obj.isOop()) { + Klass k = (Klass) obj.getOop(); + return ""; + } else if (obj.isMetaData()) { + Symbol sym = obj.getSymbol(); + return ""; } else { throw new RuntimeException("should not reach here"); } diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithKlass.java --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithKlass.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithKlass.java Thu Feb 03 23:26:25 2011 -0800 @@ -37,11 +37,11 @@ } public Symbol getClassName() { - Oop obj = method().getConstants().getObjAt(index()); - if (obj instanceof Symbol) { - return (Symbol)obj; + ConstantPool.CPSlot obj = method().getConstants().getSlotAt(index()); + if (obj.isMetaData()) { + return obj.getSymbol(); } else { - return ((Klass)obj).getName(); + return ((Klass)obj.getOop()).getName(); } } diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java Thu Feb 03 23:26:25 2011 -0800 @@ -63,7 +63,7 @@ } public Klass klass() { - return (Klass) literal(); + return (Klass)VM.getVM().getObjectHeap().newOop(literalValue().addOffsetToAsOopHandle(0)); } public DictionaryEntry(Address addr) { diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintEntry.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintEntry.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintEntry.java Thu Feb 03 23:26:25 2011 -0800 @@ -42,14 +42,14 @@ private static synchronized void initialize(TypeDataBase db) { Type type = db.lookupType("LoaderConstraintEntry"); - nameField = type.getOopField("_name"); + nameField = type.getAddressField("_name"); numLoadersField = type.getCIntegerField("_num_loaders"); maxLoadersField = type.getCIntegerField("_max_loaders"); loadersField = type.getAddressField("_loaders"); } // Fields - private static sun.jvm.hotspot.types.OopField nameField; + private static AddressField nameField; private static CIntegerField numLoadersField; private static CIntegerField maxLoadersField; private static AddressField loadersField; @@ -57,7 +57,7 @@ // Accessors public Symbol name() { - return (Symbol) VM.getVM().getObjectHeap().newOop(nameField.getValue(addr)); + return Symbol.create(nameField.getValue(addr)); } public int numLoaders() { diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/memory/PlaceholderEntry.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/PlaceholderEntry.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/PlaceholderEntry.java Thu Feb 03 23:26:25 2011 -0800 @@ -58,7 +58,7 @@ } public Symbol klass() { - return (Symbol) literal(); + return Symbol.create(literalValue()); } /* covariant return type :-( diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java Thu Feb 03 23:26:25 2011 -0800 @@ -70,11 +70,13 @@ } public void stringsDo(StringVisitor visitor) { + ObjectHeap oh = VM.getVM().getObjectHeap(); int numBuckets = tableSize(); for (int i = 0; i < numBuckets; i++) { for (HashtableEntry e = (HashtableEntry) bucket(i); e != null; e = (HashtableEntry) e.next()) { - visitor.visit((Instance) e.literal()); + Instance s = (Instance)oh.newOop(e.literalValue().addOffsetToAsOopHandle(0)); + visitor.visit(s); } } } diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Thu Feb 03 23:26:25 2011 -0800 @@ -85,7 +85,7 @@ long hashValue = hashSymbol(name); for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) { if (e.hash() == hashValue) { - Symbol sym = (Symbol) e.literal(); + Symbol sym = Symbol.create(e.literalValue()); if (sym.equals(name)) { return sym; } @@ -103,7 +103,7 @@ for (int i = 0; i < numBuckets; i++) { for (HashtableEntry e = (HashtableEntry) bucket(i); e != null; e = (HashtableEntry) e.next()) { - visitor.visit((Symbol) e.literal()); + visitor.visit(Symbol.create(e.literalValue())); } } } diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Thu Feb 03 23:26:25 2011 -0800 @@ -35,6 +35,38 @@ // as described in the class file public class ConstantPool extends Oop implements ClassConstants { + + public class CPSlot { + private Address ptr; + + CPSlot(Address ptr) { + this.ptr = ptr; + } + CPSlot(Symbol sym) { + this.ptr = sym.getAddress().orWithMask(1); + } + + public boolean isOop() { + return (ptr.minus(null) & 1) == 0; + } + public boolean isMetaData() { + return (ptr.minus(null) & 1) == 1; + } + + public Symbol getSymbol() { + if (isMetaData()) { + return Symbol.create(ptr.xorWithMask(1)); + } + throw new InternalError("not a symbol"); + } + public Oop getOop() { + if (isOop()) { + return VM.getVM().getObjectHeap().newOop(ptr.addOffsetToAsOopHandle(0)); + } + throw new InternalError("not an oop"); + } + } + // Used for debugging this code private static final boolean DEBUG = false; @@ -110,12 +142,17 @@ return new ConstantTag(getTags().getByteAt((int) index)); } - public Oop getObjAt(long index){ + public CPSlot getSlotAt(long index) { + return new CPSlot(getHandle().getAddressAt(indexOffset(index))); + } + + public Oop getObjAtRaw(long index){ return getHeap().newOop(getHandle().getOopHandleAt(indexOffset(index))); } public Symbol getSymbolAt(long index) { - return (Symbol) getObjAt(index); + CPSlot slot = getSlotAt(index); + return slot.getSymbol(); } public int getIntAt(long index){ @@ -187,7 +224,7 @@ // returns null, if not resolved. public Klass getKlassRefAt(int which) { if( ! getTagAt(which).isKlass()) return null; - return (Klass) getObjAt(which); + return (Klass) getObjAtRaw(which); } // returns null, if not resolved. @@ -477,7 +514,7 @@ case JVM_CONSTANT_Class: { dos.writeByte(cpConstType); // Klass already resolved. ConstantPool constains klassOop. - Klass refKls = (Klass) getObjAt(ci); + Klass refKls = (Klass) getObjAtRaw(ci); String klassName = refKls.getName().asString(); Short s = (Short) utf8ToIndex.get(klassName); dos.writeShort(s.shortValue()); @@ -498,7 +535,7 @@ case JVM_CONSTANT_String: { dos.writeByte(cpConstType); - String str = OopUtilities.stringOopToString(getObjAt(ci)); + String str = OopUtilities.stringOopToString(getObjAtRaw(ci)); Short s = (Short) utf8ToIndex.get(str); dos.writeShort(s.shortValue()); if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java Thu Feb 03 23:26:25 2011 -0800 @@ -576,7 +576,7 @@ ConstantPool cp = method().getConstants(); int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx); int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx); - symbolOop signature = cp.symbol_at(signatureIdx); + Symbol* signature = cp.symbol_at(signatureIdx); tty.print("%s", signature.as_C_string()); */ } @@ -616,7 +616,7 @@ constantPoolOop cp = method().constants(); int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx); int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx); - symbolOop signature = cp.symbol_at(signatureIdx); + Symbol* signature = cp.symbol_at(signatureIdx); tty.print("%s", signature.as_C_string()); */ } diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Thu Feb 03 23:26:25 2011 -0800 @@ -82,8 +82,8 @@ classLoader = new OopField(type.getOopField("_class_loader"), Oop.getHeaderSize()); protectionDomain = new OopField(type.getOopField("_protection_domain"), Oop.getHeaderSize()); signers = new OopField(type.getOopField("_signers"), Oop.getHeaderSize()); - sourceFileName = new OopField(type.getOopField("_source_file_name"), Oop.getHeaderSize()); - sourceDebugExtension = new OopField(type.getOopField("_source_debug_extension"), Oop.getHeaderSize()); + sourceFileName = type.getAddressField("_source_file_name"); + sourceDebugExtension = type.getAddressField("_source_debug_extension"); innerClasses = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize()); nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize()); staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize()); @@ -94,7 +94,7 @@ vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize()); itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize()); breakpoints = type.getAddressField("_breakpoints"); - genericSignature = new OopField(type.getOopField("_generic_signature"), Oop.getHeaderSize()); + genericSignature = type.getAddressField("_generic_signature"); majorVersion = new CIntField(type.getCIntegerField("_major_version"), Oop.getHeaderSize()); minorVersion = new CIntField(type.getCIntegerField("_minor_version"), Oop.getHeaderSize()); headerSize = alignObjectOffset(Oop.getHeaderSize() + type.getSize()); @@ -135,8 +135,8 @@ private static OopField classLoader; private static OopField protectionDomain; private static OopField signers; - private static OopField sourceFileName; - private static OopField sourceDebugExtension; + private static AddressField sourceFileName; + private static AddressField sourceDebugExtension; private static OopField innerClasses; private static CIntField nonstaticFieldSize; private static CIntField staticFieldSize; @@ -147,7 +147,7 @@ private static CIntField vtableLen; private static CIntField itableLen; private static AddressField breakpoints; - private static OopField genericSignature; + private static AddressField genericSignature; private static CIntField majorVersion; private static CIntField minorVersion; @@ -257,8 +257,8 @@ public Oop getClassLoader() { return classLoader.getValue(this); } public Oop getProtectionDomain() { return protectionDomain.getValue(this); } public ObjArray getSigners() { return (ObjArray) signers.getValue(this); } - public Symbol getSourceFileName() { return (Symbol) sourceFileName.getValue(this); } - public Symbol getSourceDebugExtension(){ return (Symbol) sourceDebugExtension.getValue(this); } + public Symbol getSourceFileName() { return getSymbol(sourceFileName); } + public Symbol getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); } public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); } public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); } public long getStaticFieldSize() { return staticFieldSize.getValue(this); } @@ -267,7 +267,7 @@ public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } public long getVtableLen() { return vtableLen.getValue(this); } public long getItableLen() { return itableLen.getValue(this); } - public Symbol getGenericSignature() { return (Symbol) genericSignature.getValue(this); } + public Symbol getGenericSignature() { return getSymbol(genericSignature); } public long majorVersion() { return majorVersion.getValue(this); } public long minorVersion() { return minorVersion.getValue(this); } @@ -308,12 +308,12 @@ if (ioff != 0) { // only look at classes that are already loaded // since we are looking for the flags for our self. - Oop classInfo = getConstants().getObjAt(ioff); + ConstantPool.CPSlot classInfo = getConstants().getSlotAt(ioff); Symbol name = null; - if (classInfo instanceof Klass) { - name = ((Klass) classInfo).getName(); - } else if (classInfo instanceof Symbol) { - name = (Symbol) classInfo; + if (classInfo.isOop()) { + name = ((Klass) classInfo.getOop()).getName(); + } else if (classInfo.isMetaData()) { + name = classInfo.getSymbol(); } else { throw new RuntimeException("should not reach here"); } @@ -358,12 +358,12 @@ // 'ioff' can be zero. // refer to JVM spec. section 4.7.5. if (ioff != 0) { - Oop iclassInfo = getConstants().getObjAt(ioff); + ConstantPool.CPSlot iclassInfo = getConstants().getSlotAt(ioff); Symbol innerName = null; - if (iclassInfo instanceof Klass) { - innerName = ((Klass) iclassInfo).getName(); - } else if (iclassInfo instanceof Symbol) { - innerName = (Symbol) iclassInfo; + if (iclassInfo.isOop()) { + innerName = ((Klass) iclassInfo.getOop()).getName(); + } else if (iclassInfo.isMetaData()) { + innerName = iclassInfo.getSymbol(); } else { throw new RuntimeException("should not reach here"); } @@ -387,12 +387,12 @@ } } } else { - Oop oclassInfo = getConstants().getObjAt(ooff); + ConstantPool.CPSlot oclassInfo = getConstants().getSlotAt(ooff); Symbol outerName = null; - if (oclassInfo instanceof Klass) { - outerName = ((Klass) oclassInfo).getName(); - } else if (oclassInfo instanceof Symbol) { - outerName = (Symbol) oclassInfo; + if (oclassInfo.isOop()) { + outerName = ((Klass) oclassInfo.getOop()).getName(); + } else if (oclassInfo.isMetaData()) { + outerName = oclassInfo.getSymbol(); } else { throw new RuntimeException("should not reach here"); } @@ -450,7 +450,6 @@ visitor.doOop(classLoader, true); visitor.doOop(protectionDomain, true); visitor.doOop(signers, true); - visitor.doOop(sourceFileName, true); visitor.doOop(innerClasses, true); visitor.doCInt(nonstaticFieldSize, true); visitor.doCInt(staticFieldSize, true); @@ -467,7 +466,7 @@ for (int index = 0; index < length; index += NEXT_OFFSET) { short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET); short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET); - FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex)); + FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex)); AccessFlags access = new AccessFlags(accessFlags); if (access.isStatic()) { visitField(visitor, type, index); @@ -490,7 +489,7 @@ short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET); short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET); - FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex)); + FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex)); AccessFlags access = new AccessFlags(accessFlags); if (!access.isStatic()) { visitField(visitor, type, index); @@ -787,7 +786,7 @@ private Field newField(int index) { TypeArray fields = getFields(); short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET); - FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex)); + FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex)); if (type.isOop()) { if (VM.getVM().isCompressedOopsEnabled()) { return new NarrowOopField(this, index); diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java Thu Feb 03 23:26:25 2011 -0800 @@ -53,7 +53,7 @@ javaMirror = new OopField(type.getOopField("_java_mirror"), Oop.getHeaderSize()); superField = new OopField(type.getOopField("_super"), Oop.getHeaderSize()); layoutHelper = new IntField(type.getJIntField("_layout_helper"), Oop.getHeaderSize()); - name = new OopField(type.getOopField("_name"), Oop.getHeaderSize()); + name = type.getAddressField("_name"); accessFlags = new CIntField(type.getCIntegerField("_access_flags"), Oop.getHeaderSize()); subklass = new OopField(type.getOopField("_subklass"), Oop.getHeaderSize()); nextSibling = new OopField(type.getOopField("_next_sibling"), Oop.getHeaderSize()); @@ -83,18 +83,26 @@ private static OopField javaMirror; private static OopField superField; private static IntField layoutHelper; - private static OopField name; + private static AddressField name; private static CIntField accessFlags; private static OopField subklass; private static OopField nextSibling; private static CIntField allocCount; + private Address getValue(AddressField field) { + return getHandle().getAddressAt(field.getOffset() + Oop.getHeaderSize()); + } + + protected Symbol getSymbol(AddressField field) { + return Symbol.create(getHandle().getAddressAt(field.getOffset() + Oop.getHeaderSize())); + } + // Accessors for declared fields public Instance getJavaMirror() { return (Instance) javaMirror.getValue(this); } public Klass getSuper() { return (Klass) superField.getValue(this); } public Klass getJavaSuper() { return null; } public int getLayoutHelper() { return (int) layoutHelper.getValue(this); } - public Symbol getName() { return (Symbol) name.getValue(this); } + public Symbol getName() { return getSymbol(name); } public long getAccessFlags() { return accessFlags.getValue(this); } // Convenience routine public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); } @@ -162,7 +170,7 @@ visitor.doOop(javaMirror, true); visitor.doOop(superField, true); visitor.doInt(layoutHelper, true); - visitor.doOop(name, true); + // visitor.doOop(name, true); visitor.doCInt(accessFlags, true); visitor.doOop(subklass, true); visitor.doOop(nextSibling, true); diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/oops/Method.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Thu Feb 03 23:26:25 2011 -0800 @@ -196,11 +196,11 @@ public Address getFromCompiledCodeEntryPoint() { return fromCompiledCodeEntryPointField.getValue(this); } */ // Accessors - public Symbol getName() { return (Symbol) getConstants().getObjAt(getNameIndex()); } - public Symbol getSignature() { return (Symbol) getConstants().getObjAt(getSignatureIndex()); } + public Symbol getName() { return getConstants().getSymbolAt(getNameIndex()); } + public Symbol getSignature() { return getConstants().getSymbolAt(getSignatureIndex()); } public Symbol getGenericSignature() { long index = getGenericSignatureIndex(); - return (index != 0L) ? (Symbol) getConstants().getObjAt(index) : null; + return (index != 0L) ? getConstants().getSymbolAt(index) : null; } // Method holder (the Klass holding this method) diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Thu Feb 03 23:26:25 2011 -0800 @@ -47,7 +47,6 @@ DEBUG = System.getProperty("sun.jvm.hotspot.oops.ObjectHeap.DEBUG") != null; } - private OopHandle symbolKlassHandle; private OopHandle methodKlassHandle; private OopHandle constMethodKlassHandle; private OopHandle methodDataKlassHandle; @@ -68,7 +67,6 @@ private OopHandle arrayKlassKlassHandle; private OopHandle compiledICHolderKlassHandle; - private SymbolKlass symbolKlassObj; private MethodKlass methodKlassObj; private ConstMethodKlass constMethodKlassObj; private MethodDataKlass methodDataKlassObj; @@ -93,9 +91,6 @@ // Lookup the roots in the object hierarchy. Type universeType = db.lookupType("Universe"); - symbolKlassHandle = universeType.getOopField("_symbolKlassObj").getValue(); - symbolKlassObj = new SymbolKlass(symbolKlassHandle, this); - methodKlassHandle = universeType.getOopField("_methodKlassObj").getValue(); methodKlassObj = new MethodKlass(methodKlassHandle, this); @@ -199,7 +194,6 @@ public long getDoubleSize() { return doubleSize; } // Accessors for well-known system classes (from Universe) - public SymbolKlass getSymbolKlassObj() { return symbolKlassObj; } public MethodKlass getMethodKlassObj() { return methodKlassObj; } public ConstMethodKlass getConstMethodKlassObj() { return constMethodKlassObj; } public MethodDataKlass getMethodDataKlassObj() { return methodDataKlassObj; } @@ -337,7 +331,6 @@ // First check if handle is one of the root objects if (handle.equals(methodKlassHandle)) return getMethodKlassObj(); if (handle.equals(constMethodKlassHandle)) return getConstMethodKlassObj(); - if (handle.equals(symbolKlassHandle)) return getSymbolKlassObj(); if (handle.equals(constantPoolKlassHandle)) return getConstantPoolKlassObj(); if (handle.equals(constantPoolCacheKlassHandle)) return getConstantPoolCacheKlassObj(); if (handle.equals(instanceKlassKlassHandle)) return getInstanceKlassKlassObj(); @@ -363,7 +356,6 @@ if (klass != null) { if (klass.equals(methodKlassHandle)) return new Method(handle, this); if (klass.equals(constMethodKlassHandle)) return new ConstMethod(handle, this); - if (klass.equals(symbolKlassHandle)) return new Symbol(handle, this); if (klass.equals(constantPoolKlassHandle)) return new ConstantPool(handle, this); if (klass.equals(constantPoolCacheKlassHandle)) return new ConstantPoolCache(handle, this); if (!VM.getVM().isCore()) { diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Thu Feb 03 23:26:25 2011 -0800 @@ -34,7 +34,7 @@ // A Symbol is a canonicalized string. // All Symbols reside in global symbolTable. -public class Symbol extends Oop { +public class Symbol extends VMObject { static { VM.registerVMInitializedObserver(new Observer() { public void update(Observable o, Object data) { @@ -44,9 +44,10 @@ } private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { - Type type = db.lookupType("symbolOopDesc"); - length = new CIntField(type.getCIntegerField("_length"), 0); + Type type = db.lookupType("Symbol"); + length = type.getCIntegerField("_length"); baseOffset = type.getField("_body").getOffset(); + idHash = type.getCIntegerField("_identity_hash"); } // Format: @@ -55,8 +56,15 @@ // [length] byte size of uft8 string // ..body.. - Symbol(OopHandle handle, ObjectHeap heap) { - super(handle, heap); + public static Symbol create(Address addr) { + if (addr == null) { + return null; + } + return new Symbol(addr); + } + + Symbol(Address addr) { + super(addr); } public boolean isSymbol() { return true; } @@ -64,15 +72,19 @@ private static long baseOffset; // tells where the array part starts // Fields - private static CIntField length; + private static CIntegerField length; // Accessors for declared fields - public long getLength() { return length.getValue(this); } + public long getLength() { return length.getValue(this.addr); } public byte getByteAt(long index) { - return getHandle().getJByteAt(baseOffset + index); + return addr.getJByteAt(baseOffset + index); } + private static CIntegerField idHash; + + public int identityHash() { return (int)idHash.getValue(this.addr); } + public boolean equals(byte[] modUTF8Chars) { int l = (int) getLength(); if (l != modUTF8Chars.length) return false; @@ -98,7 +110,9 @@ // Decode the byte array and return the string. try { return readModifiedUTF8(asByteArray()); - } catch(IOException e) { + } catch(Exception e) { + System.err.println(addr); + e.printStackTrace(); return null; } } @@ -111,28 +125,13 @@ tty.print("#" + asString()); } - public long getObjectSize() { - return alignObjectSize(baseOffset + getLength()); - } - - void iterateFields(OopVisitor visitor, boolean doVMFields) { - super.iterateFields(visitor, doVMFields); - if (doVMFields) { - visitor.doCInt(length, true); - int length = (int) getLength(); - for (int index = 0; index < length; index++) { - visitor.doByte(new ByteField(new IndexableFieldIdentifier(index), baseOffset + index, false), true); - } - } - } - /** Note: this comparison is used for vtable sorting only; it doesn't matter what order it defines, as long as it is a total, - time-invariant order Since symbolOops are in permSpace, their + time-invariant order Since Symbol* are in C_HEAP, their relative order in memory never changes, so use address comparison for speed. */ public int fastCompare(Symbol other) { - return (int) getHandle().minus(other.getHandle()); + return (int) addr.minus(other.addr); } private static String readModifiedUTF8(byte[] buf) throws IOException { diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/oops/SymbolKlass.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/SymbolKlass.java Thu Feb 03 17:22:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.oops; - -import java.io.*; -import java.util.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.types.*; - -// A SymbolKlass is the klass for all Symbols - -public class SymbolKlass extends Klass { - static { - VM.registerVMInitializedObserver(new Observer() { - public void update(Observable o, Object data) { - initialize(VM.getVM().getTypeDataBase()); - } - }); - } - - private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { - Type type = db.lookupType("symbolKlass"); - headerSize = type.getSize() + Oop.getHeaderSize(); - } - - SymbolKlass(OopHandle handle, ObjectHeap heap) { - super(handle, heap); - } - - private static long headerSize; - - public long getObjectSize() { return alignObjectSize(headerSize); } - - public void printValueOn(PrintStream tty) { - tty.print("SymbolKlass"); - } -} diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Thu Feb 03 23:26:25 2011 -0800 @@ -229,7 +229,7 @@ case JVM_CONSTANT_Class: { dos.writeByte(cpConstType); // Klass already resolved. ConstantPool constains klassOop. - Klass refKls = (Klass) cpool.getObjAt(ci); + Klass refKls = (Klass) cpool.getObjAtRaw(ci); String klassName = refKls.getName().asString(); Short s = (Short) utf8ToIndex.get(klassName); @@ -255,7 +255,7 @@ case JVM_CONSTANT_String: { dos.writeByte(cpConstType); - String str = OopUtilities.stringOopToString(cpool.getObjAt(ci)); + String str = OopUtilities.stringOopToString(cpool.getObjAtRaw(ci)); Short s = (Short) utf8ToIndex.get(str); dos.writeShort(s.shortValue()); if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/types/Field.java --- a/agent/src/share/classes/sun/jvm/hotspot/types/Field.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/types/Field.java Thu Feb 03 23:26:25 2011 -0800 @@ -56,7 +56,7 @@ FIXME: among other things, this interface is not sufficient to - describe fields which are themselves arrays (like symbolOop's + describe fields which are themselves arrays (like Symbol's jbyte _body[1]). */ public interface Field { /** Get the name of this field */ diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java --- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Feb 03 23:26:25 2011 -0800 @@ -530,7 +530,7 @@ case JVM_CONSTANT_Class: buf.cell("JVM_CONSTANT_Class"); - Klass klass = (Klass) cpool.getObjAt(index); + Klass klass = (Klass) cpool.getObjAtRaw(index); if (klass instanceof InstanceKlass) { buf.cell(genKlassLink((InstanceKlass) klass)); } else { @@ -555,7 +555,7 @@ case JVM_CONSTANT_String: buf.cell("JVM_CONSTANT_String"); buf.cell("\"" + - escapeHTMLSpecialChars(OopUtilities.stringOopToString(cpool.getObjAt(index))) + "\""); + escapeHTMLSpecialChars(OopUtilities.stringOopToString(cpool.getObjAtRaw(index))) + "\""); break; case JVM_CONSTANT_Fieldref: @@ -672,11 +672,11 @@ buf.beginTag("ul"); for (int exp = 0; exp < exceptions.length; exp++) { short cpIndex = (short) exceptions[exp].getClassCPIndex(); - Oop obj = cpool.getObjAt(cpIndex); - if (obj instanceof Symbol) { - buf.li(((Symbol)obj).asString().replace('/', '.')); + ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex); + if (obj.isMetaData()) { + buf.li((obj.getSymbol()).asString().replace('/', '.')); } else { - buf.li(genKlassLink((InstanceKlass)obj)); + buf.li(genKlassLink((InstanceKlass)obj.getOop())); } } buf.endTag("ul"); @@ -756,7 +756,7 @@ } else if (instr instanceof BytecodeLoadConstant) { BytecodeLoadConstant ldc = (BytecodeLoadConstant) instr; if (ldc.isKlassConstant()) { - Oop oop = ldc.getKlass(); + Object oop = ldc.getKlass(); if (oop instanceof Klass) { buf.append(""); } // derived class may return Class diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java Thu Feb 03 23:26:25 2011 -0800 @@ -41,16 +41,16 @@ } private static synchronized void initialize(TypeDataBase db) { - Type type = db.lookupType("HashtableEntry"); - literalField = type.getOopField("_literal"); + Type type = db.lookupType("HashtableEntry"); + literalField = type.getAddressField("_literal"); } // Fields - private static OopField literalField; + private static AddressField literalField; // Accessors - public Oop literal() { - return VM.getVM().getObjectHeap().newOop(literalField.getValue(addr)); + public Address literalValue() { + return literalField.getValue(addr); } public HashtableEntry(Address addr) { diff -r 6ecdca5709df -r ae4b185f2ed1 agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Thu Feb 03 17:22:06 2011 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Thu Feb 03 23:26:25 2011 -0800 @@ -740,7 +740,7 @@ for (Iterator itr = fields.iterator(); itr.hasNext();) { Field field = (Field) itr.next(); Symbol name = symTbl.probe(field.getID().getName()); - writeObjectID(name); + writeSymbolID(name); char typeCode = (char) field.getSignature().getByteAt(0); int kind = signatureToHprofKind(typeCode); out.writeByte((byte)kind); @@ -852,7 +852,7 @@ private void writeSymbol(Symbol sym) throws IOException { byte[] buf = sym.asString().getBytes("UTF-8"); writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE); - writeObjectID(sym); + writeSymbolID(sym); out.write(buf); } @@ -869,7 +869,7 @@ out.writeInt(serialNum); writeObjectID(clazz); out.writeInt(DUMMY_STACK_TRACE_ID); - writeObjectID(k.getName()); + writeSymbolID(k.getName()); serialNum++; } catch (IOException exp) { throw new RuntimeException(exp); @@ -901,6 +901,10 @@ writeObjectID(address); } + private void writeSymbolID(Symbol sym) throws IOException { + writeObjectID(getAddressValue(sym.getAddress())); + } + private void writeObjectID(long address) throws IOException { if (OBJ_ID_SIZE == 4) { out.writeInt((int) address); diff -r 6ecdca5709df -r ae4b185f2ed1 make/hotspot_version --- a/make/hotspot_version Thu Feb 03 17:22:06 2011 -0800 +++ b/make/hotspot_version Thu Feb 03 23:26:25 2011 -0800 @@ -33,9 +33,9 @@ # Don't put quotes (fail windows build). HOTSPOT_VM_COPYRIGHT=Copyright 2011 -HS_MAJOR_VER=20 +HS_MAJOR_VER=21 HS_MINOR_VER=0 -HS_BUILD_NUMBER=07 +HS_BUILD_NUMBER=01 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 diff -r 6ecdca5709df -r ae4b185f2ed1 src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -129,27 +129,6 @@ } -// Implementation of ArrayStoreExceptionStub - -ArrayStoreExceptionStub::ArrayStoreExceptionStub(CodeEmitInfo* info): - _info(info) { -} - - -void ArrayStoreExceptionStub::emit_code(LIR_Assembler* ce) { - __ bind(_entry); - __ call(Runtime1::entry_for(Runtime1::throw_array_store_exception_id), relocInfo::runtime_call_type); - __ delayed()->nop(); - ce->add_call_info_here(_info); - ce->verify_oop_map(_info); -#ifdef ASSERT - __ should_not_reach_here(); -#endif -} - - - - // Implementation of NewInstanceStub NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/cpu/sparc/vm/c1_Runtime1_sparc.cpp --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -710,7 +710,7 @@ case throw_array_store_exception_id: { __ set_info("throw_array_store_exception", dont_gc_arguments); - oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), false); + oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true); } break; diff -r 6ecdca5709df -r ae4b185f2ed1 src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -2541,7 +2541,7 @@ in_sig_bt[i++] = bt; // Collect remaining bits of signature out_sig_bt[total_c_args++] = bt; if( bt == T_OBJECT) { - symbolOop s = ss.as_symbol_or_null(); + Symbol* s = ss.as_symbol_or_null(); if (s == vmSymbols::java_lang_String()) { total_strings++; out_sig_bt[total_c_args-1] = T_ADDRESS; diff -r 6ecdca5709df -r ae4b185f2ed1 src/cpu/x86/vm/c1_CodeStubs_x86.cpp --- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -411,20 +411,6 @@ } -ArrayStoreExceptionStub::ArrayStoreExceptionStub(CodeEmitInfo* info): - _info(info) { -} - - -void ArrayStoreExceptionStub::emit_code(LIR_Assembler* ce) { - assert(__ rsp_offset() == 0, "frame size should be fixed"); - __ bind(_entry); - __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_array_store_exception_id))); - ce->add_call_info_here(_info); - debug_only(__ should_not_reach_here()); -} - - void ArrayCopyStub::emit_code(LIR_Assembler* ce) { //---------------slow case: call to native----------------- __ bind(_entry); diff -r 6ecdca5709df -r ae4b185f2ed1 src/cpu/x86/vm/c1_LIRGenerator_x86.cpp --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -733,8 +733,8 @@ // generate compare-and-swap; produces zero condition if swap occurs int value_offset = sun_misc_AtomicLongCSImpl::value_offset(); - LIR_Opr addr = obj.result(); - __ add(addr, LIR_OprFact::intConst(value_offset), addr); + LIR_Opr addr = new_pointer_register(); + __ leal(LIR_OprFact::address(new LIR_Address(obj.result(), value_offset, T_LONG)), addr); LIR_Opr t1 = LIR_OprFact::illegalOpr; // no temp needed LIR_Opr t2 = LIR_OprFact::illegalOpr; // no temp needed __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2); diff -r 6ecdca5709df -r ae4b185f2ed1 src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1337,7 +1337,7 @@ { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments); // tos + 0: link // + 1: return address - oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), false); + oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true); } break; diff -r 6ecdca5709df -r ae4b185f2ed1 src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1974,7 +1974,7 @@ in_sig_bt[i++] = bt; // Collect remaining bits of signature out_sig_bt[total_c_args++] = bt; if( bt == T_OBJECT) { - symbolOop s = ss.as_symbol_or_null(); + Symbol* s = ss.as_symbol_or_null(); // symbol is created if (s == vmSymbols::java_lang_String()) { total_strings++; out_sig_bt[total_c_args-1] = T_ADDRESS; diff -r 6ecdca5709df -r ae4b185f2ed1 src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1980,7 +1980,7 @@ in_sig_bt[i++] = bt; // Collect remaining bits of signature out_sig_bt[total_c_args++] = bt; if( bt == T_OBJECT) { - symbolOop s = ss.as_symbol_or_null(); + Symbol* s = ss.as_symbol_or_null(); // symbol is created if (s == vmSymbols::java_lang_String()) { total_strings++; out_sig_bt[total_c_args-1] = T_ADDRESS; diff -r 6ecdca5709df -r ae4b185f2ed1 src/os/solaris/dtrace/generateJvmOffsets.cpp --- a/src/os/solaris/dtrace/generateJvmOffsets.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/os/solaris/dtrace/generateJvmOffsets.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -49,7 +49,7 @@ #include "oops/klass.hpp" #include "oops/methodOop.hpp" #include "oops/oop.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/virtualspace.hpp" #include "runtime/vmStructs.hpp" #include "utilities/accessFlags.hpp" @@ -215,8 +215,8 @@ GEN_VALUE(AccessFlags_NATIVE, JVM_ACC_NATIVE); GEN_VALUE(constMethodOopDesc_has_linenumber_table, constMethodOopDesc::_has_linenumber_table); GEN_OFFS(AccessFlags, _flags); - GEN_OFFS(symbolOopDesc, _length); - GEN_OFFS(symbolOopDesc, _body); + GEN_OFFS(Symbol, _length); + GEN_OFFS(Symbol, _body); printf("\n"); GEN_OFFS(methodOopDesc, _constMethod); diff -r 6ecdca5709df -r ae4b185f2ed1 src/os/solaris/dtrace/jhelper.d --- a/src/os/solaris/dtrace/jhelper.d Thu Feb 03 17:22:06 2011 -0800 +++ b/src/os/solaris/dtrace/jhelper.d Thu Feb 03 23:26:25 2011 -0800 @@ -114,8 +114,8 @@ copyin_offset(OFFSET_HeapBlockHeader_used); copyin_offset(OFFSET_oopDesc_metadata); - copyin_offset(OFFSET_symbolOopDesc_length); - copyin_offset(OFFSET_symbolOopDesc_body); + copyin_offset(OFFSET_Symbol_length); + copyin_offset(OFFSET_Symbol_body); copyin_offset(OFFSET_methodOopDesc_constMethod); copyin_offset(OFFSET_methodOopDesc_constants); @@ -366,13 +366,13 @@ this->nameIndex * sizeof (pointer) + SIZE_constantPoolOopDesc); this->nameSymbolLength = copyin_uint16(this->nameSymbol + - OFFSET_symbolOopDesc_length); + OFFSET_Symbol_length); this->signatureSymbol = copyin_ptr(this->constantPool + this->signatureIndex * sizeof (pointer) + SIZE_constantPoolOopDesc); this->signatureSymbolLength = copyin_uint16(this->signatureSymbol + - OFFSET_symbolOopDesc_length); + OFFSET_Symbol_length); this->klassPtr = copyin_ptr(this->constantPool + OFFSET_constantPoolOopDesc_pool_holder); @@ -381,7 +381,7 @@ OFFSET_Klass_name + SIZE_oopDesc); this->klassSymbolLength = copyin_uint16(this->klassSymbol + - OFFSET_symbolOopDesc_length); + OFFSET_Symbol_length); /* * Enough for three strings, plus the '.', plus the trailing '\0'. @@ -390,7 +390,7 @@ this->nameSymbolLength + this->signatureSymbolLength + 2 + 1); - copyinto(this->klassSymbol + OFFSET_symbolOopDesc_body, + copyinto(this->klassSymbol + OFFSET_Symbol_body, this->klassSymbolLength, this->result); /* @@ -398,11 +398,11 @@ */ this->result[this->klassSymbolLength] = '.'; - copyinto(this->nameSymbol + OFFSET_symbolOopDesc_body, + copyinto(this->nameSymbol + OFFSET_Symbol_body, this->nameSymbolLength, this->result + this->klassSymbolLength + 1); - copyinto(this->signatureSymbol + OFFSET_symbolOopDesc_body, + copyinto(this->signatureSymbol + OFFSET_Symbol_body, this->signatureSymbolLength, this->result + this->klassSymbolLength + this->nameSymbolLength + 1); diff -r 6ecdca5709df -r ae4b185f2ed1 src/os/solaris/dtrace/libjvm_db.c --- a/src/os/solaris/dtrace/libjvm_db.c Thu Feb 03 17:22:06 2011 -0800 +++ b/src/os/solaris/dtrace/libjvm_db.c Thu Feb 03 23:26:25 2011 -0800 @@ -524,10 +524,10 @@ CHECK_FAIL(err); err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &nameSymbol); CHECK_FAIL(err); - err = ps_pread(J->P, nameSymbol + OFFSET_symbolOopDesc_length, &nameSymbolLength, 2); + err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2); CHECK_FAIL(err); nameString = (char*)calloc(nameSymbolLength + 1, 1); - err = ps_pread(J->P, nameSymbol + OFFSET_symbolOopDesc_body, nameString, nameSymbolLength); + err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength); CHECK_FAIL(err); /* To get signature string */ @@ -535,10 +535,10 @@ CHECK_FAIL(err); err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol); CHECK_FAIL(err); - err = ps_pread(J->P, signatureSymbol + OFFSET_symbolOopDesc_length, &signatureSymbolLength, 2); + err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2); CHECK_FAIL(err); signatureString = (char*)calloc(signatureSymbolLength + 1, 1); - err = ps_pread(J->P, signatureSymbol + OFFSET_symbolOopDesc_body, signatureString, signatureSymbolLength); + err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength); CHECK_FAIL(err); /* To get klass string */ @@ -546,10 +546,10 @@ CHECK_FAIL(err); err = read_pointer(J, klassPtr + OFFSET_Klass_name + SIZE_oopDesc, &klassSymbol); CHECK_FAIL(err); - err = ps_pread(J->P, klassSymbol + OFFSET_symbolOopDesc_length, &klassSymbolLength, 2); + err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2); CHECK_FAIL(err); klassString = (char*)calloc(klassSymbolLength + 1, 1); - err = ps_pread(J->P, klassSymbol + OFFSET_symbolOopDesc_body, klassString, klassSymbolLength); + err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength); CHECK_FAIL(err); result[0] = '\0'; diff -r 6ecdca5709df -r ae4b185f2ed1 src/os/solaris/vm/dtraceJSDT_solaris.cpp --- a/src/os/solaris/vm/dtraceJSDT_solaris.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/os/solaris/vm/dtraceJSDT_solaris.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -142,7 +142,7 @@ ++strcount; for(int prbc = 0; prbc < provider->probe_count; ++prbc) { JVM_DTraceProbe* p = &(provider->probes[prbc]); - symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); + Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); // function + name + one per argument strcount += 2 + ArgumentCount(sig).size(); } @@ -178,7 +178,7 @@ stroffs[curstr++] = string_index; string_index += strlen(name) + 1; - symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); + Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); SignatureStream ss(sig); for ( ; !ss.at_return_type(); ss.next()) { BasicType bt = ss.type(); @@ -227,7 +227,7 @@ uint32_t argscount = 0; for(int prbc = 0; prbc < provider->probe_count; ++prbc) { JVM_DTraceProbe* p = &(provider->probes[prbc]); - symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); + Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); argscount += ArgumentCount(sig).size(); } secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]); @@ -298,7 +298,7 @@ strcpy(str, name); str += strlen(name) + 1; - symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); + Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); SignatureStream ss(sig); for ( ; !ss.at_return_type(); ss.next()) { BasicType bt = ss.type(); @@ -433,7 +433,7 @@ uint8_t* par = (uint8_t*)(dof + sec->dofs_offset); for (int prbc = 0; prbc < provider->probe_count; ++prbc) { JVM_DTraceProbe* p = &(provider->probes[prbc]); - symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); + Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature(); uint8_t count = (uint8_t)ArgumentCount(sig).size(); for (uint8_t i = 0; i < count; ++i) { *par++ = i; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_Canonicalizer.cpp --- a/src/share/vm/c1/c1_Canonicalizer.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_Canonicalizer.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -898,4 +898,4 @@ void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void Canonicalizer::do_ProfileCall(ProfileCall* x) {} void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {} - +void Canonicalizer::do_RuntimeCall(RuntimeCall* x) {} diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_Canonicalizer.hpp --- a/src/share/vm/c1/c1_Canonicalizer.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_Canonicalizer.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,6 +102,7 @@ virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileInvoke (ProfileInvoke* x); + virtual void do_RuntimeCall (RuntimeCall* x); }; #endif // SHARE_VM_C1_C1_CANONICALIZER_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_CodeStubs.hpp --- a/src/share/vm/c1/c1_CodeStubs.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_CodeStubs.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -476,18 +476,12 @@ -class ArrayStoreExceptionStub: public CodeStub { +class ArrayStoreExceptionStub: public SimpleExceptionStub { private: CodeEmitInfo* _info; public: - ArrayStoreExceptionStub(CodeEmitInfo* info); - virtual void emit_code(LIR_Assembler* emit); - virtual CodeEmitInfo* info() const { return _info; } - virtual bool is_exception_throw_stub() const { return true; } - virtual void visit(LIR_OpVisitState* visitor) { - visitor->do_slow_case(_info); - } + ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {} #ifndef PRODUCT virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); } #endif // PRODUCT diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1396,6 +1396,13 @@ if (continuation() != NULL) { assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet"); + if (compilation()->env()->dtrace_method_probes()) { + // Report exit from inline methods + Values* args = new Values(1); + args->push(append(new Constant(new ObjectConstant(method())))); + append(new RuntimeCall(voidType, "dtrace_method_exit", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), args)); + } + // If the inlined method is synchronized, the monitor must be // released before we jump to the continuation block. if (method()->is_synchronized()) { @@ -3301,6 +3308,13 @@ Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI); assert(exception->is_pinned(), "must be"); + if (compilation()->env()->dtrace_method_probes()) { + // Report exit from inline methods + Values* args = new Values(1); + args->push(append(new Constant(new ObjectConstant(method())))); + append(new RuntimeCall(voidType, "dtrace_method_exit", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), args)); + } + int bci = SynchronizationEntryBCI; if (lock) { assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing"); @@ -3486,6 +3500,11 @@ inline_sync_entry(lock, sync_handler); } + if (compilation()->env()->dtrace_method_probes()) { + Values* args = new Values(1); + args->push(append(new Constant(new ObjectConstant(method())))); + append(new RuntimeCall(voidType, "dtrace_method_entry", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), args)); + } BlockBegin* callee_start_block = block_at(0); if (callee_start_block != NULL) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_Instruction.hpp --- a/src/share/vm/c1/c1_Instruction.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_Instruction.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -106,6 +106,7 @@ class UnsafePrefetchWrite; class ProfileCall; class ProfileInvoke; +class RuntimeCall; // A Value is a reference to the instruction creating the value typedef Instruction* Value; @@ -202,6 +203,7 @@ virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; virtual void do_ProfileCall (ProfileCall* x) = 0; virtual void do_ProfileInvoke (ProfileInvoke* x) = 0; + virtual void do_RuntimeCall (RuntimeCall* x) = 0; }; @@ -2267,6 +2269,38 @@ virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); } }; + +// Call some C runtime function that doesn't safepoint, +// optionally passing the current thread as the first argument. +LEAF(RuntimeCall, Instruction) + private: + const char* _entry_name; + address _entry; + Values* _args; + bool _pass_thread; // Pass the JavaThread* as an implicit first argument + + public: + RuntimeCall(ValueType* type, const char* entry_name, address entry, Values* args, bool pass_thread = true) + : Instruction(type) + , _entry(entry) + , _args(args) + , _entry_name(entry_name) + , _pass_thread(pass_thread) { + ASSERT_VALUES + pin(); + } + + const char* entry_name() const { return _entry_name; } + address entry() const { return _entry; } + int number_of_arguments() const { return _args->length(); } + Value argument_at(int i) const { return _args->at(i); } + bool pass_thread() const { return _pass_thread; } + + virtual void input_values_do(ValueVisitor* f) { + for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i)); + } +}; + // Use to trip invocation counter of an inlined method LEAF(ProfileInvoke, Instruction) diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_InstructionPrinter.cpp --- a/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -841,4 +841,13 @@ } +void InstructionPrinter::do_RuntimeCall(RuntimeCall* x) { + output()->print("call_rt %s(", x->entry_name()); + for (int i = 0; i < x->number_of_arguments(); i++) { + if (i > 0) output()->print(", "); + print_value(x->argument_at(i)); + } + output()->put(')'); +} + #endif // PRODUCT diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_InstructionPrinter.hpp --- a/src/share/vm/c1/c1_InstructionPrinter.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_InstructionPrinter.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,6 +131,7 @@ virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileInvoke (ProfileInvoke* x); + virtual void do_RuntimeCall (RuntimeCall* x); }; #endif // PRODUCT diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_LIR.cpp --- a/src/share/vm/c1/c1_LIR.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_LIR.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -396,7 +396,7 @@ , _should_profile(false) { if (code == lir_store_check) { - _stub = new ArrayStoreExceptionStub(info_for_exception); + _stub = new ArrayStoreExceptionStub(object, info_for_exception); assert(info_for_exception != NULL, "store_check throws exceptions"); } else { ShouldNotReachHere(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_LIRGenerator.cpp --- a/src/share/vm/c1/c1_LIRGenerator.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2741,6 +2741,31 @@ } } +void LIRGenerator::do_RuntimeCall(RuntimeCall* x) { + LIR_OprList* args = new LIR_OprList(x->number_of_arguments()); + BasicTypeList* signature = new BasicTypeList(x->number_of_arguments()); + + if (x->pass_thread()) { + signature->append(T_ADDRESS); + args->append(getThreadPointer()); + } + + for (int i = 0; i < x->number_of_arguments(); i++) { + Value a = x->argument_at(i); + LIRItem* item = new LIRItem(a, this); + item->load_item(); + args->append(item->result()); + signature->append(as_BasicType(a->type())); + } + + LIR_Opr result = call_runtime(signature, args, x->entry(), x->type(), NULL); + if (x->type() == voidType) { + set_no_result(x); + } else { + __ move(result, rlock_result(x)); + } +} + LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) { LIRItemList args(1); LIRItem value(arg1, this); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_LIRGenerator.hpp --- a/src/share/vm/c1/c1_LIRGenerator.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_LIRGenerator.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -522,6 +522,7 @@ virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileInvoke (ProfileInvoke* x); + virtual void do_RuntimeCall (RuntimeCall* x); }; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_Optimizer.cpp --- a/src/share/vm/c1/c1_Optimizer.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_Optimizer.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -496,6 +496,7 @@ void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); void do_ProfileCall (ProfileCall* x); void do_ProfileInvoke (ProfileInvoke* x); + void do_RuntimeCall (RuntimeCall* x); }; @@ -664,6 +665,7 @@ void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); } void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {} +void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {} void NullCheckEliminator::visit(Value* p) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_Runtime1.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -339,8 +339,10 @@ JRT_END -JRT_ENTRY(void, Runtime1::throw_array_store_exception(JavaThread* thread)) - THROW(vmSymbolHandles::java_lang_ArrayStoreException()); +JRT_ENTRY(void, Runtime1::throw_array_store_exception(JavaThread* thread, oopDesc* obj)) + ResourceMark rm(thread); + const char* klass_name = Klass::cast(obj->klass())->external_name(); + SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayStoreException(), klass_name); JRT_END diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_Runtime1.hpp --- a/src/share/vm/c1/c1_Runtime1.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_Runtime1.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,9 +143,9 @@ static void throw_index_exception(JavaThread* thread, int index); static void throw_div0_exception(JavaThread* thread); static void throw_null_pointer_exception(JavaThread* thread); - static void throw_class_cast_exception(JavaThread* thread, oopDesc* obect); + static void throw_class_cast_exception(JavaThread* thread, oopDesc* object); static void throw_incompatible_class_change_error(JavaThread* thread); - static void throw_array_store_exception(JavaThread* thread); + static void throw_array_store_exception(JavaThread* thread, oopDesc* object); static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock); static void monitorexit (JavaThread* thread, BasicObjectLock* lock); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/c1/c1_ValueMap.hpp --- a/src/share/vm/c1/c1_ValueMap.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/c1/c1_ValueMap.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -192,11 +192,12 @@ void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ } void do_RoundFP (RoundFP* x) { /* nothing to do */ } void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ } - void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ } void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ } void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ } void do_ProfileCall (ProfileCall* x) { /* nothing to do */ } + void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; + void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ }; }; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/bcEscapeAnalyzer.cpp --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -233,6 +233,10 @@ // compute size of arguments int arg_size = target->arg_size(); + if (code == Bytecodes::_invokedynamic) { + assert(!target->is_static(), "receiver explicit in method"); + arg_size--; // implicit, not really on stack + } if (!target->is_loaded() && code == Bytecodes::_invokestatic) { arg_size--; } @@ -250,6 +254,10 @@ ArgumentMap arg = state._stack[i]; skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base)); } + // For now we conservatively skip invokedynamic. + if (code == Bytecodes::_invokedynamic) { + skip_callee = true; + } if (skip_callee) { TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8())); for (i = 0; i < arg_size; i++) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciClassList.hpp --- a/src/share/vm/ci/ciClassList.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciClassList.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -60,7 +60,6 @@ class ciKlass; class ciInstanceKlass; class ciMethodKlass; -class ciSymbolKlass; class ciArrayKlass; class ciObjArrayKlass; class ciTypeArrayKlass; @@ -112,7 +111,6 @@ friend class ciKlass; \ friend class ciInstanceKlass; \ friend class ciMethodKlass; \ -friend class ciSymbolKlass; \ friend class ciArrayKlass; \ friend class ciObjArrayKlass; \ friend class ciTypeArrayKlass; \ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciEnv.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -68,7 +68,6 @@ ciObject* ciEnv::_null_object_instance; ciMethodKlass* ciEnv::_method_klass_instance; -ciSymbolKlass* ciEnv::_symbol_klass_instance; ciKlassKlass* ciEnv::_klass_klass_instance; ciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance; ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance; @@ -202,6 +201,7 @@ ciEnv::~ciEnv() { CompilerThread* current_thread = CompilerThread::current(); + _factory->remove_symbols(); current_thread->set_env(NULL); } @@ -234,7 +234,7 @@ // ------------------------------------------------------------------ // helper for lazy exception creation -ciInstance* ciEnv::get_or_create_exception(jobject& handle, symbolHandle name) { +ciInstance* ciEnv::get_or_create_exception(jobject& handle, Symbol* name) { VM_ENTRY_MARK; if (handle == NULL) { // Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance. @@ -261,7 +261,7 @@ if (_ArrayIndexOutOfBoundsException_instance == NULL) { _ArrayIndexOutOfBoundsException_instance = get_or_create_exception(_ArrayIndexOutOfBoundsException_handle, - vmSymbolHandles::java_lang_ArrayIndexOutOfBoundsException()); + vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); } return _ArrayIndexOutOfBoundsException_instance; } @@ -269,7 +269,7 @@ if (_ArrayStoreException_instance == NULL) { _ArrayStoreException_instance = get_or_create_exception(_ArrayStoreException_handle, - vmSymbolHandles::java_lang_ArrayStoreException()); + vmSymbols::java_lang_ArrayStoreException()); } return _ArrayStoreException_instance; } @@ -277,7 +277,7 @@ if (_ClassCastException_instance == NULL) { _ClassCastException_instance = get_or_create_exception(_ClassCastException_handle, - vmSymbolHandles::java_lang_ClassCastException()); + vmSymbols::java_lang_ClassCastException()); } return _ClassCastException_instance; } @@ -377,14 +377,16 @@ EXCEPTION_CONTEXT; // Now we need to check the SystemDictionary - symbolHandle sym(THREAD, name->get_symbolOop()); + Symbol* sym = name->get_symbol(); if (sym->byte_at(0) == 'L' && sym->byte_at(sym->utf8_length()-1) == ';') { // This is a name from a signature. Strip off the trimmings. - sym = oopFactory::new_symbol_handle(sym->as_utf8()+1, - sym->utf8_length()-2, - KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); - name = get_object(sym())->as_symbol(); + // Call recursive to keep scope of strippedsym. + TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, + sym->utf8_length()-2, + KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); + ciSymbol* strippedname = get_symbol(strippedsym); + return get_klass_by_name_impl(accessing_klass, strippedname, require_local); } // Check for prior unloaded klass. The SystemDictionary's answers @@ -430,13 +432,14 @@ (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { // We have an unloaded array. // Build it on the fly if the element class exists. - symbolOop elem_sym = oopFactory::new_symbol(sym->as_utf8()+1, - sym->utf8_length()-1, - KILL_COMPILE_ON_FATAL_(fail_type)); + TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1, + sym->utf8_length()-1, + KILL_COMPILE_ON_FATAL_(fail_type)); + // Get element ciKlass recursively. ciKlass* elem_klass = get_klass_by_name_impl(accessing_klass, - get_object(elem_sym)->as_symbol(), + get_symbol(elem_sym), require_local); if (elem_klass != NULL && elem_klass->is_loaded()) { // Now make an array for it @@ -475,7 +478,7 @@ ciInstanceKlass* accessor) { EXCEPTION_CONTEXT; KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index)); - symbolHandle klass_name; + Symbol* klass_name = NULL; if (klass.is_null()) { // The klass has not been inserted into the constant pool. // Try to look it up by name. @@ -490,10 +493,10 @@ // very recently. klass = KlassHandle(THREAD, cpool->resolved_klass_at(index)); } else if (tag.is_symbol()) { - klass_name = symbolHandle(THREAD, cpool->symbol_at(index)); + klass_name = cpool->symbol_at(index); } else { assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag"); - klass_name = symbolHandle(THREAD, cpool->unresolved_klass_at(index)); + klass_name = cpool->unresolved_klass_at(index); } } } @@ -501,7 +504,7 @@ if (klass.is_null()) { // Not found in constant pool. Use the name to do the lookup. ciKlass* k = get_klass_by_name_impl(accessor, - get_object(klass_name())->as_symbol(), + get_symbol(klass_name), false); // Calculate accessibility the hard way. if (!k->is_loaded()) { @@ -519,7 +522,7 @@ // Check for prior unloaded klass. The SystemDictionary's answers // can vary over time but the compiler needs consistency. - ciSymbol* name = get_object(klass()->klass_part()->name())->as_symbol(); + ciSymbol* name = get_symbol(klass()->klass_part()->name()); ciKlass* unloaded_klass = check_get_unloaded_klass(accessor, name); if (unloaded_klass != NULL) { is_accessible = false; @@ -605,7 +608,7 @@ return ciConstant(T_OBJECT, ciobj); } else if (tag.is_method_type()) { // must execute Java code to link this CP entry into cache[i].f1 - ciSymbol* signature = get_object(cpool->method_type_signature_at(index))->as_symbol(); + ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index)); ciObject* ciobj = get_unloaded_method_type_constant(signature); return ciConstant(T_OBJECT, ciobj); } else if (tag.is_method_handle()) { @@ -613,8 +616,8 @@ int ref_kind = cpool->method_handle_ref_kind_at(index); int callee_index = cpool->method_handle_klass_index_at(index); ciKlass* callee = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor); - ciSymbol* name = get_object(cpool->method_handle_name_ref_at(index))->as_symbol(); - ciSymbol* signature = get_object(cpool->method_handle_signature_ref_at(index))->as_symbol(); + ciSymbol* name = get_symbol(cpool->method_handle_name_ref_at(index)); + ciSymbol* signature = get_symbol(cpool->method_handle_signature_ref_at(index)); ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind); return ciConstant(T_OBJECT, ciobj); } else { @@ -674,33 +677,31 @@ // name, signature, and bytecode. methodOop ciEnv::lookup_method(instanceKlass* accessor, instanceKlass* holder, - symbolOop name, - symbolOop sig, + Symbol* name, + Symbol* sig, Bytecodes::Code bc) { EXCEPTION_CONTEXT; KlassHandle h_accessor(THREAD, accessor); KlassHandle h_holder(THREAD, holder); - symbolHandle h_name(THREAD, name); - symbolHandle h_sig(THREAD, sig); LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); methodHandle dest_method; switch (bc) { case Bytecodes::_invokestatic: dest_method = - LinkResolver::resolve_static_call_or_null(h_holder, h_name, h_sig, h_accessor); + LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor); break; case Bytecodes::_invokespecial: dest_method = - LinkResolver::resolve_special_call_or_null(h_holder, h_name, h_sig, h_accessor); + LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor); break; case Bytecodes::_invokeinterface: dest_method = - LinkResolver::linktime_resolve_interface_method_or_null(h_holder, h_name, h_sig, + LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig, h_accessor, true); break; case Bytecodes::_invokevirtual: dest_method = - LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, h_name, h_sig, + LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig, h_accessor, true); break; default: ShouldNotReachHere(); @@ -721,8 +722,8 @@ ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); // Get the method's name and signature. - symbolOop name_sym = cpool->name_ref_at(index); - symbolOop sig_sym = cpool->signature_ref_at(index); + Symbol* name_sym = cpool->name_ref_at(index); + Symbol* sig_sym = cpool->signature_ref_at(index); if (holder_is_accessible) { // Our declared holder is loaded. instanceKlass* lookup = declared_holder->get_instanceKlass(); @@ -738,8 +739,8 @@ // lookup. return get_unloaded_method(declared_holder, - get_object(name_sym)->as_symbol(), - get_object(sig_sym)->as_symbol()); + get_symbol(name_sym), + get_symbol(sig_sym)); } @@ -759,7 +760,7 @@ // compiler, but it is simpler to stop the code path here with an unlinked method. if (!is_resolved) { ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); - ciSymbol* sig_sym = get_object(cpool->signature_ref_at(index))->as_symbol(); + ciSymbol* sig_sym = get_symbol(cpool->signature_ref_at(index)); return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciEnv.hpp --- a/src/share/vm/ci/ciEnv.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciEnv.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -79,7 +79,6 @@ // Distinguished instances of certain ciObjects.. static ciObject* _null_object_instance; static ciMethodKlass* _method_klass_instance; - static ciSymbolKlass* _symbol_klass_instance; static ciKlassKlass* _klass_klass_instance; static ciInstanceKlassKlass* _instance_klass_klass_instance; static ciTypeArrayKlassKlass* _type_array_klass_klass_instance; @@ -160,8 +159,8 @@ klassOop resolved_klassOop); methodOop lookup_method(instanceKlass* accessor, instanceKlass* holder, - symbolOop name, - symbolOop sig, + Symbol* name, + Symbol* sig, Bytecodes::Code bc); // Get a ciObject from the object factory. Ensures uniqueness @@ -174,9 +173,18 @@ } } + ciSymbol* get_symbol(Symbol* o) { + if (o == NULL) { + ShouldNotReachHere(); + return NULL; + } else { + return _factory->get_symbol(o); + } + } + ciMethod* get_method_from_handle(jobject method); - ciInstance* get_or_create_exception(jobject& handle, symbolHandle name); + ciInstance* get_or_create_exception(jobject& handle, Symbol* name); // Get a ciMethod representing either an unfound method or // a method with an unloaded holder. Ensures uniqueness of diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciField.cpp --- a/src/share/vm/ci/ciField.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciField.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -79,15 +79,15 @@ constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); // Get the field's name, signature, and type. - symbolHandle name (thread, cpool->name_ref_at(index)); - _name = ciEnv::current(thread)->get_object(name())->as_symbol(); + Symbol* name = cpool->name_ref_at(index); + _name = ciEnv::current(thread)->get_symbol(name); int nt_index = cpool->name_and_type_ref_index_at(index); int sig_index = cpool->signature_ref_index_at(nt_index); - symbolHandle signature (thread, cpool->symbol_at(sig_index)); - _signature = ciEnv::current(thread)->get_object(signature())->as_symbol(); + Symbol* signature = cpool->symbol_at(sig_index); + _signature = ciEnv::current(thread)->get_symbol(signature); - BasicType field_type = FieldType::basic_type(signature()); + BasicType field_type = FieldType::basic_type(signature); // If the field is a pointer type, get the klass of the // field. @@ -100,7 +100,7 @@ _type = ciType::make(field_type); } - _name = (ciSymbol*)ciEnv::current(thread)->get_object(name()); + _name = (ciSymbol*)ciEnv::current(thread)->get_symbol(name); // Get the field's declared holder. // @@ -130,7 +130,7 @@ // Perform the field lookup. fieldDescriptor field_desc; klassOop canonical_holder = - loaded_decl_holder->find_field(name(), signature(), &field_desc); + loaded_decl_holder->find_field(name, signature, &field_desc); if (canonical_holder == NULL) { // Field lookup failed. Will be detected by will_link. _holder = declared_holder; @@ -150,8 +150,8 @@ // Get the field's name, signature, and type. ciEnv* env = CURRENT_ENV; - _name = env->get_object(fd->name())->as_symbol(); - _signature = env->get_object(fd->signature())->as_symbol(); + _name = env->get_symbol(fd->name()); + _signature = env->get_symbol(fd->signature()); BasicType field_type = fd->field_type(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciInstanceKlass.cpp --- a/src/share/vm/ci/ciInstanceKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -380,7 +380,7 @@ VM_ENTRY_MARK; instanceKlass* k = get_instanceKlass(); fieldDescriptor fd; - klassOop def = k->find_field(name->get_symbolOop(), signature->get_symbolOop(), is_static, &fd); + klassOop def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd); if (def == NULL) { return NULL; } @@ -541,8 +541,8 @@ ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { VM_ENTRY_MARK; instanceKlass* k = get_instanceKlass(); - symbolOop name_sym = name->get_symbolOop(); - symbolOop sig_sym= signature->get_symbolOop(); + Symbol* name_sym = name->get_symbol(); + Symbol* sig_sym= signature->get_symbol(); methodOop m = k->find_method(name_sym, sig_sym); if (m == NULL) return NULL; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciKlass.cpp --- a/src/share/vm/ci/ciKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -39,9 +39,9 @@ assert(get_oop()->is_klass(), "wrong type"); Klass* k = get_Klass(); _layout_helper = k->layout_helper(); - symbolOop klass_name = k->name(); + Symbol* klass_name = k->name(); assert(klass_name != NULL, "wrong ciKlass constructor"); - _name = CURRENT_ENV->get_object(klass_name)->as_symbol(); + _name = CURRENT_ENV->get_symbol(klass_name); } // ------------------------------------------------------------------ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciMethod.cpp --- a/src/share/vm/ci/ciMethod.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciMethod.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -122,9 +122,9 @@ // generating _signature may allow GC and therefore move m. // These fields are always filled in. - _name = env->get_object(h_m()->name())->as_symbol(); + _name = env->get_symbol(h_m()->name()); _holder = env->get_object(h_m()->method_holder())->as_instance_klass(); - ciSymbol* sig_symbol = env->get_object(h_m()->signature())->as_symbol(); + ciSymbol* sig_symbol = env->get_symbol(h_m()->signature()); _signature = new (env->arena()) ciSignature(_holder, sig_symbol); _method_data = NULL; // Take a snapshot of these values, so they will be commensurate with the MDO. @@ -649,8 +649,8 @@ KlassHandle caller_klass (THREAD, caller->get_klassOop()); KlassHandle h_recv (THREAD, exact_receiver->get_klassOop()); KlassHandle h_resolved (THREAD, holder()->get_klassOop()); - symbolHandle h_name (THREAD, name()->get_symbolOop()); - symbolHandle h_signature (THREAD, signature()->get_symbolOop()); + Symbol* h_name = name()->get_symbol(); + Symbol* h_signature = signature()->get_symbol(); methodHandle m; // Only do exact lookup if receiver klass has been linked. Otherwise, @@ -702,8 +702,8 @@ KlassHandle caller_klass (THREAD, caller->get_klassOop()); KlassHandle h_recv (THREAD, receiver->get_klassOop()); - symbolHandle h_name (THREAD, name()->get_symbolOop()); - symbolHandle h_signature (THREAD, signature()->get_symbolOop()); + Symbol* h_name = name()->get_symbol(); + Symbol* h_signature = signature()->get_symbol(); vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass); if (vtable_index == methodOopDesc::nonvirtual_vtable_index) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciObjArrayKlass.cpp --- a/src/share/vm/ci/ciObjArrayKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciObjArrayKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -110,7 +110,7 @@ EXCEPTION_CONTEXT; int element_len = element_name->utf8_length(); - symbolOop base_name_sym = element_name->get_symbolOop(); + Symbol* base_name_sym = element_name->get_symbol(); char* name; if (base_name_sym->byte_at(0) == '[' || diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciObject.hpp --- a/src/share/vm/ci/ciObject.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciObject.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -268,10 +268,6 @@ assert(is_type_array_klass(), "bad cast"); return (ciTypeArrayKlass*)this; } - ciSymbolKlass* as_symbol_klass() { - assert(is_symbol_klass(), "bad cast"); - return (ciSymbolKlass*)this; - } ciKlassKlass* as_klass_klass() { assert(is_klass_klass(), "bad cast"); return (ciKlassKlass*)this; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciObjectFactory.cpp --- a/src/share/vm/ci/ciObjectFactory.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciObjectFactory.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -38,7 +38,6 @@ #include "ci/ciObjArrayKlassKlass.hpp" #include "ci/ciObjectFactory.hpp" #include "ci/ciSymbol.hpp" -#include "ci/ciSymbolKlass.hpp" #include "ci/ciTypeArray.hpp" #include "ci/ciTypeArrayKlass.hpp" #include "ci/ciTypeArrayKlassKlass.hpp" @@ -98,6 +97,8 @@ _unloaded_instances = new (arena) GrowableArray(arena, 4, 0, NULL); _return_addresses = new (arena) GrowableArray(arena, 8, 0, NULL); + + _symbols = new (arena) GrowableArray(arena, 100, 0, NULL); } // ------------------------------------------------------------------ @@ -127,19 +128,19 @@ // Create the shared symbols, but not in _shared_ci_objects. int i; for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { - symbolHandle sym_handle = vmSymbolHandles::symbol_handle_at((vmSymbols::SID) i); - assert(vmSymbols::find_sid(sym_handle()) == i, "1-1 mapping"); - ciSymbol* sym = new (_arena) ciSymbol(sym_handle, (vmSymbols::SID) i); + Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i); + assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping"); + ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i); init_ident_of(sym); _shared_ci_symbols[i] = sym; } #ifdef ASSERT for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { - symbolHandle sym_handle = vmSymbolHandles::symbol_handle_at((vmSymbols::SID) i); + Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i); ciSymbol* sym = vm_symbol_at((vmSymbols::SID) i); - assert(sym->get_oop() == sym_handle(), "oop must match"); + assert(sym->get_symbol() == vmsym, "oop must match"); } - assert(ciSymbol::void_class_signature()->get_oop() == vmSymbols::void_class_signature(), "spot check"); + assert(ciSymbol::void_class_signature()->get_symbol() == vmSymbols::void_class_signature(), "spot check"); #endif } @@ -157,8 +158,6 @@ init_ident_of(ciEnv::_null_object_instance); ciEnv::_method_klass_instance = get(Universe::methodKlassObj())->as_method_klass(); - ciEnv::_symbol_klass_instance = - get(Universe::symbolKlassObj())->as_symbol_klass(); ciEnv::_klass_klass_instance = get(Universe::klassKlassObj())->as_klass_klass(); ciEnv::_instance_klass_klass_instance = @@ -188,7 +187,7 @@ } } - ciEnv::_unloaded_cisymbol = (ciSymbol*) ciObjectFactory::get(vmSymbols::dummy_symbol_oop()); + ciEnv::_unloaded_cisymbol = ciObjectFactory::get_symbol(vmSymbols::dummy_symbol()); // Create dummy instanceKlass and objArrayKlass object and assign them idents ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL); init_ident_of(ciEnv::_unloaded_ciinstance_klass); @@ -218,6 +217,30 @@ _shared_ci_objects = _ci_objects; } + +ciSymbol* ciObjectFactory::get_symbol(Symbol* key) { + vmSymbols::SID sid = vmSymbols::find_sid(key); + if (sid != vmSymbols::NO_SID) { + // do not pollute the main cache with it + return vm_symbol_at(sid); + } + + assert(vmSymbols::find_sid(key) == vmSymbols::NO_SID, ""); + ciSymbol* s = new (arena()) ciSymbol(key, vmSymbols::NO_SID); + _symbols->push(s); + return s; +} + +// Decrement the refcount when done on symbols referenced by this compilation. +void ciObjectFactory::remove_symbols() { + for (int i = 0; i < _symbols->length(); i++) { + ciSymbol* s = _symbols->at(i); + s->get_symbol()->decrement_refcount(); + } + // Since _symbols is resource allocated we're not allowed to delete it + // but it'll go away just the same. +} + // ------------------------------------------------------------------ // ciObjectFactory::get // @@ -255,15 +278,6 @@ return bucket->object(); } - // Check in the shared symbol area before putting it in the list. - if (key->is_symbol()) { - vmSymbols::SID sid = vmSymbols::find_sid((symbolOop)key); - if (sid != vmSymbols::NO_SID) { - // do not pollute the main cache with it - return vm_symbol_at(sid); - } - } - // The ciObject does not yet exist. Create it and insert it // into the cache. Handle keyHandle(key); @@ -297,11 +311,7 @@ ciObject* ciObjectFactory::create_new_object(oop o) { EXCEPTION_CONTEXT; - if (o->is_symbol()) { - symbolHandle h_o(THREAD, (symbolOop)o); - assert(vmSymbols::find_sid(h_o()) == vmSymbols::NO_SID, ""); - return new (arena()) ciSymbol(h_o, vmSymbols::NO_SID); - } else if (o->is_klass()) { + if (o->is_klass()) { KlassHandle h_k(THREAD, (klassOop)o); Klass* k = ((klassOop)o)->klass_part(); if (k->oop_is_instance()) { @@ -312,8 +322,6 @@ return new (arena()) ciTypeArrayKlass(h_k); } else if (k->oop_is_method()) { return new (arena()) ciMethodKlass(h_k); - } else if (k->oop_is_symbol()) { - return new (arena()) ciSymbolKlass(h_k); } else if (k->oop_is_klass()) { if (k->oop_is_objArrayKlass()) { return new (arena()) ciObjArrayKlassKlass(h_k); @@ -426,22 +434,20 @@ // unloaded instanceKlass. Deal with both. if (name->byte_at(0) == '[') { // Decompose the name.' - jint dimension = 0; - symbolOop element_name = NULL; - BasicType element_type= FieldType::get_array_info(name->get_symbolOop(), - &dimension, - &element_name, - THREAD); + FieldArrayInfo fd; + BasicType element_type = FieldType::get_array_info(name->get_symbol(), + fd, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; CURRENT_THREAD_ENV->record_out_of_memory_failure(); return ciEnv::_unloaded_ciobjarrayklass; } + int dimension = fd.dimension(); assert(element_type != T_ARRAY, "unsuccessful decomposition"); ciKlass* element_klass = NULL; if (element_type == T_OBJECT) { ciEnv *env = CURRENT_THREAD_ENV; - ciSymbol* ci_name = env->get_object(element_name)->as_symbol(); + ciSymbol* ci_name = env->get_symbol(fd.object_key()); element_klass = env->get_klass_by_name(accessing_klass, ci_name, false)->as_instance_klass(); } else { @@ -573,6 +579,10 @@ obj->set_ident(_next_ident++); } +void ciObjectFactory::init_ident_of(ciSymbol* obj) { + obj->set_ident(_next_ident++); +} + // ------------------------------------------------------------------ // ciObjectFactory::find diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciObjectFactory.hpp --- a/src/share/vm/ci/ciObjectFactory.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciObjectFactory.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -48,6 +48,7 @@ GrowableArray* _unloaded_klasses; GrowableArray* _unloaded_instances; GrowableArray* _return_addresses; + GrowableArray* _symbols; // keep list of symbols created int _next_ident; public: @@ -76,6 +77,7 @@ void insert_non_perm(NonPermObject* &where, oop key, ciObject* obj); void init_ident_of(ciObject* obj); + void init_ident_of(ciSymbol* obj); Arena* arena() { return _arena; } @@ -88,13 +90,15 @@ static void initialize(); void init_shared_objects(); + void remove_symbols(); ciObjectFactory(Arena* arena, int expected_size); - // Get the ciObject corresponding to some oop. ciObject* get(oop key); + ciSymbol* get_symbol(Symbol* key); + // Get the ciSymbol corresponding to one of the vmSymbols. static ciSymbol* vm_symbol_at(int index); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciSignature.cpp --- a/src/share/vm/ci/ciSignature.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciSignature.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -47,7 +47,8 @@ int size = 0; int count = 0; - symbolHandle sh (THREAD, symbol->get_symbolOop()); + ResourceMark rm(THREAD); + Symbol* sh = symbol->get_symbol(); SignatureStream ss(sh); for (; ; ss.next()) { // Process one element of the signature @@ -55,14 +56,14 @@ if (!ss.is_object()) { type = ciType::make(ss.type()); } else { - symbolOop name = ss.as_symbol(THREAD); + Symbol* name = ss.as_symbol(THREAD); if (HAS_PENDING_EXCEPTION) { type = ss.is_array() ? (ciType*)ciEnv::unloaded_ciobjarrayklass() : (ciType*)ciEnv::unloaded_ciinstance_klass(); env->record_out_of_memory_failure(); CLEAR_PENDING_EXCEPTION; } else { - ciSymbol* klass_name = env->get_object(name)->as_symbol(); + ciSymbol* klass_name = env->get_symbol(name); type = env->get_klass_by_name_impl(_accessing_klass, klass_name, false); } } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciSignature.hpp --- a/src/share/vm/ci/ciSignature.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciSignature.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -48,7 +48,7 @@ void get_all_klasses(); - symbolOop get_symbolOop() const { return _symbol->get_symbolOop(); } + Symbol* get_symbol() const { return _symbol->get_symbol(); } public: ciSymbol* as_symbol() const { return _symbol; } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciSymbol.cpp --- a/src/share/vm/ci/ciSymbol.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciSymbol.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -30,23 +30,27 @@ // ------------------------------------------------------------------ // ciSymbol::ciSymbol // -// Preallocated handle variant. Used with handles from vmSymboHandles. -ciSymbol::ciSymbol(symbolHandle h_s, vmSymbols::SID sid) - : ciObject(h_s), _sid(sid) +// Preallocated symbol variant. Used with symbols from vmSymbols. +ciSymbol::ciSymbol(Symbol* s, vmSymbols::SID sid) + : _symbol(s), _sid(sid) { + assert(_symbol != NULL, "adding null symbol"); + _symbol->increment_refcount(); // increment ref count assert(sid_ok(), "must be in vmSymbols"); } // Normal case for non-famous symbols. -ciSymbol::ciSymbol(symbolOop s) - : ciObject(s), _sid(vmSymbols::NO_SID) +ciSymbol::ciSymbol(Symbol* s) + : _symbol(s), _sid(vmSymbols::NO_SID) { + assert(_symbol != NULL, "adding null symbol"); + _symbol->increment_refcount(); // increment ref count assert(sid_ok(), "must not be in vmSymbols"); } // ciSymbol // -// This class represents a symbolOop in the HotSpot virtual +// This class represents a Symbol* in the HotSpot virtual // machine. // ------------------------------------------------------------------ @@ -55,20 +59,20 @@ // The text of the symbol as a null-terminated C string. const char* ciSymbol::as_utf8() { VM_QUICK_ENTRY_MARK; - symbolOop s = get_symbolOop(); + Symbol* s = get_symbol(); return s->as_utf8(); } // ------------------------------------------------------------------ // ciSymbol::base -jbyte* ciSymbol::base() { - GUARDED_VM_ENTRY(return get_symbolOop()->base();) +const jbyte* ciSymbol::base() { + GUARDED_VM_ENTRY(return get_symbol()->base();) } // ------------------------------------------------------------------ // ciSymbol::byte_at int ciSymbol::byte_at(int i) { - GUARDED_VM_ENTRY(return get_symbolOop()->byte_at(i);) + GUARDED_VM_ENTRY(return get_symbol()->byte_at(i);) } // ------------------------------------------------------------------ @@ -76,7 +80,7 @@ // // Tests if the symbol starts with the given prefix. bool ciSymbol::starts_with(const char* prefix, int len) const { - GUARDED_VM_ENTRY(return get_symbolOop()->starts_with(prefix, len);) + GUARDED_VM_ENTRY(return get_symbol()->starts_with(prefix, len);) } // ------------------------------------------------------------------ @@ -84,13 +88,13 @@ // // Determines where the symbol contains the given substring. int ciSymbol::index_of_at(int i, const char* str, int len) const { - GUARDED_VM_ENTRY(return get_symbolOop()->index_of_at(i, str, len);) + GUARDED_VM_ENTRY(return get_symbol()->index_of_at(i, str, len);) } // ------------------------------------------------------------------ // ciSymbol::utf8_length int ciSymbol::utf8_length() { - GUARDED_VM_ENTRY(return get_symbolOop()->utf8_length();) + GUARDED_VM_ENTRY(return get_symbol()->utf8_length();) } // ------------------------------------------------------------------ @@ -107,7 +111,7 @@ // // Print the value of this symbol on an outputStream void ciSymbol::print_symbol_on(outputStream *st) { - GUARDED_VM_ENTRY(get_symbolOop()->print_symbol_on(st);) + GUARDED_VM_ENTRY(get_symbol()->print_symbol_on(st);) } // ------------------------------------------------------------------ @@ -116,15 +120,13 @@ // Make a ciSymbol from a C string (implementation). ciSymbol* ciSymbol::make_impl(const char* s) { EXCEPTION_CONTEXT; - // For some reason, oopFactory::new_symbol doesn't declare its - // char* argument as const. - symbolOop sym = oopFactory::new_symbol((char*)s, (int)strlen(s), THREAD); + TempNewSymbol sym = SymbolTable::new_symbol(s, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; CURRENT_THREAD_ENV->record_out_of_memory_failure(); return ciEnv::_unloaded_cisymbol; } - return CURRENT_THREAD_ENV->get_object(sym)->as_symbol(); + return CURRENT_THREAD_ENV->get_symbol(sym); } // ------------------------------------------------------------------ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciSymbol.hpp --- a/src/share/vm/ci/ciSymbol.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/ciSymbol.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -28,15 +28,18 @@ #include "ci/ciObject.hpp" #include "ci/ciObjectFactory.hpp" #include "classfile/vmSymbols.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" // ciSymbol // -// This class represents a symbolOop in the HotSpot virtual +// This class represents a Symbol* in the HotSpot virtual // machine. -class ciSymbol : public ciObject { +class ciSymbol : public ResourceObj { + Symbol* _symbol; + uint _ident; + CI_PACKAGE_ACCESS - // These friends all make direct use of get_symbolOop: + // These friends all make direct use of get_symbol: friend class ciEnv; friend class ciInstanceKlass; friend class ciSignature; @@ -45,24 +48,28 @@ private: const vmSymbols::SID _sid; - DEBUG_ONLY( bool sid_ok() { return vmSymbols::find_sid(get_symbolOop()) == _sid; } ) + DEBUG_ONLY( bool sid_ok() { return vmSymbols::find_sid(get_symbol()) == _sid; } ) - ciSymbol(symbolOop s); // normal case, for symbols not mentioned in vmSymbols - ciSymbol(symbolHandle s, vmSymbols::SID sid); // for use with vmSymbolHandles + ciSymbol(Symbol* s); // normal case, for symbols not mentioned in vmSymbols + ciSymbol(Symbol* s, vmSymbols::SID sid); // for use with vmSymbols - symbolOop get_symbolOop() const { return (symbolOop)get_oop(); } + Symbol* get_symbol() const { return _symbol; } const char* type_string() { return "ciSymbol"; } void print_impl(outputStream* st); - // This is public in symbolOop but private here, because the base can move: - jbyte* base(); + // This is public in Symbol* but private here, because the base can move: + const jbyte* base(); // Make a ciSymbol from a C string (implementation). static ciSymbol* make_impl(const char* s); + void set_ident(uint id) { _ident = id; } public: + // A number unique to this object. + uint ident() { return _ident; } + // The enumeration ID from vmSymbols, or vmSymbols::NO_SID if none. vmSymbols::SID sid() const { return _sid; } @@ -79,9 +86,6 @@ // Determines where the symbol contains the given substring. int index_of_at(int i, const char* str, int len) const; - // What kind of ciObject is this? - bool is_symbol() { return true; } - void print_symbol_on(outputStream* st); void print_symbol() { print_symbol_on(tty); @@ -96,6 +100,13 @@ static ciSymbol* name() { return ciObjectFactory::vm_symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(name)); } VM_SYMBOLS_DO(CI_SYMBOL_DECLARE, CI_SYMBOL_DECLARE) #undef CI_SYMBOL_DECLARE + + void print() { + _symbol->print(); + } + + // Are two ciSymbols equal? + bool equals(ciSymbol* obj) { return this->_symbol == obj->get_symbol(); } }; #endif // SHARE_VM_CI_CISYMBOL_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciSymbolKlass.cpp --- a/src/share/vm/ci/ciSymbolKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "ci/ciSymbolKlass.hpp" -#include "ci/ciUtilities.hpp" - -// ciSymbolKlass -// -// This class represents a klassOop in the HotSpot virtual machine -// whose Klass part is a symbolKlass. - -// ------------------------------------------------------------------ -// ciSymbolKlass::instance -// -// Return the distinguished instance of this class -ciSymbolKlass* ciSymbolKlass::make() { - return CURRENT_ENV->_symbol_klass_instance; -} diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/ciSymbolKlass.hpp --- a/src/share/vm/ci/ciSymbolKlass.hpp Thu Feb 03 17:22:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_CI_CISYMBOLKLASS_HPP -#define SHARE_VM_CI_CISYMBOLKLASS_HPP - -#include "ci/ciKlass.hpp" -#include "ci/ciSymbol.hpp" - -// ciSymbolKlass -// -// This class represents a klassOop in the HotSpot virtual machine -// whose Klass part in a symbolKlass. Although, in the VM -// Klass hierarchy, symbolKlass is a direct subclass of typeArrayKlass, -// we do not model this relationship in the ciObject hierarchy -- the -// subclassing is used to share implementation and is not of note -// to compiler writers. -class ciSymbolKlass : public ciKlass { - CI_PACKAGE_ACCESS - -protected: - ciSymbolKlass(KlassHandle h_k) - : ciKlass(h_k, ciSymbol::make("unique_symbolKlass")) { - assert(get_Klass()->oop_is_symbol(), "wrong type"); - } - - symbolKlass* get_symbolKlass() { return (symbolKlass*)get_Klass(); } - - const char* type_string() { return "ciSymbolKlass"; } - -public: - // What kind of ciObject is this? - bool is_symbol_klass() { return true; } - - // Return the distinguished ciSymbolKlass instance. - static ciSymbolKlass* make(); -}; - -#endif // SHARE_VM_CI_CISYMBOLKLASS_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/ci/compilerInterface.hpp --- a/src/share/vm/ci/compilerInterface.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/ci/compilerInterface.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -49,7 +49,6 @@ #include "ci/ciSignature.hpp" #include "ci/ciStreams.hpp" #include "ci/ciSymbol.hpp" -#include "ci/ciSymbolKlass.hpp" #include "ci/ciTypeArray.hpp" #include "ci/ciTypeArrayKlass.hpp" #include "ci/ciTypeArrayKlassKlass.hpp" diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/classFileError.cpp --- a/src/share/vm/classfile/classFileError.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/classFileError.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,25 +31,25 @@ void ClassFileParser::classfile_parse_error(const char* msg, TRAPS) { ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbolHandles::java_lang_ClassFormatError(), + Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), msg, _class_name->as_C_string()); } void ClassFileParser::classfile_parse_error(const char* msg, int index, TRAPS) { ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbolHandles::java_lang_ClassFormatError(), + Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), msg, index, _class_name->as_C_string()); } void ClassFileParser::classfile_parse_error(const char* msg, const char *name, TRAPS) { ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbolHandles::java_lang_ClassFormatError(), + Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), msg, name, _class_name->as_C_string()); } void ClassFileParser::classfile_parse_error(const char* msg, int index, const char *name, TRAPS) { ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbolHandles::java_lang_ClassFormatError(), + Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), msg, index, name, _class_name->as_C_string()); } @@ -57,7 +57,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_ClassFormatError(), + vmSymbols::java_lang_ClassFormatError(), "StackMapTable format error: %s", msg ); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/classFileParser.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -41,7 +41,7 @@ #include "oops/klassOop.hpp" #include "oops/klassVtable.hpp" #include "oops/methodOop.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/javaCalls.hpp" #include "runtime/perfData.hpp" @@ -267,14 +267,14 @@ } unsigned int hash; - symbolOop result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash); + Symbol* result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash); if (result == NULL) { names[names_count] = (char*)utf8_buffer; lengths[names_count] = utf8_length; indices[names_count] = index; hashValues[names_count++] = hash; if (names_count == SymbolTable::symbol_alloc_batch_size) { - oopFactory::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK); + SymbolTable::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK); names_count = 0; } } else { @@ -291,7 +291,7 @@ // Allocate the remaining symbols if (names_count > 0) { - oopFactory::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK); + SymbolTable::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK); } // Copy _current pointer of local copy back to stream(). @@ -301,6 +301,23 @@ cfs0->set_current(cfs1.current()); } +// This class unreferences constant pool symbols if an error has occurred +// while parsing the class before it is assigned into the class. +// If it gets an error after that it is unloaded and the constant pool will +// be cleaned up then. +class ConstantPoolCleaner : public StackObj { + constantPoolHandle _cphandle; + bool _in_error; + public: + ConstantPoolCleaner(constantPoolHandle cp) : _cphandle(cp), _in_error(true) {} + ~ConstantPoolCleaner() { + if (_in_error && _cphandle.not_null()) { + _cphandle->unreference_symbols(); + } + } + void set_in_error(bool clean) { _in_error = clean; } +}; + bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); } constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) { @@ -319,6 +336,7 @@ constantPoolHandle cp (THREAD, constant_pool); cp->set_partially_loaded(); // Enables heap verify to work on partial constantPoolOops + ConstantPoolCleaner cp_in_error(cp); // set constant pool to be cleaned up. // parsing constant pool entries parse_constant_pool_entries(cp, length, CHECK_(nullHandle)); @@ -411,7 +429,7 @@ cp->tag_at(string_index).is_utf8(), "Invalid constant pool index %u in class file %s", string_index, CHECK_(nullHandle)); - symbolOop sym = cp->symbol_at(string_index); + Symbol* sym = cp->symbol_at(string_index); cp->unresolved_string_at_put(index, sym); } break; @@ -526,6 +544,7 @@ } if (!_need_verify) { + cp_in_error.set_in_error(false); return cp; } @@ -535,7 +554,7 @@ jbyte tag = cp->tag_at(index).value(); switch (tag) { case JVM_CONSTANT_UnresolvedClass: { - symbolHandle class_name(THREAD, cp->unresolved_klass_at(index)); + Symbol* class_name = cp->unresolved_klass_at(index); // check the name, even if _cp_patches will overwrite it verify_legal_class_name(class_name, CHECK_(nullHandle)); break; @@ -544,8 +563,8 @@ if (_need_verify && _major_version >= JAVA_7_VERSION) { int sig_index = cp->signature_ref_index_at(index); int name_index = cp->name_ref_index_at(index); - symbolHandle name(THREAD, cp->symbol_at(name_index)); - symbolHandle sig(THREAD, cp->symbol_at(sig_index)); + Symbol* name = cp->symbol_at(name_index); + Symbol* sig = cp->symbol_at(sig_index); if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) { verify_legal_method_signature(name, sig, CHECK_(nullHandle)); } else { @@ -562,8 +581,8 @@ int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); // already verified to be utf8 int signature_ref_index = cp->signature_ref_index_at(name_and_type_ref_index); - symbolHandle name(THREAD, cp->symbol_at(name_ref_index)); - symbolHandle signature(THREAD, cp->symbol_at(signature_ref_index)); + Symbol* name = cp->symbol_at(name_ref_index); + Symbol* signature = cp->symbol_at(signature_ref_index); if (tag == JVM_CONSTANT_Fieldref) { verify_legal_field_name(name, CHECK_(nullHandle)); if (_need_verify && _major_version >= JAVA_7_VERSION) { @@ -590,11 +609,11 @@ } if (tag == JVM_CONSTANT_Methodref) { // 4509014: If a class method name begins with '<', it must be "". - assert(!name.is_null(), "method name in constant pool is null"); + assert(name != NULL, "method name in constant pool is null"); unsigned int name_len = name->utf8_length(); assert(name_len > 0, "bad method name"); // already verified as legal name if (name->byte_at(0) == '<') { - if (name() != vmSymbols::object_initializer_name()) { + if (name != vmSymbols::object_initializer_name()) { classfile_parse_error( "Bad method name at constant pool index %u in class file %s", name_ref_index, CHECK_(nullHandle)); @@ -615,15 +634,15 @@ { int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index); int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); - symbolHandle name(THREAD, cp->symbol_at(name_ref_index)); + Symbol* name = cp->symbol_at(name_ref_index); if (ref_kind == JVM_REF_newInvokeSpecial) { - if (name() != vmSymbols::object_initializer_name()) { + if (name != vmSymbols::object_initializer_name()) { classfile_parse_error( "Bad constructor name at constant pool index %u in class file %s", name_ref_index, CHECK_(nullHandle)); } } else { - if (name() == vmSymbols::object_initializer_name()) { + if (name == vmSymbols::object_initializer_name()) { classfile_parse_error( "Bad method name at constant pool index %u in class file %s", name_ref_index, CHECK_(nullHandle)); @@ -636,14 +655,18 @@ break; } case JVM_CONSTANT_MethodType: { - symbolHandle no_name = vmSymbolHandles::type_name(); // place holder - symbolHandle signature(THREAD, cp->method_type_signature_at(index)); + Symbol* no_name = vmSymbols::type_name(); // place holder + Symbol* signature = cp->method_type_signature_at(index); verify_legal_method_signature(no_name, signature, CHECK_(nullHandle)); break; } + case JVM_CONSTANT_Utf8: { + assert(cp->symbol_at(index)->refcount() != 0, "count corrupted"); + } } // end of switch } // end of for + cp_in_error.set_in_error(false); return cp; } @@ -665,8 +688,8 @@ guarantee_property(java_lang_String::is_instance(patch()), "Illegal class patch at %d in class file %s", index, CHECK); - symbolHandle name = java_lang_String::as_symbol(patch(), CHECK); - cp->unresolved_klass_at_put(index, name()); + Symbol* name = java_lang_String::as_symbol(patch(), CHECK); + cp->unresolved_klass_at_put(index, name); } break; @@ -717,15 +740,15 @@ class NameSigHash: public ResourceObj { public: - symbolOop _name; // name - symbolOop _sig; // signature + Symbol* _name; // name + Symbol* _sig; // signature NameSigHash* _next; // Next entry in hash table }; #define HASH_ROW_SIZE 256 -unsigned int hash(symbolOop name, symbolOop sig) { +unsigned int hash(Symbol* name, Symbol* sig) { unsigned int raw_hash = 0; raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2); raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize; @@ -742,8 +765,8 @@ // Return true if no duplicate is found. And name/sig is added as a new entry in table. // The old format checker uses heap sort to find duplicates. // NOTE: caller should guarantee that GC doesn't happen during the life cycle -// of table since we don't expect symbolOop's to move. -bool put_after_lookup(symbolOop name, symbolOop sig, NameSigHash** table) { +// of table since we don't expect Symbol*'s to move. +bool put_after_lookup(Symbol* name, Symbol* sig, NameSigHash** table) { assert(name != NULL, "name in constant pool is NULL"); // First lookup for duplicates @@ -773,7 +796,7 @@ int length, Handle class_loader, Handle protection_domain, - symbolHandle class_name, + Symbol* class_name, TRAPS) { ClassFileStream* cfs = stream(); assert(length > 0, "only called for length>0"); @@ -793,7 +816,7 @@ if (cp->tag_at(interface_index).is_klass()) { interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index)); } else { - symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index)); + Symbol* unresolved_klass = cp->klass_name_at(interface_index); // Don't need to check legal name because it's checked when parsing constant pool. // But need to make sure it's not an array type. @@ -830,7 +853,7 @@ debug_only(No_Safepoint_Verifier nsv;) for (index = 0; index < length; index++) { klassOop k = (klassOop)interfaces->obj_at(index); - symbolOop name = instanceKlass::cast(k)->name(); + Symbol* name = instanceKlass::cast(k)->name(); // If no duplicates, add (name, NULL) in hashtable interface_names. if (!put_after_lookup(name, NULL, interface_names)) { dup = true; @@ -908,7 +931,7 @@ "Invalid field attribute index %u in class file %s", attribute_name_index, CHECK); - symbolOop attribute_name = cp->symbol_at(attribute_name_index); + Symbol* attribute_name = cp->symbol_at(attribute_name_index); if (is_static && attribute_name == vmSymbols::tag_constant_value()) { // ignore if non-static if (constantvalue_index != 0) { @@ -1031,7 +1054,7 @@ valid_cp_range(name_index, cp_size) && cp->tag_at(name_index).is_utf8(), "Invalid constant pool index %u for field name in class file %s", name_index, CHECK_(nullHandle)); - symbolHandle name(THREAD, cp->symbol_at(name_index)); + Symbol* name = cp->symbol_at(name_index); verify_legal_field_name(name, CHECK_(nullHandle)); u2 signature_index = cfs->get_u2_fast(); @@ -1040,7 +1063,7 @@ cp->tag_at(signature_index).is_utf8(), "Invalid constant pool index %u for field signature in class file %s", signature_index, CHECK_(nullHandle)); - symbolHandle sig(THREAD, cp->symbol_at(signature_index)); + Symbol* sig = cp->symbol_at(signature_index); verify_legal_field_signature(name, sig, CHECK_(nullHandle)); u2 constantvalue_index = 0; @@ -1166,9 +1189,9 @@ debug_only(No_Safepoint_Verifier nsv;) for (int i = 0; i < length*instanceKlass::next_offset; i += instanceKlass::next_offset) { int name_index = fields->ushort_at(i + instanceKlass::name_index_offset); - symbolOop name = cp->symbol_at(name_index); + Symbol* name = cp->symbol_at(name_index); int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset); - symbolOop sig = cp->symbol_at(sig_index); + Symbol* sig = cp->symbol_at(sig_index); // If no duplicates, add name/signature in hashtable names_and_sigs. if (!put_after_lookup(name, sig, names_and_sigs)) { dup = true; @@ -1422,16 +1445,16 @@ "Signature index %u in %s has bad constant type in class file %s", descriptor_index, tbl_name, CHECK_NULL); - symbolHandle name(THREAD, cp->symbol_at(name_index)); - symbolHandle sig(THREAD, cp->symbol_at(descriptor_index)); + Symbol* name = cp->symbol_at(name_index); + Symbol* sig = cp->symbol_at(descriptor_index); verify_legal_field_name(name, CHECK_NULL); u2 extra_slot = 0; if (!isLVTT) { verify_legal_field_signature(name, sig, CHECK_NULL); // 4894874: check special cases for double and long local variables - if (sig() == vmSymbols::type_signature(T_DOUBLE) || - sig() == vmSymbols::type_signature(T_LONG)) { + if (sig == vmSymbols::type_signature(T_DOUBLE) || + sig == vmSymbols::type_signature(T_LONG)) { extra_slot = 1; } } @@ -1539,7 +1562,7 @@ } void ClassFileParser::throwIllegalSignature( - const char* type, symbolHandle name, symbolHandle sig, TRAPS) { + const char* type, Symbol* name, Symbol* sig, TRAPS) { ResourceMark rm(THREAD); Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -1580,7 +1603,7 @@ cp->tag_at(name_index).is_utf8(), "Illegal constant pool index %u for method name in class file %s", name_index, CHECK_(nullHandle)); - symbolHandle name(THREAD, cp->symbol_at(name_index)); + Symbol* name = cp->symbol_at(name_index); verify_legal_method_name(name, CHECK_(nullHandle)); u2 signature_index = cfs->get_u2_fast(); @@ -1589,7 +1612,7 @@ cp->tag_at(signature_index).is_utf8(), "Illegal constant pool index %u for method signature in class file %s", signature_index, CHECK_(nullHandle)); - symbolHandle signature(THREAD, cp->symbol_at(signature_index)); + Symbol* signature = cp->symbol_at(signature_index); AccessFlags access_flags; if (name == vmSymbols::class_initializer_name()) { @@ -1660,7 +1683,7 @@ "Invalid method attribute name index %u in class file %s", method_attribute_name_index, CHECK_(nullHandle)); - symbolOop method_attribute_name = cp->symbol_at(method_attribute_name_index); + Symbol* method_attribute_name = cp->symbol_at(method_attribute_name_index); if (method_attribute_name == vmSymbols::tag_code()) { // Parse Code attribute if (_need_verify) { @@ -2057,16 +2080,16 @@ 0, CHECK_(nullHandle)); - if (name() == vmSymbols::finalize_method_name() && - signature() == vmSymbols::void_method_signature()) { + if (name == vmSymbols::finalize_method_name() && + signature == vmSymbols::void_method_signature()) { if (m->is_empty_method()) { _has_empty_finalizer = true; } else { _has_finalizer = true; } } - if (name() == vmSymbols::object_initializer_name() && - signature() == vmSymbols::void_method_signature() && + if (name == vmSymbols::object_initializer_name() && + signature == vmSymbols::void_method_signature() && m->is_vanilla_constructor()) { _has_vanilla_constructor = true; } @@ -2193,7 +2216,7 @@ } } // Sort method array by ascending method name (for faster lookups & vtable construction) - // Note that the ordering is not alphabetical, see symbolOopDesc::fast_compare + // Note that the ordering is not alphabetical, see Symbol::fast_compare methodOopDesc::sort_methods(methods(), methods_annotations(), methods_parameter_annotations(), @@ -2242,9 +2265,10 @@ if (JvmtiExport::can_get_source_debug_extension()) { // Optimistically assume that only 1 byte UTF format is used // (common case) - symbolOop sde_symbol = oopFactory::new_symbol((char*)sde_buffer, - length, CHECK); + TempNewSymbol sde_symbol = SymbolTable::new_symbol((const char*)sde_buffer, length, CHECK); k->set_source_debug_extension(sde_symbol); + // Note that set_source_debug_extension() increments the reference count + // for its copy of the Symbol*, so use a TempNewSymbol here. } // Got utf8 string, set stream position forward cfs->skip_u1(length, CHECK); @@ -2440,7 +2464,7 @@ cp->tag_at(attribute_name_index).is_utf8(), "Attribute name has bad constant pool index %u in class file %s", attribute_name_index, CHECK); - symbolOop tag = cp->symbol_at(attribute_name_index); + Symbol* tag = cp->symbol_at(attribute_name_index); if (tag == vmSymbols::tag_source_file()) { // Check for SourceFile tag if (_need_verify) { @@ -2607,7 +2631,7 @@ case T_OBJECT: { #ifdef ASSERT - symbolOop sym = oopFactory::new_symbol("Ljava/lang/String;", CHECK); + TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK); assert(fd->signature() == sym, "just checking"); #endif oop string = fd->string_initial_value(CHECK); @@ -2650,8 +2674,8 @@ (*fields_ptr)()->ushort_at(i + instanceKlass::name_index_offset); int sig_index = (*fields_ptr)()->ushort_at(i + instanceKlass::signature_index_offset); - symbolOop f_name = cp->symbol_at(name_index); - symbolOop f_sig = cp->symbol_at(sig_index); + Symbol* f_name = cp->symbol_at(name_index); + Symbol* f_sig = cp->symbol_at(sig_index); if (f_sig == vmSymbols::reference_signature() && reference_index == 0) { // Save the index for reference signature for later use. // The fake discovered field does not entries in the @@ -2805,9 +2829,8 @@ int name_index = fields->ushort_at(i + instanceKlass::name_index_offset); int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset); int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset); - symbolOop f_name = cp->symbol_at(name_index); - symbolOop f_sig = cp->symbol_at(sig_index); - + Symbol* f_name = cp->symbol_at(name_index); + Symbol* f_sig = cp->symbol_at(sig_index); if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) { if (f_sig == vmSymbols::machine_word_signature()) { // If the signature of vmentry is already changed, we're done. @@ -2841,12 +2864,12 @@ } -instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, +instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, Handle class_loader, Handle protection_domain, KlassHandle host_klass, GrowableArray* cp_patches, - symbolHandle& parsed_name, + TempNewSymbol& parsed_name, bool verify, TRAPS) { // So that JVMTI can cache class file in the state before retransformable agents @@ -2899,7 +2922,7 @@ cfs->set_verify(_need_verify); // Save the class file name for easier error message printing. - _class_name = name.not_null()? name : vmSymbolHandles::unknown_class_name(); + _class_name = (name != NULL) ? name : vmSymbols::unknown_class_name(); cfs->guarantee_more(8, CHECK_(nullHandle)); // magic, major, minor // Magic value @@ -2914,10 +2937,10 @@ // Check version numbers - we check this even with verifier off if (!is_supported_version(major_version, minor_version)) { - if (name.is_null()) { + if (name == NULL) { Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_UnsupportedClassVersionError(), + vmSymbols::java_lang_UnsupportedClassVersionError(), "Unsupported major.minor version %u.%u", major_version, minor_version); @@ -2925,7 +2948,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_UnsupportedClassVersionError(), + vmSymbols::java_lang_UnsupportedClassVersionError(), "%s : Unsupported major.minor version %u.%u", name->as_C_string(), major_version, @@ -2944,6 +2967,8 @@ // Constant pool constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle)); + ConstantPoolCleaner error_handler(cp); // set constant pool to be cleaned up. + int cp_size = cp->length(); cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len @@ -2968,12 +2993,15 @@ "Invalid this class index %u in constant pool in class file %s", this_class_index, CHECK_(nullHandle)); - symbolHandle class_name (THREAD, cp->unresolved_klass_at(this_class_index)); - assert(class_name.not_null(), "class_name can't be null"); + Symbol* class_name = cp->unresolved_klass_at(this_class_index); + assert(class_name != NULL, "class_name can't be null"); // It's important to set parsed_name *before* resolving the super class. // (it's used for cleanup by the caller if parsing fails) parsed_name = class_name; + // parsed_name is returned and can be used if there's an error, so add to + // its reference count. Caller will decrement the refcount. + parsed_name->increment_refcount(); // Update _class_name which could be null previously to be class_name _class_name = class_name; @@ -2993,11 +3021,11 @@ { HandleMark hm(THREAD); // Checks if name in class file matches requested name - if (name.not_null() && class_name() != name()) { + if (name != NULL && class_name != name) { ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_NoClassDefFoundError(), + vmSymbols::java_lang_NoClassDefFoundError(), "%s (wrong name: %s)", name->as_C_string(), class_name->as_C_string() @@ -3006,14 +3034,14 @@ } if (TraceClassLoadingPreorder) { - tty->print("[Loading %s", name()->as_klass_external_name()); + tty->print("[Loading %s", name->as_klass_external_name()); if (cfs->source() != NULL) tty->print(" from %s", cfs->source()); tty->print_cr("]"); } u2 super_class_index = cfs->get_u2_fast(); if (super_class_index == 0) { - check_property(class_name() == vmSymbols::java_lang_Object(), + check_property(class_name == vmSymbols::java_lang_Object(), "Invalid superclass index %u in class file %s", super_class_index, CHECK_(nullHandle)); @@ -3075,11 +3103,11 @@ // We check super class after class file is parsed and format is checked if (super_class_index > 0 && super_klass.is_null()) { - symbolHandle sk (THREAD, cp->klass_name_at(super_class_index)); + Symbol* sk = cp->klass_name_at(super_class_index); if (access_flags.is_interface()) { // Before attempting to resolve the superclass, check for class format // errors not checked yet. - guarantee_property(sk() == vmSymbols::java_lang_Object(), + guarantee_property(sk == vmSymbols::java_lang_Object(), "Interfaces must have java.lang.Object as superclass in class file %s", CHECK_(nullHandle)); } @@ -3100,7 +3128,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_IncompatibleClassChangeError(), + vmSymbols::java_lang_IncompatibleClassChangeError(), "class %s has interface %s as super class", class_name->as_klass_external_name(), super_klass->external_name() @@ -3193,18 +3221,18 @@ next_nonstatic_field_offset = first_nonstatic_field_offset; // Add fake fields for java.lang.Class instances (also see below) - if (class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) { + if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) { java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle)); } // adjust the vmentry field declaration in java.dyn.MethodHandle - if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) { + if (EnableMethodHandles && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) { java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle)); } // Add a fake "discovered" field if it is not present // for compatibility with earlier jdk's. - if (class_name() == vmSymbols::java_lang_ref_Reference() + if (class_name == vmSymbols::java_lang_ref_Reference() && class_loader.is_null()) { java_lang_ref_Reference_fix_pre(&fields, cp, &fac, CHECK_(nullHandle)); } @@ -3236,7 +3264,7 @@ // Add fake fields for java.lang.Class instances (also see above). // FieldsAllocationStyle and CompactFields values will be reset to default. - if(class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) { + if(class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) { java_lang_Class_fix_post(&next_nonstatic_field_offset); nonstatic_oop_offsets[0] = first_nonstatic_field_offset; const uint fake_oop_count = (next_nonstatic_field_offset - @@ -3279,22 +3307,22 @@ // (see in JavaClasses::compute_hard_coded_offsets()). // Use default fields allocation order for them. if( (allocation_style != 0 || compact_fields ) && class_loader.is_null() && - (class_name() == vmSymbols::java_lang_AssertionStatusDirectives() || - class_name() == vmSymbols::java_lang_Class() || - class_name() == vmSymbols::java_lang_ClassLoader() || - class_name() == vmSymbols::java_lang_ref_Reference() || - class_name() == vmSymbols::java_lang_ref_SoftReference() || - class_name() == vmSymbols::java_lang_StackTraceElement() || - class_name() == vmSymbols::java_lang_String() || - class_name() == vmSymbols::java_lang_Throwable() || - class_name() == vmSymbols::java_lang_Boolean() || - class_name() == vmSymbols::java_lang_Character() || - class_name() == vmSymbols::java_lang_Float() || - class_name() == vmSymbols::java_lang_Double() || - class_name() == vmSymbols::java_lang_Byte() || - class_name() == vmSymbols::java_lang_Short() || - class_name() == vmSymbols::java_lang_Integer() || - class_name() == vmSymbols::java_lang_Long())) { + (class_name == vmSymbols::java_lang_AssertionStatusDirectives() || + class_name == vmSymbols::java_lang_Class() || + class_name == vmSymbols::java_lang_ClassLoader() || + class_name == vmSymbols::java_lang_ref_Reference() || + class_name == vmSymbols::java_lang_ref_SoftReference() || + class_name == vmSymbols::java_lang_StackTraceElement() || + class_name == vmSymbols::java_lang_String() || + class_name == vmSymbols::java_lang_Throwable() || + class_name == vmSymbols::java_lang_Boolean() || + class_name == vmSymbols::java_lang_Character() || + class_name == vmSymbols::java_lang_Float() || + class_name == vmSymbols::java_lang_Double() || + class_name == vmSymbols::java_lang_Byte() || + class_name == vmSymbols::java_lang_Short() || + class_name == vmSymbols::java_lang_Integer() || + class_name == vmSymbols::java_lang_Long())) { allocation_style = 0; // Allocate oops first compact_fields = false; // Don't compact fields } @@ -3543,6 +3571,7 @@ this_klass->set_has_nonstatic_fields(has_nonstatic_fields); this_klass->set_static_oop_field_size(fac.static_oop_count); cp->set_pool_holder(this_klass()); + error_handler.set_in_error(false); // turn off error handler for cp this_klass->set_constants(cp()); this_klass->set_local_interfaces(local_interfaces()); this_klass->set_fields(fields()); @@ -3935,7 +3964,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_IllegalAccessError(), + vmSymbols::java_lang_IllegalAccessError(), "class %s cannot access its superclass %s", this_klass->external_name(), instanceKlass::cast(super)->external_name() @@ -3955,7 +3984,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_IllegalAccessError(), + vmSymbols::java_lang_IllegalAccessError(), "class %s cannot access its superinterface %s", this_klass->external_name(), instanceKlass::cast(k)->external_name() @@ -3979,8 +4008,8 @@ (!m->is_static()) && (m->name() != vmSymbols::object_initializer_name())) { - symbolOop name = m->name(); - symbolOop signature = m->signature(); + Symbol* name = m->name(); + Symbol* signature = m->signature(); klassOop k = this_klass->super(); methodOop super_m = NULL; while (k != NULL) { @@ -4003,7 +4032,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_VerifyError(), + vmSymbols::java_lang_VerifyError(), "class %s overrides final method %s.%s", this_klass->external_name(), name->as_C_string(), @@ -4037,7 +4066,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_VerifyError(), + vmSymbols::java_lang_VerifyError(), "Illegal static method %s in interface %s", m->name()->as_C_string(), this_klass->external_name() @@ -4067,7 +4096,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_ClassFormatError(), + vmSymbols::java_lang_ClassFormatError(), "Illegal class modifiers in class %s: 0x%X", _class_name->as_C_string(), flags ); @@ -4127,7 +4156,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_ClassFormatError(), + vmSymbols::java_lang_ClassFormatError(), "Illegal field modifiers in class %s: 0x%X", _class_name->as_C_string(), flags); return; @@ -4135,7 +4164,7 @@ } void ClassFileParser::verify_legal_method_modifiers( - jint flags, bool is_interface, symbolHandle name, TRAPS) { + jint flags, bool is_interface, Symbol* name, TRAPS) { if (!_need_verify) { return; } const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; @@ -4180,7 +4209,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_ClassFormatError(), + vmSymbols::java_lang_ClassFormatError(), "Method %s in class %s has illegal modifiers: 0x%X", name->as_C_string(), _class_name->as_C_string(), flags); return; @@ -4251,7 +4280,7 @@ } // Checks if name is a legal class name. -void ClassFileParser::verify_legal_class_name(symbolHandle name, TRAPS) { +void ClassFileParser::verify_legal_class_name(Symbol* name, TRAPS) { if (!_need_verify || _relax_verify) { return; } char buf[fixed_buffer_size]; @@ -4281,7 +4310,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_ClassFormatError(), + vmSymbols::java_lang_ClassFormatError(), "Illegal class name \"%s\" in class file %s", bytes, _class_name->as_C_string() ); @@ -4290,7 +4319,7 @@ } // Checks if name is a legal field name. -void ClassFileParser::verify_legal_field_name(symbolHandle name, TRAPS) { +void ClassFileParser::verify_legal_field_name(Symbol* name, TRAPS) { if (!_need_verify || _relax_verify) { return; } char buf[fixed_buffer_size]; @@ -4314,7 +4343,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_ClassFormatError(), + vmSymbols::java_lang_ClassFormatError(), "Illegal field name \"%s\" in class %s", bytes, _class_name->as_C_string() ); @@ -4323,10 +4352,10 @@ } // Checks if name is a legal method name. -void ClassFileParser::verify_legal_method_name(symbolHandle name, TRAPS) { +void ClassFileParser::verify_legal_method_name(Symbol* name, TRAPS) { if (!_need_verify || _relax_verify) { return; } - assert(!name.is_null(), "method name is null"); + assert(name != NULL, "method name is null"); char buf[fixed_buffer_size]; char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); unsigned int length = name->utf8_length(); @@ -4351,7 +4380,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_ClassFormatError(), + vmSymbols::java_lang_ClassFormatError(), "Illegal method name \"%s\" in class %s", bytes, _class_name->as_C_string() ); @@ -4361,7 +4390,7 @@ // Checks if signature is a legal field signature. -void ClassFileParser::verify_legal_field_signature(symbolHandle name, symbolHandle signature, TRAPS) { +void ClassFileParser::verify_legal_field_signature(Symbol* name, Symbol* signature, TRAPS) { if (!_need_verify) { return; } char buf[fixed_buffer_size]; @@ -4376,7 +4405,7 @@ // Checks if signature is a legal method signature. // Returns number of parameters -int ClassFileParser::verify_legal_method_signature(symbolHandle name, symbolHandle signature, TRAPS) { +int ClassFileParser::verify_legal_method_signature(Symbol* name, Symbol* signature, TRAPS) { if (!_need_verify) { // make sure caller's args_size will be less than 0 even for non-static // method so it will be recomputed in compute_size_of_parameters(). @@ -4508,8 +4537,8 @@ // public static boolean isJavaIdentifierStart(char ch); JavaCalls::call_static(&result, klass, - vmSymbolHandles::isJavaIdentifierStart_name(), - vmSymbolHandles::int_bool_signature(), + vmSymbols::isJavaIdentifierStart_name(), + vmSymbols::int_bool_signature(), &args, THREAD); @@ -4525,8 +4554,8 @@ // public static boolean isJavaIdentifierPart(char ch); JavaCalls::call_static(&result, klass, - vmSymbolHandles::isJavaIdentifierPart_name(), - vmSymbolHandles::int_bool_signature(), + vmSymbols::isJavaIdentifierPart_name(), + vmSymbols::int_bool_signature(), &args, THREAD); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/classFileParser.hpp --- a/src/share/vm/classfile/classFileParser.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/classFileParser.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -32,6 +32,7 @@ #include "runtime/handles.inline.hpp" #include "utilities/accessFlags.hpp" +class TempNewSymbol; // Parser for for .class files // // The bytes describing the class file structure is read from a Stream object @@ -42,7 +43,7 @@ bool _relax_verify; u2 _major_version; u2 _minor_version; - symbolHandle _class_name; + Symbol* _class_name; KlassHandle _host_klass; GrowableArray* _cp_patches; // overrides for CP entries @@ -73,7 +74,7 @@ int length, Handle class_loader, Handle protection_domain, - symbolHandle class_name, + Symbol* class_name, TRAPS); // Field parsing @@ -209,21 +210,21 @@ } void throwIllegalSignature( - const char* type, symbolHandle name, symbolHandle sig, TRAPS); + const char* type, Symbol* name, Symbol* sig, TRAPS); bool is_supported_version(u2 major, u2 minor); bool has_illegal_visibility(jint flags); void verify_constantvalue(int constantvalue_index, int signature_index, constantPoolHandle cp, TRAPS); void verify_legal_utf8(const unsigned char* buffer, int length, TRAPS); - void verify_legal_class_name(symbolHandle name, TRAPS); - void verify_legal_field_name(symbolHandle name, TRAPS); - void verify_legal_method_name(symbolHandle name, TRAPS); - void verify_legal_field_signature(symbolHandle fieldname, symbolHandle signature, TRAPS); - int verify_legal_method_signature(symbolHandle methodname, symbolHandle signature, TRAPS); + void verify_legal_class_name(Symbol* name, TRAPS); + void verify_legal_field_name(Symbol* name, TRAPS); + void verify_legal_method_name(Symbol* name, TRAPS); + void verify_legal_field_signature(Symbol* fieldname, Symbol* signature, TRAPS); + int verify_legal_method_signature(Symbol* methodname, Symbol* signature, TRAPS); void verify_legal_class_modifiers(jint flags, TRAPS); void verify_legal_field_modifiers(jint flags, bool is_interface, TRAPS); - void verify_legal_method_modifiers(jint flags, bool is_interface, symbolHandle name, TRAPS); + void verify_legal_method_modifiers(jint flags, bool is_interface, Symbol* name, TRAPS); bool verify_unqualified_name(char* name, unsigned int length, int type); char* skip_over_field_name(char* name, bool slash_ok, unsigned int length); char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS); @@ -272,21 +273,21 @@ // // "parsed_name" is updated by this method, and is the name found // while parsing the stream. - instanceKlassHandle parseClassFile(symbolHandle name, + instanceKlassHandle parseClassFile(Symbol* name, Handle class_loader, Handle protection_domain, - symbolHandle& parsed_name, + TempNewSymbol& parsed_name, bool verify, TRAPS) { KlassHandle no_host_klass; return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD); } - instanceKlassHandle parseClassFile(symbolHandle name, + instanceKlassHandle parseClassFile(Symbol* name, Handle class_loader, Handle protection_domain, KlassHandle host_klass, GrowableArray* cp_patches, - symbolHandle& parsed_name, + TempNewSymbol& parsed_name, bool verify, TRAPS); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/classLoader.cpp --- a/src/share/vm/classfile/classLoader.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/classLoader.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -41,7 +41,7 @@ #include "oops/instanceKlass.hpp" #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/compilationPolicy.hpp" @@ -752,11 +752,7 @@ } } if (*top + n + sizeof(intptr_t) >= end) { - warning("\nThe shared miscellaneous data space is not large " - "enough to \npreload requested classes. Use " - "-XX:SharedMiscDataSize= to increase \nthe initial " - "size of the miscellaneous data space.\n"); - exit(2); + report_out_of_shared_space(SharedMiscData); } // Copy the table data (the strings) to the shared space. @@ -875,9 +871,9 @@ } -instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) { +instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) { ResourceMark rm(THREAD); - EventMark m("loading class " INTPTR_FORMAT, (address)h_name()); + EventMark m("loading class " INTPTR_FORMAT, (address)h_name); ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion); stringStream st; @@ -912,7 +908,7 @@ ClassFileParser parser(stream); Handle class_loader; Handle protection_domain; - symbolHandle parsed_name; + TempNewSymbol parsed_name = NULL; instanceKlassHandle result = parser.parseClassFile(h_name, class_loader, protection_domain, @@ -1308,7 +1304,7 @@ if (_compile_the_world_counter > CompileTheWorldStopAt) return; // Construct name without extension - symbolHandle sym = oopFactory::new_symbol_handle(buffer, CHECK); + TempNewSymbol sym = SymbolTable::new_symbol(buffer, CHECK); // Use loader to load and initialize class klassOop ik = SystemDictionary::resolve_or_null(sym, loader, Handle(), THREAD); instanceKlassHandle k (THREAD, ik); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/classLoader.hpp --- a/src/share/vm/classfile/classLoader.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/classLoader.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -280,7 +280,7 @@ } // Load individual .class file - static instanceKlassHandle load_classfile(symbolHandle h_name, TRAPS); + static instanceKlassHandle load_classfile(Symbol* h_name, TRAPS); // If the specified package has been loaded by the system, then returns // the name of the directory or ZIP file that the package was loaded from. diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/dictionary.cpp --- a/src/share/vm/classfile/dictionary.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/dictionary.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -36,7 +36,7 @@ Dictionary::Dictionary(int table_size) - : TwoOopHashtable(table_size, sizeof(DictionaryEntry)) { + : TwoOopHashtable(table_size, sizeof(DictionaryEntry)) { _current_class_index = 0; _current_class_entry = NULL; }; @@ -45,7 +45,7 @@ Dictionary::Dictionary(int table_size, HashtableBucket* t, int number_of_entries) - : TwoOopHashtable(table_size, sizeof(DictionaryEntry), t, number_of_entries) { + : TwoOopHashtable(table_size, sizeof(DictionaryEntry), t, number_of_entries) { _current_class_index = 0; _current_class_entry = NULL; }; @@ -54,7 +54,7 @@ DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass, oop loader) { DictionaryEntry* entry; - entry = (DictionaryEntry*)Hashtable::new_entry(hash, klass); + entry = (DictionaryEntry*)Hashtable::new_entry(hash, klass); entry->set_loader(loader); entry->set_pd_set(NULL); return entry; @@ -62,7 +62,7 @@ DictionaryEntry* Dictionary::new_entry() { - DictionaryEntry* entry = (DictionaryEntry*)Hashtable::new_entry(0L, NULL); + DictionaryEntry* entry = (DictionaryEntry*)Hashtable::new_entry(0L, NULL); entry->set_loader(NULL); entry->set_pd_set(NULL); return entry; @@ -76,7 +76,7 @@ entry->set_pd_set(to_delete->next()); delete to_delete; } - Hashtable::free_entry(entry); + Hashtable::free_entry(entry); } @@ -298,7 +298,7 @@ for (DictionaryEntry *probe = bucket(index); probe != NULL; probe = probe->next()) { - oop e = probe->klass(); + klassOop e = probe->klass(); oop class_loader = probe->loader(); if (is_strongly_reachable(class_loader, e)) { blk->do_oop((oop*)probe->klass_addr()); @@ -421,11 +421,11 @@ // also cast to volatile; we do this to ensure store order is maintained // by the compilers. -void Dictionary::add_klass(symbolHandle class_name, Handle class_loader, +void Dictionary::add_klass(Symbol* class_name, Handle class_loader, KlassHandle obj) { assert_locked_or_safepoint(SystemDictionary_lock); assert(obj() != NULL, "adding NULL obj"); - assert(Klass::cast(obj())->name() == class_name(), "sanity check on name"); + assert(Klass::cast(obj())->name() == class_name, "sanity check on name"); unsigned int hash = compute_hash(class_name, class_loader); int index = hash_to_index(hash); @@ -444,15 +444,14 @@ // Callers should be aware that an entry could be added just after // _buckets[index] is read here, so the caller will not see the new entry. DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash, - symbolHandle class_name, + Symbol* class_name, Handle class_loader) { - symbolOop name_ = class_name(); - oop loader_ = class_loader(); + oop loader = class_loader(); debug_only(_lookup_count++); for (DictionaryEntry* entry = bucket(index); entry != NULL; entry = entry->next()) { - if (entry->hash() == hash && entry->equals(name_, loader_)) { + if (entry->hash() == hash && entry->equals(class_name, loader)) { return entry; } debug_only(_lookup_length++); @@ -461,7 +460,7 @@ } -klassOop Dictionary::find(int index, unsigned int hash, symbolHandle name, +klassOop Dictionary::find(int index, unsigned int hash, Symbol* name, Handle loader, Handle protection_domain, TRAPS) { DictionaryEntry* entry = get_entry(index, hash, name, loader); if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { @@ -473,7 +472,7 @@ klassOop Dictionary::find_class(int index, unsigned int hash, - symbolHandle name, Handle loader) { + Symbol* name, Handle loader) { assert_locked_or_safepoint(SystemDictionary_lock); assert (index == index_for(name, loader), "incorrect index?"); @@ -486,7 +485,7 @@ // that table is static. klassOop Dictionary::find_shared_class(int index, unsigned int hash, - symbolHandle name) { + Symbol* name) { assert (index == index_for(name, Handle()), "incorrect index?"); DictionaryEntry* entry = get_entry(index, hash, name, Handle()); @@ -498,7 +497,7 @@ instanceKlassHandle klass, Handle loader, Handle protection_domain, TRAPS) { - symbolHandle klass_name(THREAD, klass->name()); + Symbol* klass_name = klass->name(); DictionaryEntry* entry = get_entry(index, hash, klass_name, loader); assert(entry != NULL,"entry must be present, we just created it"); @@ -513,7 +512,7 @@ bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, - symbolHandle name, + Symbol* name, Handle loader, Handle protection_domain) { DictionaryEntry* entry = get_entry(index, hash, name, loader); @@ -545,7 +544,7 @@ DictionaryEntry* p = master_list; master_list = master_list->next(); p->set_next(NULL); - symbolHandle class_name (thread, instanceKlass::cast((klassOop)(p->klass()))->name()); + Symbol* class_name = instanceKlass::cast((klassOop)(p->klass()))->name(); unsigned int hash = compute_hash(class_name, Handle(thread, p->loader())); int index = hash_to_index(hash); p->set_hash(hash); @@ -555,22 +554,22 @@ } SymbolPropertyTable::SymbolPropertyTable(int table_size) - : Hashtable(table_size, sizeof(SymbolPropertyEntry)) + : Hashtable(table_size, sizeof(SymbolPropertyEntry)) { } SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries) - : Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) + : Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) { } SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash, - symbolHandle sym, + Symbol* sym, intptr_t sym_mode) { assert(index == index_for(sym, sym_mode), "incorrect index?"); for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { - if (p->hash() == hash && p->symbol() == sym() && p->symbol_mode() == sym_mode) { + if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) { return p; } } @@ -579,13 +578,13 @@ SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash, - symbolHandle sym, intptr_t sym_mode) { + Symbol* sym, intptr_t sym_mode) { assert_locked_or_safepoint(SystemDictionary_lock); assert(index == index_for(sym, sym_mode), "incorrect index?"); assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry"); - SymbolPropertyEntry* p = new_entry(hash, sym(), sym_mode); - Hashtable::add_entry(index, p); + SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode); + Hashtable::add_entry(index, p); return p; } @@ -593,7 +592,6 @@ void SymbolPropertyTable::oops_do(OopClosure* f) { for (int index = 0; index < table_size(); index++) { for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { - f->do_oop((oop*) p->symbol_addr()); if (p->property_oop() != NULL) { f->do_oop(p->property_oop_addr()); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/dictionary.hpp --- a/src/share/vm/classfile/dictionary.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/dictionary.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -36,7 +36,7 @@ // The data structure for the system dictionary (and the shared system // dictionary). -class Dictionary : public TwoOopHashtable { +class Dictionary : public TwoOopHashtable { friend class VMStructs; private: // current iteration index. @@ -45,19 +45,19 @@ static DictionaryEntry* _current_class_entry; DictionaryEntry* get_entry(int index, unsigned int hash, - symbolHandle name, Handle loader); + Symbol* name, Handle loader); DictionaryEntry* bucket(int i) { - return (DictionaryEntry*)Hashtable::bucket(i); + return (DictionaryEntry*)Hashtable::bucket(i); } // The following method is not MT-safe and must be done under lock. DictionaryEntry** bucket_addr(int i) { - return (DictionaryEntry**)Hashtable::bucket_addr(i); + return (DictionaryEntry**)Hashtable::bucket_addr(i); } void add_entry(int index, DictionaryEntry* new_entry) { - Hashtable::add_entry(index, (HashtableEntry*)new_entry); + Hashtable::add_entry(index, (HashtableEntry*)new_entry); } @@ -71,12 +71,12 @@ void free_entry(DictionaryEntry* entry); - void add_klass(symbolHandle class_name, Handle class_loader,KlassHandle obj); + void add_klass(Symbol* class_name, Handle class_loader,KlassHandle obj); klassOop find_class(int index, unsigned int hash, - symbolHandle name, Handle loader); + Symbol* name, Handle loader); - klassOop find_shared_class(int index, unsigned int hash, symbolHandle name); + klassOop find_shared_class(int index, unsigned int hash, Symbol* name); // Compiler support klassOop try_get_next_class(); @@ -95,7 +95,7 @@ // Classes loaded by the bootstrap loader are always strongly reachable. // If we're not doing class unloading, all classes are strongly reachable. - static bool is_strongly_reachable(oop class_loader, oop klass) { + static bool is_strongly_reachable(oop class_loader, klassOop klass) { assert (klass != NULL, "should have non-null klass"); return (class_loader == NULL || !ClassUnloading); } @@ -105,10 +105,10 @@ bool do_unloading(BoolObjectClosure* is_alive); // Protection domains - klassOop find(int index, unsigned int hash, symbolHandle name, + klassOop find(int index, unsigned int hash, Symbol* name, Handle loader, Handle protection_domain, TRAPS); bool is_valid_protection_domain(int index, unsigned int hash, - symbolHandle name, Handle class_loader, + Symbol* name, Handle class_loader, Handle protection_domain); void add_protection_domain(int index, unsigned int hash, instanceKlassHandle klass, Handle loader, @@ -147,7 +147,7 @@ // An entry in the system dictionary, this describes a class as // { klassOop, loader, protection_domain }. -class DictionaryEntry : public HashtableEntry { +class DictionaryEntry : public HashtableEntry { friend class VMStructs; private: // Contains the set of approved protection domains that can access @@ -166,11 +166,11 @@ klassOop* klass_addr() { return (klassOop*)literal_addr(); } DictionaryEntry* next() const { - return (DictionaryEntry*)HashtableEntry::next(); + return (DictionaryEntry*)HashtableEntry::next(); } DictionaryEntry** next_addr() { - return (DictionaryEntry**)HashtableEntry::next_addr(); + return (DictionaryEntry**)HashtableEntry::next_addr(); } oop loader() const { return _loader; } @@ -209,7 +209,7 @@ } } - bool equals(symbolOop class_name, oop class_loader) const { + bool equals(Symbol* class_name, oop class_loader) const { klassOop klass = (klassOop)literal(); return (instanceKlass::cast(klass)->name() == class_name && _loader == class_loader); @@ -226,9 +226,9 @@ } }; -// Entry in a SymbolPropertyTable, mapping a single symbolOop +// Entry in a SymbolPropertyTable, mapping a single Symbol* // to a managed and an unmanaged pointer. -class SymbolPropertyEntry : public HashtableEntry { +class SymbolPropertyEntry : public HashtableEntry { friend class VMStructs; private: intptr_t _symbol_mode; // secondary key @@ -236,7 +236,7 @@ address _property_data; public: - symbolOop symbol() const { return (symbolOop) literal(); } + Symbol* symbol() const { return literal(); } intptr_t symbol_mode() const { return _symbol_mode; } void set_symbol_mode(intptr_t m) { _symbol_mode = m; } @@ -248,14 +248,13 @@ void set_property_data(address p) { _property_data = p; } SymbolPropertyEntry* next() const { - return (SymbolPropertyEntry*)HashtableEntry::next(); + return (SymbolPropertyEntry*)HashtableEntry::next(); } SymbolPropertyEntry** next_addr() { - return (SymbolPropertyEntry**)HashtableEntry::next_addr(); + return (SymbolPropertyEntry**)HashtableEntry::next_addr(); } - oop* symbol_addr() { return literal_addr(); } oop* property_oop_addr() { return &_property_oop; } void print_on(outputStream* st) const { @@ -279,16 +278,16 @@ // A system-internal mapping of symbols to pointers, both managed // and unmanaged. Used to record the auto-generation of each method // MethodHandle.invoke(S)T, for all signatures (S)T. -class SymbolPropertyTable : public Hashtable { +class SymbolPropertyTable : public Hashtable { friend class VMStructs; private: SymbolPropertyEntry* bucket(int i) { - return (SymbolPropertyEntry*) Hashtable::bucket(i); + return (SymbolPropertyEntry*) Hashtable::bucket(i); } // The following method is not MT-safe and must be done under lock. SymbolPropertyEntry** bucket_addr(int i) { - return (SymbolPropertyEntry**) Hashtable::bucket_addr(i); + return (SymbolPropertyEntry**) Hashtable::bucket_addr(i); } void add_entry(int index, SymbolPropertyEntry* new_entry) { @@ -298,8 +297,10 @@ ShouldNotReachHere(); } - SymbolPropertyEntry* new_entry(unsigned int hash, symbolOop symbol, intptr_t symbol_mode) { - SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable::new_entry(hash, symbol); + SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) { + SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable::new_entry(hash, symbol); + // Hashtable with Symbol* literal must increment and decrement refcount. + symbol->increment_refcount(); entry->set_symbol_mode(symbol_mode); entry->set_property_oop(NULL); entry->set_property_data(NULL); @@ -311,23 +312,25 @@ SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries); void free_entry(SymbolPropertyEntry* entry) { - Hashtable::free_entry(entry); + // decrement Symbol refcount here because hashtable doesn't. + entry->literal()->decrement_refcount(); + Hashtable::free_entry(entry); } - unsigned int compute_hash(symbolHandle sym, intptr_t symbol_mode) { + unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) { // Use the regular identity_hash. - return Hashtable::compute_hash(sym) ^ symbol_mode; + return Hashtable::compute_hash(sym) ^ symbol_mode; } - int index_for(symbolHandle name, intptr_t symbol_mode) { + int index_for(Symbol* name, intptr_t symbol_mode) { return hash_to_index(compute_hash(name, symbol_mode)); } // need not be locked; no state change - SymbolPropertyEntry* find_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode); + SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode); // must be done under SystemDictionary_lock - SymbolPropertyEntry* add_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode); + SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode); // GC support void oops_do(OopClosure* f); @@ -343,6 +346,4 @@ #endif void verify(); }; - - #endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/javaAssertions.cpp --- a/src/share/vm/classfile/javaAssertions.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/javaAssertions.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -93,7 +93,7 @@ } oop JavaAssertions::createAssertionStatusDirectives(TRAPS) { - symbolHandle asd_sym = vmSymbolHandles::java_lang_AssertionStatusDirectives(); + Symbol* asd_sym = vmSymbols::java_lang_AssertionStatusDirectives(); klassOop k = SystemDictionary::resolve_or_fail(asd_sym, true, CHECK_NULL); instanceKlassHandle asd_klass (THREAD, k); asd_klass->initialize(CHECK_NULL); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/javaClasses.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -36,7 +36,7 @@ #include "oops/klass.hpp" #include "oops/klassOop.hpp" #include "oops/methodOop.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "oops/typeArrayOop.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" @@ -57,7 +57,7 @@ #endif static bool find_field(instanceKlass* ik, - symbolOop name_symbol, symbolOop signature_symbol, + Symbol* name_symbol, Symbol* signature_symbol, fieldDescriptor* fd, bool allow_super = false) { if (allow_super) @@ -69,7 +69,7 @@ // Helpful routine for computing field offsets at run time rather than hardcoding them static void compute_offset(int &dest_offset, - klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol, + klassOop klass_oop, Symbol* name_symbol, Symbol* signature_symbol, bool allow_super = false) { fieldDescriptor fd; instanceKlass* ik = instanceKlass::cast(klass_oop); @@ -84,7 +84,7 @@ // Same as above but for "optional" offsets that might not be present in certain JDK versions static void compute_optional_offset(int& dest_offset, - klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol, + klassOop klass_oop, Symbol* name_symbol, Symbol* signature_symbol, bool allow_super = false) { fieldDescriptor fd; instanceKlass* ik = instanceKlass::cast(klass_oop); @@ -164,7 +164,7 @@ return h_obj(); } -Handle java_lang_String::create_from_symbol(symbolHandle symbol, TRAPS) { +Handle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) { int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length()); Handle h_obj = basic_create(length, false, CHECK_NH); if (length > 0) { @@ -278,17 +278,17 @@ return result; } -symbolHandle java_lang_String::as_symbol(Handle java_string, TRAPS) { +Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) { oop obj = java_string(); typeArrayOop value = java_lang_String::value(obj); int offset = java_lang_String::offset(obj); int length = java_lang_String::length(obj); jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); - symbolOop sym = SymbolTable::lookup_unicode(base, length, THREAD); - return symbolHandle(THREAD, sym); + Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD); + return sym; } -symbolOop java_lang_String::as_symbol_or_null(oop java_string) { +Symbol* java_lang_String::as_symbol_or_null(oop java_string) { typeArrayOop value = java_lang_String::value(java_string); int offset = java_lang_String::offset(java_string); int length = java_lang_String::length(java_string); @@ -437,7 +437,7 @@ void java_lang_Class::print_signature(oop java_class, outputStream* st) { assert(java_lang_Class::is_instance(java_class), "must be a Class object"); - symbolOop name = NULL; + Symbol* name = NULL; bool is_instance = false; if (is_primitive(java_class)) { name = vmSymbols::type_signature(primitive_type(java_class)); @@ -455,25 +455,32 @@ if (is_instance) st->print(";"); } -symbolOop java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) { +Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) { assert(java_lang_Class::is_instance(java_class), "must be a Class object"); - symbolOop name = NULL; + Symbol* name; if (is_primitive(java_class)) { - return vmSymbols::type_signature(primitive_type(java_class)); + name = vmSymbols::type_signature(primitive_type(java_class)); + // Because this can create a new symbol, the caller has to decrement + // the refcount, so make adjustment here and below for symbols returned + // that are not created or incremented due to a successful lookup. + name->increment_refcount(); } else { klassOop k = as_klassOop(java_class); if (!Klass::cast(k)->oop_is_instance()) { - return Klass::cast(k)->name(); + name = Klass::cast(k)->name(); + name->increment_refcount(); } else { ResourceMark rm; const char* sigstr = Klass::cast(k)->signature_name(); int siglen = (int) strlen(sigstr); - if (!intern_if_not_found) - return SymbolTable::probe(sigstr, siglen); - else - return oopFactory::new_symbol(sigstr, siglen, THREAD); + if (!intern_if_not_found) { + name = SymbolTable::probe(sigstr, siglen); + } else { + name = SymbolTable::new_symbol(sigstr, siglen, THREAD); + } } } + return name; } @@ -1022,8 +1029,8 @@ JavaCalls::call_virtual(&result, stream, KlassHandle(THREAD, stream->klass()), - vmSymbolHandles::println_name(), - vmSymbolHandles::char_array_void_signature(), + vmSymbols::println_name(), + vmSymbols::char_array_void_signature(), arg, THREAD); } @@ -1077,8 +1084,8 @@ JavaCalls::call_virtual(&result, h_throwable, KlassHandle(THREAD, h_throwable->klass()), - vmSymbolHandles::getCause_name(), - vmSymbolHandles::void_throwable_signature(), + vmSymbols::getCause_name(), + vmSymbols::void_throwable_signature(), THREAD); // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. if (HAS_PENDING_EXCEPTION) { @@ -1516,7 +1523,7 @@ oop methodname = StringTable::intern(method->name(), CHECK_0); java_lang_StackTraceElement::set_methodName(element(), methodname); // Fill in source file name - symbolOop source = instanceKlass::cast(method->method_holder())->source_file_name(); + Symbol* source = instanceKlass::cast(method->method_holder())->source_file_name(); oop filename = StringTable::intern(source, CHECK_0); java_lang_StackTraceElement::set_fileName(element(), filename); // File in source line number @@ -1732,7 +1739,7 @@ Handle java_lang_reflect_Constructor::create(TRAPS) { assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); - symbolHandle name = vmSymbolHandles::java_lang_reflect_Constructor(); + Symbol* name = vmSymbols::java_lang_reflect_Constructor(); klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); instanceKlassHandle klass (THREAD, k); // Ensure it is initialized @@ -1854,7 +1861,7 @@ Handle java_lang_reflect_Field::create(TRAPS) { assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); - symbolHandle name = vmSymbolHandles::java_lang_reflect_Field(); + Symbol* name = vmSymbols::java_lang_reflect_Field(); klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); instanceKlassHandle klass (THREAD, k); // Ensure it is initialized @@ -2422,16 +2429,19 @@ java_lang_Class::print_signature(rtype(mt), st); } -symbolOop java_dyn_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) { +Symbol* java_dyn_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) { ResourceMark rm; stringStream buffer(128); print_signature(mt, &buffer); const char* sigstr = buffer.base(); int siglen = (int) buffer.size(); - if (!intern_if_not_found) - return SymbolTable::probe(sigstr, siglen); - else - return oopFactory::new_symbol(sigstr, siglen, THREAD); + Symbol *name; + if (!intern_if_not_found) { + name = SymbolTable::probe(sigstr, siglen); + } else { + name = SymbolTable::new_symbol(sigstr, siglen, THREAD); + } + return name; } oop java_dyn_MethodType::rtype(oop mt) { @@ -2908,13 +2918,12 @@ bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) { EXCEPTION_MARK; fieldDescriptor fd; - symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH); + TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH); klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); instanceKlassHandle h_klass (THREAD, k); - //instanceKlassHandle h_klass(klass); - symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); - symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); - if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) { + TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH); + TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH); + if (!h_klass->find_local_field(f_name, f_sig, &fd)) { tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name); return false; } @@ -2935,12 +2944,12 @@ bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) { EXCEPTION_MARK; fieldDescriptor fd; - symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH); + TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH); klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); instanceKlassHandle h_klass (THREAD, k); - symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); - symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); - if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) { + TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH); + TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH); + if (!h_klass->find_local_field(f_name, f_sig, &fd)) { tty->print_cr("Static field %s.%s not found", klass_name, field_name); return false; } @@ -2960,12 +2969,12 @@ bool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) { EXCEPTION_MARK; fieldDescriptor fd; - symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH); + TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH); klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); instanceKlassHandle h_klass (THREAD, k); - symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); - symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); - if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) { + TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH); + TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH); + if (!h_klass->find_local_field(f_name, f_sig, &fd)) { tty->print_cr("Static field %s.%s not found", klass_name, field_name); return false; } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/javaClasses.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -78,7 +78,7 @@ static oop create_oop_from_unicode(jchar* unicode, int len, TRAPS); static Handle create_from_str(const char* utf8_str, TRAPS); static oop create_oop_from_str(const char* utf8_str, TRAPS); - static Handle create_from_symbol(symbolHandle symbol, TRAPS); + static Handle create_from_symbol(Symbol* symbol, TRAPS); static Handle create_from_platform_dependent_str(const char* str, TRAPS); static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS); @@ -116,8 +116,8 @@ static Handle internalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '.', '/', THREAD); } // Conversion - static symbolHandle as_symbol(Handle java_string, TRAPS); - static symbolOop as_symbol_or_null(oop java_string); + static Symbol* as_symbol(Handle java_string, TRAPS); + static Symbol* as_symbol_or_null(oop java_string); // Testers static bool is_instance(oop obj) { @@ -167,7 +167,7 @@ (*reference_klass) = KlassHandle(refk_oop); return result; } - static symbolOop as_signature(oop java_class, bool intern_if_not_found, TRAPS); + static Symbol* as_signature(oop java_class, bool intern_if_not_found, TRAPS); static void print_signature(oop java_class, outputStream *st); // Testing static bool is_instance(oop obj) { @@ -1039,7 +1039,7 @@ static oop ptype(oop mt, int index); static int ptype_count(oop mt); - static symbolOop as_signature(oop mt, bool intern_if_not_found, TRAPS); + static Symbol* as_signature(oop mt, bool intern_if_not_found, TRAPS); static void print_signature(oop mt, outputStream* st); static bool is_instance(oop obj) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/loaderConstraints.cpp --- a/src/share/vm/classfile/loaderConstraints.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/loaderConstraints.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,28 +31,33 @@ #include "utilities/hashtable.inline.hpp" LoaderConstraintTable::LoaderConstraintTable(int nof_buckets) - : Hashtable(nof_buckets, sizeof(LoaderConstraintEntry)) {}; + : Hashtable(nof_buckets, sizeof(LoaderConstraintEntry)) {}; LoaderConstraintEntry* LoaderConstraintTable::new_entry( - unsigned int hash, symbolOop name, + unsigned int hash, Symbol* name, klassOop klass, int num_loaders, int max_loaders) { LoaderConstraintEntry* entry; - entry = (LoaderConstraintEntry*)Hashtable::new_entry(hash, klass); + entry = (LoaderConstraintEntry*)Hashtable::new_entry(hash, klass); entry->set_name(name); entry->set_num_loaders(num_loaders); entry->set_max_loaders(max_loaders); return entry; } +void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) { + // decrement name refcount before freeing + entry->name()->decrement_refcount(); + Hashtable::free_entry(entry); +} + void LoaderConstraintTable::oops_do(OopClosure* f) { for (int index = 0; index < table_size(); index++) { for (LoaderConstraintEntry* probe = bucket(index); probe != NULL; probe = probe->next()) { - f->do_oop((oop*)(probe->name_addr())); if (probe->klass() != NULL) { f->do_oop((oop*)probe->klass_addr()); } @@ -65,27 +70,13 @@ } } -// We must keep the symbolOop used in the name alive. We'll use the -// loaders to decide if a particular entry can be purged. -void LoaderConstraintTable::always_strong_classes_do(OopClosure* blk) { - // We must keep the symbolOop used in the name alive. - for (int cindex = 0; cindex < table_size(); cindex++) { - for (LoaderConstraintEntry* lc_probe = bucket(cindex); - lc_probe != NULL; - lc_probe = lc_probe->next()) { - assert (lc_probe->name() != NULL, "corrupted loader constraint table"); - blk->do_oop((oop*)lc_probe->name_addr()); - } - } -} - // The loaderConstraintTable must always be accessed with the // SystemDictionary lock held. This is true even for readers as // entries in the table could be being dynamically resized. LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint( - symbolHandle name, Handle loader) { + Symbol* name, Handle loader) { unsigned int hash = compute_hash(name); int index = hash_to_index(hash); @@ -93,7 +84,7 @@ while (*pp) { LoaderConstraintEntry* p = *pp; if (p->hash() == hash) { - if (p->name() == name()) { + if (p->name() == name) { for (int i = p->num_loaders() - 1; i >= 0; i--) { if (p->loader(i) == loader()) { return pp; @@ -177,7 +168,6 @@ free_entry(probe); } else { #ifdef ASSERT - assert(is_alive->do_object_b(probe->name()), "name should be live"); if (probe->klass() != NULL) { assert(is_alive->do_object_b(probe->klass()), "klass should be live"); } @@ -194,7 +184,7 @@ } } -bool LoaderConstraintTable::add_entry(symbolHandle class_name, +bool LoaderConstraintTable::add_entry(Symbol* class_name, klassOop klass1, Handle class_loader1, klassOop klass2, Handle class_loader2) { int failure_code = 0; // encode different reasons for failing @@ -233,7 +223,7 @@ unsigned int hash = compute_hash(class_name); int index = hash_to_index(hash); LoaderConstraintEntry* p; - p = new_entry(hash, class_name(), klass, 2, 2); + p = new_entry(hash, class_name, klass, 2, 2); p->set_loaders(NEW_C_HEAP_ARRAY(oop, 2)); p->set_loader(0, class_loader1()); p->set_loader(1, class_loader2()); @@ -244,7 +234,7 @@ ResourceMark rm; tty->print("[Adding new constraint for name: %s, loader[0]: %s," " loader[1]: %s ]\n", - class_name()->as_C_string(), + class_name->as_C_string(), SystemDictionary::loader_name(class_loader1()), SystemDictionary::loader_name(class_loader2()) ); @@ -257,7 +247,7 @@ ResourceMark rm; tty->print("[Setting class object in existing constraint for" " name: %s and loader %s ]\n", - class_name()->as_C_string(), + class_name->as_C_string(), SystemDictionary::loader_name(class_loader1()) ); } @@ -288,7 +278,7 @@ } tty->print("[Failed to add constraint for name: %s, loader[0]: %s," " loader[1]: %s, Reason: %s ]\n", - class_name()->as_C_string(), + class_name->as_C_string(), SystemDictionary::loader_name(class_loader1()), SystemDictionary::loader_name(class_loader2()), reason @@ -303,14 +293,14 @@ // violated bool LoaderConstraintTable::check_or_update(instanceKlassHandle k, Handle loader, - symbolHandle name) { + Symbol* name) { LoaderConstraintEntry* p = *(find_loader_constraint(name, loader)); if (p && p->klass() != NULL && p->klass() != k()) { if (TraceLoaderConstraints) { ResourceMark rm; tty->print("[Constraint check failed for name %s, loader %s: " "the presented class object differs from that stored ]\n", - name()->as_C_string(), + name->as_C_string(), SystemDictionary::loader_name(loader())); } return false; @@ -321,7 +311,7 @@ ResourceMark rm; tty->print("[Updating constraint for name %s, loader %s, " "by setting class object ]\n", - name()->as_C_string(), + name->as_C_string(), SystemDictionary::loader_name(loader())); } } @@ -329,7 +319,7 @@ } } -klassOop LoaderConstraintTable::find_constrained_klass(symbolHandle name, +klassOop LoaderConstraintTable::find_constrained_klass(Symbol* name, Handle loader) { LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); if (p != NULL && p->klass() != NULL) @@ -442,11 +432,10 @@ for (LoaderConstraintEntry* probe = bucket(cindex); probe != NULL; probe = probe->next()) { - guarantee(probe->name()->is_symbol(), "should be symbol"); if (probe->klass() != NULL) { instanceKlass* ik = instanceKlass::cast(probe->klass()); guarantee(ik->name() == probe->name(), "name should match"); - symbolHandle name (thread, ik->name()); + Symbol* name = ik->name(); Handle loader(thread, ik->class_loader()); unsigned int d_hash = dictionary->compute_hash(name, loader); int d_index = dictionary->hash_to_index(d_hash); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/loaderConstraints.hpp --- a/src/share/vm/classfile/loaderConstraints.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/loaderConstraints.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,7 +31,7 @@ class LoaderConstraintEntry; -class LoaderConstraintTable : public Hashtable { +class LoaderConstraintTable : public Hashtable { friend class VMStructs; private: @@ -40,39 +40,39 @@ _nof_buckets = 1009 // number of buckets in hash table }; - LoaderConstraintEntry** find_loader_constraint(symbolHandle name, + LoaderConstraintEntry** find_loader_constraint(Symbol* name, Handle loader); public: LoaderConstraintTable(int nof_buckets); - LoaderConstraintEntry* new_entry(unsigned int hash, symbolOop name, + LoaderConstraintEntry* new_entry(unsigned int hash, Symbol* name, klassOop klass, int num_loaders, int max_loaders); + void free_entry(LoaderConstraintEntry *entry); LoaderConstraintEntry* bucket(int i) { - return (LoaderConstraintEntry*)Hashtable::bucket(i); + return (LoaderConstraintEntry*)Hashtable::bucket(i); } LoaderConstraintEntry** bucket_addr(int i) { - return (LoaderConstraintEntry**)Hashtable::bucket_addr(i); + return (LoaderConstraintEntry**)Hashtable::bucket_addr(i); } // GC support void oops_do(OopClosure* f); - void always_strong_classes_do(OopClosure* blk); // Check class loader constraints - bool add_entry(symbolHandle name, klassOop klass1, Handle loader1, + bool add_entry(Symbol* name, klassOop klass1, Handle loader1, klassOop klass2, Handle loader2); // Note: The main entry point for this module is via SystemDictionary. - // SystemDictionary::check_signature_loaders(symbolHandle signature, + // SystemDictionary::check_signature_loaders(Symbol* signature, // Handle loader1, Handle loader2, // bool is_method, TRAPS) - klassOop find_constrained_klass(symbolHandle name, Handle loader); + klassOop find_constrained_klass(Symbol* name, Handle loader); // Class loader constraints @@ -83,7 +83,7 @@ LoaderConstraintEntry** pp2, klassOop klass); bool check_or_update(instanceKlassHandle k, Handle loader, - symbolHandle name); + Symbol* name); void purge_loader_constraints(BoolObjectClosure* is_alive); @@ -94,34 +94,36 @@ #endif }; -class LoaderConstraintEntry : public HashtableEntry { +class LoaderConstraintEntry : public HashtableEntry { friend class VMStructs; private: - symbolOop _name; // class name + Symbol* _name; // class name int _num_loaders; int _max_loaders; oop* _loaders; // initiating loaders public: - klassOop klass() { return (klassOop)literal(); } - klassOop* klass_addr() { return (klassOop*)literal_addr(); } + klassOop klass() { return literal(); } + klassOop* klass_addr() { return literal_addr(); } void set_klass(klassOop k) { set_literal(k); } LoaderConstraintEntry* next() { - return (LoaderConstraintEntry*)HashtableEntry::next(); + return (LoaderConstraintEntry*)HashtableEntry::next(); } LoaderConstraintEntry** next_addr() { - return (LoaderConstraintEntry**)HashtableEntry::next_addr(); + return (LoaderConstraintEntry**)HashtableEntry::next_addr(); } void set_next(LoaderConstraintEntry* next) { - HashtableEntry::set_next(next); + HashtableEntry::set_next(next); } - symbolOop name() { return _name; } - symbolOop* name_addr() { return &_name; } - void set_name(symbolOop name) { _name = name; } + Symbol* name() { return _name; } + void set_name(Symbol* name) { + _name = name; + if (name != NULL) name->increment_refcount(); + } int num_loaders() { return _num_loaders; } void set_num_loaders(int i) { _num_loaders = i; } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/placeholders.cpp --- a/src/share/vm/classfile/placeholders.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/placeholders.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,10 +31,12 @@ // Placeholder methods -PlaceholderEntry* PlaceholderTable::new_entry(int hash, symbolOop name, +PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name, oop loader, bool havesupername, - symbolOop supername) { - PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable::new_entry(hash, name); + Symbol* supername) { + PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable::new_entry(hash, name); + // Hashtable with Symbol* literal must increment and decrement refcount. + name->increment_refcount(); entry->set_loader(loader); entry->set_havesupername(havesupername); entry->set_supername(supername); @@ -46,33 +48,40 @@ return entry; } +void PlaceholderTable::free_entry(PlaceholderEntry* entry) { + // decrement Symbol refcount here because Hashtable doesn't. + entry->literal()->decrement_refcount(); + if (entry->supername() != NULL) entry->supername()->decrement_refcount(); + Hashtable::free_entry(entry); +} + // Placeholder objects represent classes currently being loaded. // All threads examining the placeholder table must hold the // SystemDictionary_lock, so we don't need special precautions // on store ordering here. void PlaceholderTable::add_entry(int index, unsigned int hash, - symbolHandle class_name, Handle class_loader, - bool havesupername, symbolHandle supername){ + Symbol* class_name, Handle class_loader, + bool havesupername, Symbol* supername){ assert_locked_or_safepoint(SystemDictionary_lock); - assert(!class_name.is_null(), "adding NULL obj"); + assert(class_name != NULL, "adding NULL obj"); // Both readers and writers are locked so it's safe to just // create the placeholder and insert it in the list without a membar. - PlaceholderEntry* entry = new_entry(hash, class_name(), class_loader(), havesupername, supername()); + PlaceholderEntry* entry = new_entry(hash, class_name, class_loader(), havesupername, supername); add_entry(index, entry); } // Remove a placeholder object. void PlaceholderTable::remove_entry(int index, unsigned int hash, - symbolHandle class_name, + Symbol* class_name, Handle class_loader) { assert_locked_or_safepoint(SystemDictionary_lock); PlaceholderEntry** p = bucket_addr(index); while (*p) { PlaceholderEntry *probe = *p; - if (probe->hash() == hash && probe->equals(class_name(), class_loader())) { + if (probe->hash() == hash && probe->equals(class_name, class_loader())) { // Delete entry *p = probe->next(); free_entry(probe); @@ -83,29 +92,28 @@ } PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash, - symbolHandle class_name, + Symbol* class_name, Handle class_loader) { assert_locked_or_safepoint(SystemDictionary_lock); - symbolOop class_name_ = class_name(); oop class_loader_ = class_loader(); for (PlaceholderEntry *place_probe = bucket(index); place_probe != NULL; place_probe = place_probe->next()) { if (place_probe->hash() == hash && - place_probe->equals(class_name_, class_loader_)) { + place_probe->equals(class_name, class_loader_)) { return place_probe; } } return NULL; } -symbolOop PlaceholderTable::find_entry(int index, unsigned int hash, - symbolHandle class_name, +Symbol* PlaceholderTable::find_entry(int index, unsigned int hash, + Symbol* class_name, Handle class_loader) { PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader); - return (probe? probe->klass(): symbolOop(NULL)); + return (probe? probe->klassname(): (Symbol*)NULL); } // find_and_add returns probe pointer - old or new @@ -113,7 +121,7 @@ // If entry exists, reuse entry // For both, push SeenThread for classloadAction // if havesupername: this is used for circularity for instanceklass loading -PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, symbolHandle name, Handle loader, classloadAction action, symbolHandle supername, Thread* thread) { +PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, Symbol* name, Handle loader, classloadAction action, Symbol* supername, Thread* thread) { PlaceholderEntry* probe = get_entry(index, hash, name, loader); if (probe == NULL) { // Nothing found, add place holder @@ -122,7 +130,7 @@ } else { if (action == LOAD_SUPER) { probe->set_havesupername(true); - probe->set_supername(supername()); + probe->set_supername(supername); } } if (probe) probe->add_seen_thread(thread, action); @@ -145,7 +153,7 @@ // Therefore - must always check SD first // Ignores the case where entry is not found void PlaceholderTable::find_and_remove(int index, unsigned int hash, - symbolHandle name, Handle loader, Thread* thread) { + Symbol* name, Handle loader, Thread* thread) { assert_locked_or_safepoint(SystemDictionary_lock); PlaceholderEntry *probe = get_entry(index, hash, name, loader); if (probe != NULL) { @@ -158,7 +166,7 @@ } PlaceholderTable::PlaceholderTable(int table_size) - : TwoOopHashtable(table_size, sizeof(PlaceholderEntry)) { + : TwoOopHashtable(table_size, sizeof(PlaceholderEntry)) { } @@ -174,26 +182,22 @@ void PlaceholderEntry::oops_do(OopClosure* blk) { - assert(klass() != NULL, "should have a non-null klass"); - blk->do_oop((oop*)klass_addr()); + assert(klassname() != NULL, "should have a non-null klass"); if (_loader != NULL) { blk->do_oop(loader_addr()); } - if (_supername != NULL) { - blk->do_oop((oop*)supername_addr()); - } if (_instanceKlass != NULL) { blk->do_oop((oop*)instanceKlass_addr()); } } // do all entries in the placeholder table -void PlaceholderTable::entries_do(void f(symbolOop, oop)) { +void PlaceholderTable::entries_do(void f(Symbol*, oop)) { for (int index = 0; index < table_size(); index++) { for (PlaceholderEntry* probe = bucket(index); probe != NULL; probe = probe->next()) { - f(probe->klass(), probe->loader()); + f(probe->klassname(), probe->loader()); } } } @@ -202,7 +206,7 @@ #ifndef PRODUCT // Note, doesn't append a cr void PlaceholderEntry::print() const { - klass()->print_value(); + klassname()->print_value(); if (loader() != NULL) { tty->print(", loader "); loader()->print_value(); @@ -238,7 +242,6 @@ guarantee(instanceKlass() == NULL || Klass::cast(instanceKlass())->oop_is_instance(), "checking type of instanceKlass result"); - klass()->verify(); } void PlaceholderTable::verify() { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/placeholders.hpp --- a/src/share/vm/classfile/placeholders.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/placeholders.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -34,35 +34,36 @@ // being loaded, as well as arrays of primitives. // -class PlaceholderTable : public TwoOopHashtable { +class PlaceholderTable : public TwoOopHashtable { friend class VMStructs; public: PlaceholderTable(int table_size); - PlaceholderEntry* new_entry(int hash, symbolOop name, oop loader, bool havesupername, symbolOop supername); + PlaceholderEntry* new_entry(int hash, Symbol* name, oop loader, bool havesupername, Symbol* supername); + void free_entry(PlaceholderEntry* entry); PlaceholderEntry* bucket(int i) { - return (PlaceholderEntry*)Hashtable::bucket(i); + return (PlaceholderEntry*)Hashtable::bucket(i); } PlaceholderEntry** bucket_addr(int i) { - return (PlaceholderEntry**)Hashtable::bucket_addr(i); + return (PlaceholderEntry**)Hashtable::bucket_addr(i); } void add_entry(int index, PlaceholderEntry* new_entry) { - Hashtable::add_entry(index, (HashtableEntry*)new_entry); + Hashtable::add_entry(index, (HashtableEntry*)new_entry); } - void add_entry(int index, unsigned int hash, symbolHandle name, - Handle loader, bool havesupername, symbolHandle supername); + void add_entry(int index, unsigned int hash, Symbol* name, + Handle loader, bool havesupername, Symbol* supername); -// This returns a symbolOop to match type for SystemDictionary - symbolOop find_entry(int index, unsigned int hash, - symbolHandle name, Handle loader); + // This returns a Symbol* to match type for SystemDictionary + Symbol* find_entry(int index, unsigned int hash, + Symbol* name, Handle loader); PlaceholderEntry* get_entry(int index, unsigned int hash, - symbolHandle name, Handle loader); + Symbol* name, Handle loader); // caller to create a placeholder entry must enumerate an action // caller claims ownership of that action @@ -84,22 +85,22 @@ // If no entry exists, add a placeholder entry and push SeenThread // If entry exists, reuse entry and push SeenThread for classloadAction PlaceholderEntry* find_and_add(int index, unsigned int hash, - symbolHandle name, Handle loader, - classloadAction action, symbolHandle supername, + Symbol* name, Handle loader, + classloadAction action, Symbol* supername, Thread* thread); void remove_entry(int index, unsigned int hash, - symbolHandle name, Handle loader); + Symbol* name, Handle loader); // Remove placeholder information void find_and_remove(int index, unsigned int hash, - symbolHandle name, Handle loader, Thread* thread); + Symbol* name, Handle loader, Thread* thread); // GC support. void oops_do(OopClosure* f); // JVMTI support - void entries_do(void f(symbolOop, oop)); + void entries_do(void f(Symbol*, oop)); #ifndef PRODUCT void print(); @@ -151,14 +152,14 @@ // on store ordering here. // The system dictionary is the only user of this class. -class PlaceholderEntry : public HashtableEntry { +class PlaceholderEntry : public HashtableEntry { friend class VMStructs; private: oop _loader; // initiating loader bool _havesupername; // distinguish between null supername, and unknown - symbolOop _supername; + Symbol* _supername; Thread* _definer; // owner of define token klassOop _instanceKlass; // instanceKlass from successful define SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class @@ -173,8 +174,7 @@ public: // Simple accessors, used only by SystemDictionary - symbolOop klass() const { return (symbolOop)literal(); } - symbolOop* klass_addr() { return (symbolOop*)literal_addr(); } + Symbol* klassname() const { return literal(); } oop loader() const { return _loader; } void set_loader(oop loader) { _loader = loader; } @@ -183,9 +183,11 @@ bool havesupername() const { return _havesupername; } void set_havesupername(bool havesupername) { _havesupername = havesupername; } - symbolOop supername() const { return _supername; } - void set_supername(symbolOop supername) { _supername = supername; } - symbolOop* supername_addr() { return &_supername; } + Symbol* supername() const { return _supername; } + void set_supername(Symbol* supername) { + _supername = supername; + if (_supername != NULL) _supername->increment_refcount(); + } Thread* definer() const {return _definer; } void set_definer(Thread* definer) { _definer = definer; } @@ -204,17 +206,17 @@ void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; } PlaceholderEntry* next() const { - return (PlaceholderEntry*)HashtableEntry::next(); + return (PlaceholderEntry*)HashtableEntry::next(); } PlaceholderEntry** next_addr() { - return (PlaceholderEntry**)HashtableEntry::next_addr(); + return (PlaceholderEntry**)HashtableEntry::next_addr(); } // Test for equality // Entries are unique for class/classloader name pair - bool equals(symbolOop class_name, oop class_loader) const { - return (klass() == class_name && loader() == class_loader); + bool equals(Symbol* class_name, oop class_loader) const { + return (klassname() == class_name && loader() == class_loader); } SeenThread* actionToQueue(PlaceholderTable::classloadAction action) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/resolutionErrors.cpp --- a/src/share/vm/classfile/resolutionErrors.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/resolutionErrors.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -32,12 +32,12 @@ // add new entry to the table void ResolutionErrorTable::add_entry(int index, unsigned int hash, - constantPoolHandle pool, int cp_index, symbolHandle error) + constantPoolHandle pool, int cp_index, Symbol* error) { assert_locked_or_safepoint(SystemDictionary_lock); - assert(!pool.is_null() && !error.is_null(), "adding NULL obj"); + assert(!pool.is_null() && error != NULL, "adding NULL obj"); - ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error()); + ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error); add_entry(index, entry); } @@ -57,20 +57,35 @@ return NULL; } +void ResolutionErrorEntry::set_error(Symbol* e) { + assert(e == NULL || _error == NULL, "cannot reset error"); + _error = e; + if (_error != NULL) _error->increment_refcount(); +} + // create new error entry ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, constantPoolOop pool, - int cp_index, symbolOop error) + int cp_index, Symbol* error) { - ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable::new_entry(hash, pool); + ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable::new_entry(hash, pool); entry->set_cp_index(cp_index); + NOT_PRODUCT(entry->set_error(NULL);) entry->set_error(error); return entry; } +void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) { + // decrement error refcount + assert(entry->error() != NULL, "error should be set"); + entry->error()->decrement_refcount(); + Hashtable::free_entry(entry); +} + + // create resolution error table ResolutionErrorTable::ResolutionErrorTable(int table_size) - : Hashtable(table_size, sizeof(ResolutionErrorEntry)) { + : Hashtable(table_size, sizeof(ResolutionErrorEntry)) { } // GC support @@ -80,7 +95,7 @@ probe != NULL; probe = probe->next()) { assert(probe->pool() != (constantPoolOop)NULL, "resolution error table is corrupt"); - assert(probe->error() != (symbolOop)NULL, "resolution error table is corrupt"); + assert(probe->error() != (Symbol*)NULL, "resolution error table is corrupt"); probe->oops_do(f); } } @@ -89,20 +104,6 @@ // GC support void ResolutionErrorEntry::oops_do(OopClosure* blk) { blk->do_oop((oop*)pool_addr()); - blk->do_oop((oop*)error_addr()); -} - -// We must keep the symbolOop used in the error alive. The constantPoolOop will -// decide when the entry can be purged. -void ResolutionErrorTable::always_strong_classes_do(OopClosure* blk) { - for (int i = 0; i < table_size(); i++) { - for (ResolutionErrorEntry* probe = bucket(i); - probe != NULL; - probe = probe->next()) { - assert(probe->error() != (symbolOop)NULL, "resolution error table is corrupt"); - blk->do_oop((oop*)probe->error_addr()); - } - } } // Remove unloaded entries from the table diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/resolutionErrors.hpp --- a/src/share/vm/classfile/resolutionErrors.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/resolutionErrors.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -33,27 +33,28 @@ // ResolutionError objects are used to record errors encountered during // constant pool resolution (JVMS 5.4.3). -class ResolutionErrorTable : public Hashtable { +class ResolutionErrorTable : public Hashtable { public: ResolutionErrorTable(int table_size); - ResolutionErrorEntry* new_entry(int hash, constantPoolOop pool, int cp_index, symbolOop error); + ResolutionErrorEntry* new_entry(int hash, constantPoolOop pool, int cp_index, Symbol* error); + void free_entry(ResolutionErrorEntry *entry); ResolutionErrorEntry* bucket(int i) { - return (ResolutionErrorEntry*)Hashtable::bucket(i); + return (ResolutionErrorEntry*)Hashtable::bucket(i); } ResolutionErrorEntry** bucket_addr(int i) { - return (ResolutionErrorEntry**)Hashtable::bucket_addr(i); + return (ResolutionErrorEntry**)Hashtable::bucket_addr(i); } void add_entry(int index, ResolutionErrorEntry* new_entry) { - Hashtable::add_entry(index, (HashtableEntry*)new_entry); + Hashtable::add_entry(index, (HashtableEntry*)new_entry); } void add_entry(int index, unsigned int hash, - constantPoolHandle pool, int which, symbolHandle error); + constantPoolHandle pool, int which, Symbol* error); // find error given the constant pool and constant pool index @@ -68,18 +69,15 @@ // purges unloaded entries from the table void purge_resolution_errors(BoolObjectClosure* is_alive); - // this table keeps symbolOops alive - void always_strong_classes_do(OopClosure* blk); - // GC support. void oops_do(OopClosure* f); }; -class ResolutionErrorEntry : public HashtableEntry { +class ResolutionErrorEntry : public HashtableEntry { private: int _cp_index; - symbolOop _error; + Symbol* _error; public: constantPoolOop pool() const { return (constantPoolOop)literal(); } @@ -88,16 +86,15 @@ int cp_index() const { return _cp_index; } void set_cp_index(int cp_index) { _cp_index = cp_index; } - symbolOop error() const { return _error; } - void set_error(symbolOop e) { _error = e; } - symbolOop* error_addr() { return &_error; } + Symbol* error() const { return _error; } + void set_error(Symbol* e); ResolutionErrorEntry* next() const { - return (ResolutionErrorEntry*)HashtableEntry::next(); + return (ResolutionErrorEntry*)HashtableEntry::next(); } ResolutionErrorEntry** next_addr() { - return (ResolutionErrorEntry**)HashtableEntry::next_addr(); + return (ResolutionErrorEntry**)HashtableEntry::next_addr(); } // GC support diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/stackMapFrame.cpp --- a/src/share/vm/classfile/stackMapFrame.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/stackMapFrame.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -27,7 +27,7 @@ #include "classfile/verifier.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" #include "utilities/globalDefinitions.hpp" @@ -90,8 +90,7 @@ VerificationType StackMapFrame::set_locals_from_arg( const methodHandle m, VerificationType thisKlass, TRAPS) { - symbolHandle signature(THREAD, m->signature()); - SignatureStream ss(signature); + SignatureStream ss(m->signature()); int init_local_num = 0; if (!m->is_static()) { init_local_num++; @@ -118,8 +117,14 @@ case T_OBJECT: case T_ARRAY: { - symbolOop sig = ss.as_symbol(CHECK_(VerificationType::bogus_type())); - return VerificationType::reference_type(symbolHandle(THREAD, sig)); + Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type())); + // Create another symbol to save as signature stream unreferences + // this symbol. + Symbol* sig_copy = + verifier()->create_temporary_symbol(sig, 0, sig->utf8_length(), + CHECK_(VerificationType::bogus_type())); + assert(sig_copy == sig, "symbols don't match"); + return VerificationType::reference_type(sig_copy); } case T_INT: return VerificationType::integer_type(); case T_BYTE: return VerificationType::byte_type(); @@ -157,7 +162,7 @@ VerificationType* from, VerificationType* to, int32_t len, TRAPS) const { for (int32_t i = 0; i < len; i++) { bool subtype = to[i].is_assignable_from( - from[i], verifier()->current_class(), THREAD); + from[i], verifier(), THREAD); if (!subtype) { return false; } @@ -187,7 +192,7 @@ } VerificationType top = _stack[--_stack_size]; bool subtype = type.is_assignable_from( - top, verifier()->current_class(), CHECK_(VerificationType::bogus_type())); + top, verifier(), CHECK_(VerificationType::bogus_type())); if (!subtype) { verifier()->verify_error(_offset, "Bad type on operand stack"); return VerificationType::bogus_type(); @@ -203,7 +208,7 @@ return VerificationType::bogus_type(); } bool subtype = type.is_assignable_from(_locals[index], - verifier()->current_class(), CHECK_(VerificationType::bogus_type())); + verifier(), CHECK_(VerificationType::bogus_type())); if (!subtype) { verifier()->verify_error(_offset, "Bad local variable type"); return VerificationType::bogus_type(); @@ -221,9 +226,9 @@ return; } bool subtype1 = type1.is_assignable_from( - _locals[index], verifier()->current_class(), CHECK); + _locals[index], verifier(), CHECK); bool subtype2 = type2.is_assignable_from( - _locals[index+1], verifier()->current_class(), CHECK); + _locals[index+1], verifier(), CHECK); if (!subtype1 || !subtype2) { verifier()->verify_error(_offset, "Bad local variable type"); return; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/stackMapFrame.hpp --- a/src/share/vm/classfile/stackMapFrame.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/stackMapFrame.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -177,8 +177,7 @@ if (_stack_size != 0) { VerificationType top = _stack[_stack_size - 1]; bool subtype = type.is_assignable_from( - top, verifier()->current_class(), - CHECK_(VerificationType::bogus_type())); + top, verifier(), CHECK_(VerificationType::bogus_type())); if (subtype) { _stack_size --; NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) @@ -194,11 +193,9 @@ assert(type2.is_long() || type2.is_double(), "must be long/double_2"); if (_stack_size >= 2) { VerificationType top1 = _stack[_stack_size - 1]; - bool subtype1 = type1.is_assignable_from( - top1, verifier()->current_class(), CHECK); + bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK); VerificationType top2 = _stack[_stack_size - 2]; - bool subtype2 = type2.is_assignable_from( - top2, verifier()->current_class(), CHECK); + bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK); if (subtype1 && subtype2) { _stack_size -= 2; NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/stackMapTable.cpp --- a/src/share/vm/classfile/stackMapTable.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/stackMapTable.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -184,8 +184,7 @@ _stream->stackmap_format_error("bad class index", THREAD); return VerificationType::bogus_type(); } - return VerificationType::reference_type( - symbolHandle(THREAD, _cp->klass_name_at(class_index))); + return VerificationType::reference_type(_cp->klass_name_at(class_index)); } if (tag == ITEM_UninitializedThis) { if (flags != NULL) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/symbolTable.cpp --- a/src/share/vm/classfile/symbolTable.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/symbolTable.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,7 +31,6 @@ #include "memory/gcLocker.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" -#include "oops/symbolKlass.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/hashtable.inline.hpp" @@ -39,14 +38,97 @@ SymbolTable* SymbolTable::_the_table = NULL; +Symbol* SymbolTable::allocate_symbol(const u1* name, int len, TRAPS) { + // Don't allow symbols to be created which cannot fit in a Symbol*. + if (len > Symbol::max_length()) { + THROW_MSG_0(vmSymbols::java_lang_InternalError(), + "name is too long to represent"); + } + Symbol* sym = new (len) Symbol(name, len); + assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted"); + return sym; +} + +bool SymbolTable::allocate_symbols(int names_count, const u1** names, + int* lengths, Symbol** syms, TRAPS) { + for (int i = 0; i< names_count; i++) { + if (lengths[i] > Symbol::max_length()) { + THROW_MSG_0(vmSymbols::java_lang_InternalError(), + "name is too long to represent"); + } + } + + for (int i = 0; i< names_count; i++) { + int len = lengths[i]; + syms[i] = new (len) Symbol(names[i], len); + assert(syms[i] != NULL, "new should call vm_exit_out_of_memory if " + "C_HEAP is exhausted"); + } + return true; +} + +// Call function for all symbols in the symbol table. +void SymbolTable::symbols_do(SymbolClosure *cl) { + const int n = the_table()->table_size(); + for (int i = 0; i < n; i++) { + for (HashtableEntry* p = the_table()->bucket(i); + p != NULL; + p = p->next()) { + cl->do_symbol(p->literal_addr()); + } + } +} + +int SymbolTable::symbols_removed = 0; +int SymbolTable::symbols_counted = 0; + +// Remove unreferenced symbols from the symbol table +// This is done late during GC. This doesn't use the hash table unlink because +// it assumes that the literals are oops. +void SymbolTable::unlink() { + int removed = 0; + int total = 0; + int memory_total = 0; + for (int i = 0; i < the_table()->table_size(); ++i) { + for (HashtableEntry** p = the_table()->bucket_addr(i); *p != NULL; ) { + HashtableEntry* entry = *p; + if (entry->is_shared()) { + break; + } + Symbol* s = entry->literal(); + memory_total += s->object_size(); + total++; + assert(s != NULL, "just checking"); + // If reference count is zero, remove. + if (s->refcount() == 0) { + delete s; + removed++; + *p = entry->next(); + the_table()->free_entry(entry); + } else { + p = entry->next_addr(); + } + } + } + symbols_removed += removed; + symbols_counted += total; + if (PrintGCDetails) { + gclog_or_tty->print(" [Symbols=%d size=%dK] ", total, + (memory_total*HeapWordSize)/1024); + } +} + + // Lookup a symbol in a bucket. -symbolOop SymbolTable::lookup(int index, const char* name, +Symbol* SymbolTable::lookup(int index, const char* name, int len, unsigned int hash) { - for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { + for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { if (e->hash() == hash) { - symbolOop sym = symbolOop(e->literal()); + Symbol* sym = e->literal(); if (sym->equals(name, len)) { + // something is referencing this symbol now. + sym->increment_refcount(); return sym; } } @@ -62,11 +144,11 @@ // entries in the symbol table during normal execution (only during // safepoints). -symbolOop SymbolTable::lookup(const char* name, int len, TRAPS) { +Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) { unsigned int hashValue = hash_symbol(name, len); int index = the_table()->hash_to_index(hashValue); - symbolOop s = the_table()->lookup(index, name, len, hashValue); + Symbol* s = the_table()->lookup(index, name, len, hashValue); // Found if (s != NULL) return s; @@ -75,7 +157,7 @@ return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL); } -symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) { +Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) { char* buffer; int index, len; unsigned int hashValue; @@ -87,7 +169,7 @@ len = end - begin; hashValue = hash_symbol(name, len); index = the_table()->hash_to_index(hashValue); - symbolOop s = the_table()->lookup(index, name, len, hashValue); + Symbol* s = the_table()->lookup(index, name, len, hashValue); // Found if (s != NULL) return s; @@ -111,18 +193,19 @@ return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL); } -symbolOop SymbolTable::lookup_only(const char* name, int len, +Symbol* SymbolTable::lookup_only(const char* name, int len, unsigned int& hash) { hash = hash_symbol(name, len); int index = the_table()->hash_to_index(hash); - return the_table()->lookup(index, name, len, hash); + Symbol* s = the_table()->lookup(index, name, len, hash); + return s; } // Suggestion: Push unicode-based lookup all the way into the hashing // and probing logic, so there is no need for convert_to_utf8 until -// an actual new symbolOop is created. -symbolOop SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) { +// an actual new Symbol* is created. +Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) { int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length); char stack_buf[128]; if (utf8_length < (int) sizeof(stack_buf)) { @@ -137,7 +220,7 @@ } } -symbolOop SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length, +Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length, unsigned int& hash) { int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length); char stack_buf[128]; @@ -163,25 +246,23 @@ // do it the hard way for (int i=0; ihash_to_index(hashValues[i]); - symbolOop sym = table->basic_add(index, (u1*)names[i], lengths[i], + Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i], hashValues[i], CHECK); cp->symbol_at_put(cp_indices[i], sym); } } } -symbolOop SymbolTable::basic_add(int index, u1 *name, int len, +Symbol* SymbolTable::basic_add(int index, u1 *name, int len, unsigned int hashValue, TRAPS) { assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), "proposed name of symbol must be stable"); // We assume that lookup() has been called already, that it failed, // and symbol was not found. We create the symbol here. - symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); - symbolOop s_oop = sk->allocate_symbol(name, len, CHECK_NULL); - symbolHandle sym (THREAD, s_oop); + Symbol* sym = allocate_symbol(name, len, CHECK_NULL); - // Allocation must be done before grapping the SymbolTable_lock lock + // Allocation must be done before grabbing the SymbolTable_lock lock MutexLocker ml(SymbolTable_lock, THREAD); assert(sym->equals((char*)name, len), "symbol must be properly initialized"); @@ -189,51 +270,51 @@ // Since look-up was done lock-free, we need to check if another // thread beat us in the race to insert the symbol. - symbolOop test = lookup(index, (char*)name, len, hashValue); + Symbol* test = lookup(index, (char*)name, len, hashValue); if (test != NULL) { // A race occurred and another thread introduced the symbol, this one // will be dropped and collected. + delete sym; + assert(test->refcount() != 0, "lookup should have incremented the count"); return test; } - HashtableEntry* entry = new_entry(hashValue, sym()); + HashtableEntry* entry = new_entry(hashValue, sym); + sym->increment_refcount(); add_entry(index, entry); - return sym(); + return sym; } bool SymbolTable::basic_add(constantPoolHandle cp, int names_count, const char** names, int* lengths, int* cp_indices, unsigned int* hashValues, TRAPS) { - symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); - symbolOop sym_oops[symbol_alloc_batch_size]; - bool allocated = sk->allocate_symbols(names_count, names, lengths, - sym_oops, CHECK_false); + Symbol* syms[symbol_alloc_batch_size]; + bool allocated = allocate_symbols(names_count, (const u1**)names, lengths, + syms, CHECK_false); if (!allocated) { return false; } - symbolHandle syms[symbol_alloc_batch_size]; - int i; - for (i=0; iequals(names[i], lengths[i]), "symbol must be properly initialized"); // Since look-up was done lock-free, we need to check if another // thread beat us in the race to insert the symbol. int index = hash_to_index(hashValues[i]); - symbolOop test = lookup(index, names[i], lengths[i], hashValues[i]); + Symbol* test = lookup(index, names[i], lengths[i], hashValues[i]); if (test != NULL) { // A race occurred and another thread introduced the symbol, this one // will be dropped and collected. Use test instead. cp->symbol_at_put(cp_indices[i], test); + assert(test->refcount() != 0, "lookup should have incremented the count"); + delete syms[i]; } else { - symbolOop sym = syms[i](); - HashtableEntry* entry = new_entry(hashValues[i], sym); + Symbol* sym = syms[i]; + HashtableEntry* entry = new_entry(hashValues[i], sym); + sym->increment_refcount(); // increment refcount in external hashtable add_entry(index, entry); cp->symbol_at_put(cp_indices[i], sym); } @@ -245,12 +326,10 @@ void SymbolTable::verify() { for (int i = 0; i < the_table()->table_size(); ++i) { - HashtableEntry* p = the_table()->bucket(i); + HashtableEntry* p = the_table()->bucket(i); for ( ; p != NULL; p = p->next()) { - symbolOop s = symbolOop(p->literal()); + Symbol* s = (Symbol*)(p->literal()); guarantee(s != NULL, "symbol is NULL"); - s->verify(); - guarantee(s->is_perm(), "symbol not in permspace"); unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length()); guarantee(p->hash() == h, "broken hash in symbol table entry"); guarantee(the_table()->hash_to_index(h) == i, @@ -279,10 +358,14 @@ int total = 0; int max_symbols = 0; int out_of_range = 0; + int memory_total = 0; + int count = 0; for (i = 0; i < the_table()->table_size(); i++) { - HashtableEntry* p = the_table()->bucket(i); + HashtableEntry* p = the_table()->bucket(i); for ( ; p != NULL; p = p->next()) { - int counter = symbolOop(p->literal())->utf8_length(); + memory_total += p->literal()->object_size(); + count++; + int counter = p->literal()->utf8_length(); total += counter; if (counter < results_length) { results[counter]++; @@ -293,6 +376,17 @@ } } tty->print_cr("Symbol Table:"); + tty->print_cr("Total number of symbols %5d", count); + tty->print_cr("Total size in memory %5dK", + (memory_total*HeapWordSize)/1024); + tty->print_cr("Total counted %5d", symbols_counted); + tty->print_cr("Total removed %5d", symbols_removed); + if (symbols_counted > 0) { + tty->print_cr("Percent removed %3.2f", + ((float)symbols_removed/(float)symbols_counted)* 100); + } + tty->print_cr("Reference counts %5d", Symbol::_total_count); + tty->print_cr("Histogram of symbol length:"); tty->print_cr("%8s %5d", "Total ", total); tty->print_cr("%8s %5d", "Maximum", max_symbols); tty->print_cr("%8s %3.2f", "Average", @@ -304,22 +398,41 @@ tty->print_cr("%6d %10d", i, results[i]); } } - int line_length = 70; - tty->print_cr("%s %30s", " Length", "Number chains that length"); - for (i = 0; i < results_length; i++) { - if (results[i] > 0) { - tty->print("%4d", i); - for (j = 0; (j < results[i]) && (j < line_length); j++) { - tty->print("%1s", "*"); + if (Verbose) { + int line_length = 70; + tty->print_cr("%s %30s", " Length", "Number chains that length"); + for (i = 0; i < results_length; i++) { + if (results[i] > 0) { + tty->print("%4d", i); + for (j = 0; (j < results[i]) && (j < line_length); j++) { + tty->print("%1s", "*"); + } + if (j == line_length) { + tty->print("%1s", "+"); + } + tty->cr(); } - if (j == line_length) { - tty->print("%1s", "+"); + } + } + tty->print_cr(" %s %d: %d\n", "Number chains longer than", + results_length, out_of_range); +} + +void SymbolTable::print() { + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry** p = the_table()->bucket_addr(i); + HashtableEntry* entry = the_table()->bucket(i); + if (entry != NULL) { + while (entry != NULL) { + tty->print(PTR_FORMAT " ", entry->literal()); + entry->literal()->print(); + tty->print(" %d", entry->literal()->refcount()); + p = entry->next_addr(); + entry = (HashtableEntry*)HashtableEntry::make_ptr(*p); } tty->cr(); } } - tty->print_cr(" %s %d: %d\n", "Number chains longer than", - results_length, out_of_range); } #endif // PRODUCT @@ -396,7 +509,7 @@ oop StringTable::lookup(int index, jchar* name, int len, unsigned int hash) { - for (HashtableEntry* l = bucket(index); l != NULL; l = l->next()) { + for (HashtableEntry* l = bucket(index); l != NULL; l = l->next()) { if (l->hash() == hash) { if (java_lang_String::equals(l->literal(), name, len)) { return l->literal(); @@ -436,13 +549,13 @@ return test; } - HashtableEntry* entry = new_entry(hashValue, string()); + HashtableEntry* entry = new_entry(hashValue, string()); add_entry(index, entry); return string(); } -oop StringTable::lookup(symbolOop symbol) { +oop StringTable::lookup(Symbol* symbol) { ResourceMark rm; int length; jchar* chars = symbol->as_unicode(length); @@ -466,7 +579,7 @@ hashValue, CHECK_NULL); } -oop StringTable::intern(symbolOop symbol, TRAPS) { +oop StringTable::intern(Symbol* symbol, TRAPS) { if (symbol == NULL) return NULL; ResourceMark rm(THREAD); int length; @@ -500,9 +613,50 @@ return result; } +void StringTable::unlink(BoolObjectClosure* is_alive) { + // Readers of the table are unlocked, so we should only be removing + // entries at a safepoint. + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + for (int i = 0; i < the_table()->table_size(); ++i) { + for (HashtableEntry** p = the_table()->bucket_addr(i); *p != NULL; ) { + HashtableEntry* entry = *p; + if (entry->is_shared()) { + break; + } + assert(entry->literal() != NULL, "just checking"); + if (is_alive->do_object_b(entry->literal())) { + p = entry->next_addr(); + } else { + *p = entry->next(); + the_table()->free_entry(entry); + } + } + } +} + +void StringTable::oops_do(OopClosure* f) { + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry** p = the_table()->bucket_addr(i); + HashtableEntry* entry = the_table()->bucket(i); + while (entry != NULL) { + f->do_oop((oop*)entry->literal_addr()); + + // Did the closure remove the literal from the table? + if (entry->literal() == NULL) { + assert(!entry->is_shared(), "immutable hashtable entry?"); + *p = entry->next(); + the_table()->free_entry(entry); + } else { + p = entry->next_addr(); + } + entry = (HashtableEntry*)HashtableEntry::make_ptr(*p); + } + } +} + void StringTable::verify() { for (int i = 0; i < the_table()->table_size(); ++i) { - HashtableEntry* p = the_table()->bucket(i); + HashtableEntry* p = the_table()->bucket(i); for ( ; p != NULL; p = p->next()) { oop s = p->literal(); guarantee(s != NULL, "interned string is NULL"); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/symbolTable.hpp --- a/src/share/vm/classfile/symbolTable.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/symbolTable.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -26,11 +26,11 @@ #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP #include "memory/allocation.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "utilities/hashtable.hpp" -// The symbol table holds all symbolOops and corresponding interned strings. -// symbolOops and literal strings should be canonicalized. +// The symbol table holds all Symbol*s and corresponding interned strings. +// Symbol*s and literal strings should be canonicalized. // // The interned strings are created lazily. // @@ -42,32 +42,76 @@ class BoolObjectClosure; -class SymbolTable : public Hashtable { +// Class to hold a newly created or referenced Symbol* temporarily in scope. +// new_symbol() and lookup() will create a Symbol* if not already in the +// symbol table and add to the symbol's reference count. +// probe() and lookup_only() will increment the refcount if symbol is found. +class TempNewSymbol : public StackObj { + Symbol* _temp; + + public: + TempNewSymbol() : _temp(NULL) {} + // Creating or looking up a symbol increments the symbol's reference count + TempNewSymbol(Symbol *s) : _temp(s) {} + + // Operator= increments reference count. + void operator=(const TempNewSymbol &s) { + _temp = s._temp; + if (_temp !=NULL) _temp->increment_refcount(); + } + + // Decrement reference counter so it can go away if it's unique + ~TempNewSymbol() { if (_temp != NULL) _temp->decrement_refcount(); } + + // Operators so they can be used like Symbols + Symbol* operator -> () const { return _temp; } + bool operator == (Symbol* o) const { return _temp == o; } + // Sneaky conversion function + operator Symbol*() { return _temp; } +}; + +class SymbolTable : public Hashtable { friend class VMStructs; + friend class ClassFileParser; private: // The symbol table static SymbolTable* _the_table; + // For statistics + static int symbols_removed; + static int symbols_counted; + + Symbol* allocate_symbol(const u1* name, int len, TRAPS); // Assumes no characters larger than 0x7F + bool allocate_symbols(int names_count, const u1** names, int* lengths, Symbol** syms, TRAPS); + // Adding elements - symbolOop basic_add(int index, u1* name, int len, + Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue, TRAPS); bool basic_add(constantPoolHandle cp, int names_count, const char** names, int* lengths, int* cp_indices, unsigned int* hashValues, TRAPS); + static void new_symbols(constantPoolHandle cp, int names_count, + const char** name, int* lengths, + int* cp_indices, unsigned int* hashValues, + TRAPS) { + add(cp, names_count, name, lengths, cp_indices, hashValues, THREAD); + } + + // Table size enum { symbol_table_size = 20011 }; - symbolOop lookup(int index, const char* name, int len, unsigned int hash); + Symbol* lookup(int index, const char* name, int len, unsigned int hash); SymbolTable() - : Hashtable(symbol_table_size, sizeof (HashtableEntry)) {} + : Hashtable(symbol_table_size, sizeof (HashtableEntry)) {} SymbolTable(HashtableBucket* t, int number_of_entries) - : Hashtable(symbol_table_size, sizeof (HashtableEntry), t, + : Hashtable(symbol_table_size, sizeof (HashtableEntry), t, number_of_entries) {} @@ -92,66 +136,76 @@ _the_table = new SymbolTable(t, number_of_entries); } - static symbolOop lookup(const char* name, int len, TRAPS); + static Symbol* lookup(const char* name, int len, TRAPS); // lookup only, won't add. Also calculate hash. - static symbolOop lookup_only(const char* name, int len, unsigned int& hash); + static Symbol* lookup_only(const char* name, int len, unsigned int& hash); // Only copy to C string to be added if lookup failed. - static symbolOop lookup(symbolHandle sym, int begin, int end, TRAPS); + static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS); + + static void release(Symbol* sym); // jchar (utf16) version of lookups - static symbolOop lookup_unicode(const jchar* name, int len, TRAPS); - static symbolOop lookup_only_unicode(const jchar* name, int len, unsigned int& hash); + static Symbol* lookup_unicode(const jchar* name, int len, TRAPS); + static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash); static void add(constantPoolHandle cp, int names_count, const char** names, int* lengths, int* cp_indices, unsigned int* hashValues, TRAPS); - // GC support - // Delete pointers to otherwise-unreachable objects. - static void unlink(BoolObjectClosure* cl) { - the_table()->Hashtable::unlink(cl); + // Release any dead symbols + static void unlink(); + + // iterate over symbols + static void symbols_do(SymbolClosure *cl); + + // Symbol creation + static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) { + assert(utf8_buffer != NULL, "just checking"); + return lookup(utf8_buffer, length, THREAD); } - - // Invoke "f->do_oop" on the locations of all oops in the table. - static void oops_do(OopClosure* f) { - the_table()->Hashtable::oops_do(f); + static Symbol* new_symbol(const char* name, TRAPS) { + return new_symbol(name, (int)strlen(name), THREAD); + } + static Symbol* new_symbol(const Symbol* sym, int begin, int end, TRAPS) { + assert(begin <= end && end <= sym->utf8_length(), "just checking"); + return lookup(sym, begin, end, THREAD); } // Symbol lookup - static symbolOop lookup(int index, const char* name, int len, TRAPS); + static Symbol* lookup(int index, const char* name, int len, TRAPS); // Needed for preloading classes in signatures when compiling. // Returns the symbol is already present in symbol table, otherwise // NULL. NO ALLOCATION IS GUARANTEED! - static symbolOop probe(const char* name, int len) { + static Symbol* probe(const char* name, int len) { unsigned int ignore_hash; return lookup_only(name, len, ignore_hash); } - static symbolOop probe_unicode(const jchar* name, int len) { + static Symbol* probe_unicode(const jchar* name, int len) { unsigned int ignore_hash; return lookup_only_unicode(name, len, ignore_hash); } // Histogram static void print_histogram() PRODUCT_RETURN; + static void print() PRODUCT_RETURN; // Debugging static void verify(); // Sharing static void copy_buckets(char** top, char*end) { - the_table()->Hashtable::copy_buckets(top, end); + the_table()->Hashtable::copy_buckets(top, end); } static void copy_table(char** top, char*end) { - the_table()->Hashtable::copy_table(top, end); + the_table()->Hashtable::copy_table(top, end); } static void reverse(void* boundary = NULL) { - ((Hashtable*)the_table())->reverse(boundary); + the_table()->Hashtable::reverse(boundary); } }; - -class StringTable : public Hashtable { +class StringTable : public Hashtable { friend class VMStructs; private: @@ -169,10 +223,10 @@ oop lookup(int index, jchar* chars, int length, unsigned int hashValue); - StringTable() : Hashtable(string_table_size, sizeof (HashtableEntry)) {} + StringTable() : Hashtable(string_table_size, sizeof (HashtableEntry)) {} StringTable(HashtableBucket* t, int number_of_entries) - : Hashtable(string_table_size, sizeof (HashtableEntry), t, + : Hashtable(string_table_size, sizeof (HashtableEntry), t, number_of_entries) {} public: @@ -192,26 +246,20 @@ _the_table = new StringTable(t, number_of_entries); } - static int hash_string(jchar* s, int len); - // GC support // Delete pointers to otherwise-unreachable objects. - static void unlink(BoolObjectClosure* cl) { - the_table()->Hashtable::unlink(cl); - } + static void unlink(BoolObjectClosure* cl); // Invoke "f->do_oop" on the locations of all oops in the table. - static void oops_do(OopClosure* f) { - the_table()->Hashtable::oops_do(f); - } + static void oops_do(OopClosure* f); // Probing - static oop lookup(symbolOop symbol); + static oop lookup(Symbol* symbol); // Interning - static oop intern(symbolOop symbol, TRAPS); + static oop intern(Symbol* symbol, TRAPS); static oop intern(oop string, TRAPS); static oop intern(const char *utf8_string, TRAPS); @@ -220,13 +268,13 @@ // Sharing static void copy_buckets(char** top, char*end) { - the_table()->Hashtable::copy_buckets(top, end); + the_table()->Hashtable::copy_buckets(top, end); } static void copy_table(char** top, char*end) { - the_table()->Hashtable::copy_table(top, end); + the_table()->Hashtable::copy_table(top, end); } static void reverse() { - ((BasicHashtable*)the_table())->reverse(); + the_table()->Hashtable::reverse(); } }; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/systemDictionary.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -93,8 +93,8 @@ JavaValue result(T_OBJECT); JavaCalls::call_static(&result, KlassHandle(THREAD, WK_KLASS(ClassLoader_klass)), - vmSymbolHandles::getSystemClassLoader_name(), - vmSymbolHandles::void_classloader_signature(), + vmSymbols::getSystemClassLoader_name(), + vmSymbols::void_classloader_signature(), CHECK); _java_system_loader = (oop)result.get_jobject(); @@ -107,8 +107,8 @@ #ifdef ASSERT // return true if class_name contains no '.' (internal format is '/') -bool SystemDictionary::is_internal_format(symbolHandle class_name) { - if (class_name.not_null()) { +bool SystemDictionary::is_internal_format(Symbol* class_name) { + if (class_name != NULL) { ResourceMark rm; char* name = class_name->as_C_string(); return strchr(name, '.') == NULL; @@ -141,7 +141,7 @@ // Forwards to resolve_or_null -klassOop SystemDictionary::resolve_or_fail(symbolHandle class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS) { +klassOop SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS) { klassOop klass = resolve_or_null(class_name, class_loader, protection_domain, THREAD); if (HAS_PENDING_EXCEPTION || klass == NULL) { KlassHandle k_h(THREAD, klass); @@ -151,7 +151,7 @@ return klass; } -klassOop SystemDictionary::handle_resolution_exception(symbolHandle class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS) { +klassOop SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS) { if (HAS_PENDING_EXCEPTION) { // If we have a pending exception we forward it to the caller, unless throw_error is true, // in which case we have to check whether the pending exception is a ClassNotFoundException, @@ -180,7 +180,7 @@ } -klassOop SystemDictionary::resolve_or_fail(symbolHandle class_name, +klassOop SystemDictionary::resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS) { return resolve_or_fail(class_name, Handle(), Handle(), throw_error, THREAD); @@ -189,48 +189,49 @@ // Forwards to resolve_instance_class_or_null -klassOop SystemDictionary::resolve_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS) { +klassOop SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { assert(!THREAD->is_Compiler_thread(), "Can not load classes with the Compiler thread"); - if (FieldType::is_array(class_name())) { + if (FieldType::is_array(class_name)) { return resolve_array_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL); + } else if (FieldType::is_obj(class_name)) { + ResourceMark rm(THREAD); + // Ignore wrapping L and ;. + TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1, + class_name->utf8_length() - 2, CHECK_NULL); + return resolve_instance_class_or_null(name, class_loader, protection_domain, CHECK_NULL); } else { return resolve_instance_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL); } } -klassOop SystemDictionary::resolve_or_null(symbolHandle class_name, TRAPS) { +klassOop SystemDictionary::resolve_or_null(Symbol* class_name, TRAPS) { return resolve_or_null(class_name, Handle(), Handle(), THREAD); } // Forwards to resolve_instance_class_or_null -klassOop SystemDictionary::resolve_array_class_or_null(symbolHandle class_name, +klassOop SystemDictionary::resolve_array_class_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { - assert(FieldType::is_array(class_name()), "must be array"); - jint dimension; - symbolOop object_key; + assert(FieldType::is_array(class_name), "must be array"); klassOop k = NULL; - // dimension and object_key are assigned as a side-effect of this call - BasicType t = FieldType::get_array_info(class_name(), - &dimension, - &object_key, - CHECK_NULL); - + FieldArrayInfo fd; + // dimension and object_key in FieldArrayInfo are assigned as a side-effect + // of this call + BasicType t = FieldType::get_array_info(class_name, fd, CHECK_NULL); if (t == T_OBJECT) { - symbolHandle h_key(THREAD, object_key); // naked oop "k" is OK here -- we assign back into it - k = SystemDictionary::resolve_instance_class_or_null(h_key, + k = SystemDictionary::resolve_instance_class_or_null(fd.object_key(), class_loader, protection_domain, CHECK_NULL); if (k != NULL) { - k = Klass::cast(k)->array_klass(dimension, CHECK_NULL); + k = Klass::cast(k)->array_klass(fd.dimension(), CHECK_NULL); } } else { k = Universe::typeArrayKlassObj(t); - k = typeArrayKlass::cast(k)->array_klass(dimension, CHECK_NULL); + k = typeArrayKlass::cast(k)->array_klass(fd.dimension(), CHECK_NULL); } return k; } @@ -271,8 +272,8 @@ // Must be called, even if superclass is null, since this is // where the placeholder entry is created which claims this // thread is loading this class/classloader. -klassOop SystemDictionary::resolve_super_or_fail(symbolHandle child_name, - symbolHandle class_name, +klassOop SystemDictionary::resolve_super_or_fail(Symbol* child_name, + Symbol* class_name, Handle class_loader, Handle protection_domain, bool is_superclass, @@ -281,7 +282,7 @@ // Try to get one of the well-known klasses. // They are trusted, and do not participate in circularities. if (LinkWellKnownClasses) { - klassOop k = find_well_known_klass(class_name()); + klassOop k = find_well_known_klass(class_name); if (k != NULL) { return k; } @@ -323,7 +324,7 @@ if ((childk != NULL ) && (is_superclass) && ((quicksuperk = instanceKlass::cast(childk)->super()) != NULL) && - ((Klass::cast(quicksuperk)->name() == class_name()) && + ((Klass::cast(quicksuperk)->name() == class_name) && (Klass::cast(quicksuperk)->class_loader() == class_loader()))) { return quicksuperk; } else { @@ -342,7 +343,7 @@ } // java.lang.Object should have been found above - assert(class_name() != NULL, "null super class for resolving"); + assert(class_name != NULL, "null super class for resolving"); // Resolve the super class or interface, check results on return klassOop superk = NULL; superk = SystemDictionary::resolve_or_null(class_name, @@ -392,8 +393,8 @@ JavaCalls::call_special(&result, class_loader, system_loader, - vmSymbolHandles::checkPackageAccess_name(), - vmSymbolHandles::class_protectiondomain_signature(), + vmSymbols::checkPackageAccess_name(), + vmSymbols::class_protectiondomain_signature(), Handle(THREAD, klass->java_mirror()), protection_domain, THREAD); @@ -414,7 +415,7 @@ { // We recalculate the entry here -- we've called out to java since // the last time it was calculated. - symbolHandle kn(THREAD, klass->name()); + Symbol* kn = klass->name(); unsigned int d_hash = dictionary()->compute_hash(kn, class_loader); int d_index = dictionary()->hash_to_index(d_hash); @@ -489,7 +490,7 @@ // and we are done, // If return null klassOop and no pending exception, the caller must load the class instanceKlassHandle SystemDictionary::handle_parallel_super_load( - symbolHandle name, symbolHandle superclassname, Handle class_loader, + Symbol* name, Symbol* superclassname, Handle class_loader, Handle protection_domain, Handle lockObject, TRAPS) { instanceKlassHandle nh = instanceKlassHandle(); // null Handle @@ -578,17 +579,9 @@ } -klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS) { - assert(class_name.not_null() && !FieldType::is_array(class_name()), "invalid class name"); - // First check to see if we should remove wrapping L and ; - symbolHandle name; - if (FieldType::is_obj(class_name())) { - ResourceMark rm(THREAD); - // Ignore wrapping L and ;. - name = oopFactory::new_symbol_handle(class_name()->as_C_string() + 1, class_name()->utf8_length() - 2, CHECK_NULL); - } else { - name = class_name; - } +klassOop SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle class_loader, Handle protection_domain, TRAPS) { + assert(name != NULL && !FieldType::is_array(name) && + !FieldType::is_obj(name), "invalid class name"); // UseNewReflection // Fix for 4474172; see evaluation for more details @@ -632,7 +625,7 @@ bool havesupername = false; instanceKlassHandle k; PlaceholderEntry* placeholder; - symbolHandle superclassname; + Symbol* superclassname = NULL; { MutexLocker mu(SystemDictionary_lock, THREAD); @@ -646,7 +639,7 @@ if (placeholder && placeholder->super_load_in_progress()) { super_load_in_progress = true; if (placeholder->havesupername() == true) { - superclassname = symbolHandle(THREAD, placeholder->supername()); + superclassname = placeholder->supername(); havesupername = true; } } @@ -691,7 +684,6 @@ // No performance benefit and no deadlock issues. // case 5. parallelCapable user level classloaders - without objectLocker // Allow parallel classloading of a class/classloader pair - symbolHandle nullsymbolHandle; bool throw_circularity_error = false; { MutexLocker mu(SystemDictionary_lock, THREAD); @@ -733,7 +725,7 @@ // LOAD_INSTANCE in parallel // add placeholder entry even if error - callers will remove on error if (!throw_circularity_error && !class_has_been_loaded) { - PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, class_loader, PlaceholderTable::LOAD_INSTANCE, nullsymbolHandle, THREAD); + PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, class_loader, PlaceholderTable::LOAD_INSTANCE, NULL, THREAD); // For class loaders that do not acquire the classloader object lock, // if they did not catch another thread holding LOAD_INSTANCE, // need a check analogous to the acquire ObjectLocker/find_class @@ -837,7 +829,7 @@ { Handle loader (THREAD, k->class_loader()); MutexLocker mu(SystemDictionary_lock, THREAD); - oop kk = find_class_or_placeholder(name, loader); + oop kk = find_class(name, loader); assert(kk == k(), "should be present in dictionary"); } #endif @@ -880,7 +872,7 @@ // _dictionary->bucket(index) is read here, so the caller will not see // the new entry. -klassOop SystemDictionary::find(symbolHandle class_name, +klassOop SystemDictionary::find(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { @@ -910,37 +902,34 @@ // Look for a loaded instance or array klass by name. Do not do any loading. // return NULL in case of error. -klassOop SystemDictionary::find_instance_or_array_klass(symbolHandle class_name, +klassOop SystemDictionary::find_instance_or_array_klass(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { klassOop k = NULL; - assert(class_name() != NULL, "class name must be non NULL"); + assert(class_name != NULL, "class name must be non NULL"); // Try to get one of the well-known klasses. if (LinkWellKnownClasses) { - k = find_well_known_klass(class_name()); + k = find_well_known_klass(class_name); if (k != NULL) { return k; } } - if (FieldType::is_array(class_name())) { + if (FieldType::is_array(class_name)) { // The name refers to an array. Parse the name. - jint dimension; - symbolOop object_key; - - // dimension and object_key are assigned as a side-effect of this call - BasicType t = FieldType::get_array_info(class_name(), &dimension, - &object_key, CHECK_(NULL)); + // dimension and object_key in FieldArrayInfo are assigned as a + // side-effect of this call + FieldArrayInfo fd; + BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL)); if (t != T_OBJECT) { k = Universe::typeArrayKlassObj(t); } else { - symbolHandle h_key(THREAD, object_key); - k = SystemDictionary::find(h_key, class_loader, protection_domain, THREAD); + k = SystemDictionary::find(fd.object_key(), class_loader, protection_domain, THREAD); } if (k != NULL) { - k = Klass::cast(k)->array_klass_or_null(dimension); + k = Klass::cast(k)->array_klass_or_null(fd.dimension()); } } else { k = find(class_name, class_loader, protection_domain, THREAD); @@ -949,7 +938,7 @@ } // Quick range check for names of well-known classes: -static symbolOop wk_klass_name_limits[2] = {NULL, NULL}; +static Symbol* wk_klass_name_limits[2] = {NULL, NULL}; #ifndef PRODUCT static int find_wkk_calls, find_wkk_probes, find_wkk_wins; @@ -957,7 +946,7 @@ // => 60% hit after limit guard, 25% total win rate #endif -klassOop SystemDictionary::find_well_known_klass(symbolOop class_name) { +klassOop SystemDictionary::find_well_known_klass(Symbol* class_name) { // A bounds-check on class_name will quickly get a negative result. NOT_PRODUCT(find_wkk_calls++); if (class_name >= wk_klass_name_limits[0] && @@ -983,14 +972,14 @@ // Note: this method is much like resolve_from_stream, but // updates no supplemental data structures. // TODO consolidate the two methods with a helper routine? -klassOop SystemDictionary::parse_stream(symbolHandle class_name, +klassOop SystemDictionary::parse_stream(Symbol* class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, KlassHandle host_klass, GrowableArray* cp_patches, TRAPS) { - symbolHandle parsed_name; + TempNewSymbol parsed_name = NULL; // Parse the stream. Note that we do this even though this klass might // already be present in the SystemDictionary, otherwise we would not @@ -1011,13 +1000,12 @@ true, THREAD); - // We don't redefine the class, so we just need to clean up whether there // was an error or not (don't want to modify any system dictionary // data structures). // Parsed name could be null if we threw an error before we got far // enough along to parse it -- in that case, there is nothing to clean up. - if (!parsed_name.is_null()) { + if (parsed_name != NULL) { unsigned int p_hash = placeholders()->compute_hash(parsed_name, class_loader); int p_index = placeholders()->hash_to_index(p_hash); @@ -1060,7 +1048,7 @@ // Note: class_name can be NULL. In that case we do not know the name of // the class until we have parsed the stream. -klassOop SystemDictionary::resolve_from_stream(symbolHandle class_name, +klassOop SystemDictionary::resolve_from_stream(Symbol* class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, @@ -1079,7 +1067,7 @@ check_loader_lock_contention(lockObject, THREAD); ObjectLocker ol(lockObject, THREAD, DoObjectLock); - symbolHandle parsed_name; + TempNewSymbol parsed_name = NULL; // Parse the stream. Note that we do this even though this klass might // already be present in the SystemDictionary, otherwise we would not @@ -1101,7 +1089,7 @@ const char* pkg = "java/"; if (!HAS_PENDING_EXCEPTION && !class_loader.is_null() && - !parsed_name.is_null() && + parsed_name != NULL && !strncmp((const char*)parsed_name->bytes(), pkg, strlen(pkg))) { // It is illegal to define classes in the "java." package from // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader @@ -1121,9 +1109,8 @@ } if (!HAS_PENDING_EXCEPTION) { - assert(!parsed_name.is_null(), "Sanity"); - assert(class_name.is_null() || class_name() == parsed_name(), - "name mismatch"); + assert(parsed_name != NULL, "Sanity"); + assert(class_name == NULL || class_name == parsed_name, "name mismatch"); // Verification prevents us from creating names with dots in them, this // asserts that that's the case. assert(is_internal_format(parsed_name), @@ -1144,7 +1131,7 @@ // must make sure parsed_name is valid first (it won't be if we had // a format error before the class was parsed far enough to // find the name). - if (HAS_PENDING_EXCEPTION && !parsed_name.is_null()) { + if (HAS_PENDING_EXCEPTION && parsed_name != NULL) { unsigned int p_hash = placeholders()->compute_hash(parsed_name, class_loader); int p_index = placeholders()->hash_to_index(p_hash); @@ -1160,16 +1147,16 @@ // SystemDictionary; this is only done on success debug_only( { if (!HAS_PENDING_EXCEPTION) { - assert(!parsed_name.is_null(), "parsed_name is still null?"); - symbolHandle h_name (THREAD, k->name()); + assert(parsed_name != NULL, "parsed_name is still null?"); + Symbol* h_name = k->name(); Handle h_loader (THREAD, k->class_loader()); MutexLocker mu(SystemDictionary_lock, THREAD); - oop check = find_class_or_placeholder(parsed_name, class_loader); + klassOop check = find_class(parsed_name, class_loader); assert(check == k(), "should be present in the dictionary"); - oop check2 = find_class_or_placeholder(h_name, h_loader); + klassOop check2 = find_class(h_name, h_loader); assert(check == check2, "name inconsistancy in SystemDictionary"); } } ); @@ -1189,7 +1176,7 @@ // If there is a shared dictionary, then find the entry for the // given shared system class, if any. -klassOop SystemDictionary::find_shared_class(symbolHandle class_name) { +klassOop SystemDictionary::find_shared_class(Symbol* class_name) { if (shared_dictionary() != NULL) { unsigned int d_hash = dictionary()->compute_hash(class_name, Handle()); int d_index = dictionary()->hash_to_index(d_hash); @@ -1207,7 +1194,7 @@ // object hierarchy until loaded.] instanceKlassHandle SystemDictionary::load_shared_class( - symbolHandle class_name, Handle class_loader, TRAPS) { + Symbol* class_name, Handle class_loader, TRAPS) { instanceKlassHandle ik (THREAD, find_shared_class(class_name)); return load_shared_class(ik, class_loader, THREAD); } @@ -1222,14 +1209,14 @@ assert(class_loader.is_null(), "non-null classloader for shared class?"); if (ik.not_null()) { instanceKlassHandle nh = instanceKlassHandle(); // null Handle - symbolHandle class_name(THREAD, ik->name()); + Symbol* class_name = ik->name(); // Found the class, now load the superclass and interfaces. If they // are shared, add them to the main system dictionary and reset // their hierarchy references (supers, subs, and interfaces). if (ik->super() != NULL) { - symbolHandle cn(THREAD, ik->super()->klass_part()->name()); + Symbol* cn = ik->super()->klass_part()->name(); resolve_super_or_fail(class_name, cn, class_loader, Handle(), true, CHECK_(nh)); } @@ -1243,7 +1230,7 @@ // interfaces' instanceKlass's C++ vtbls haven't been // reinitialized yet (they will be once the interface classes // are loaded) - symbolHandle name (THREAD, k->klass_part()->name()); + Symbol* name = k->klass_part()->name(); resolve_super_or_fail(class_name, name, class_loader, Handle(), false, CHECK_(nh)); } @@ -1290,7 +1277,7 @@ // Note that with delegation class loaders all classes in another loader will // first try to call this so it'd better be fast!! static instanceKlassHandle download_and_retry_class_load( - symbolHandle class_name, + Symbol* class_name, TRAPS) { klassOop dlm = SystemDictionary::sun_jkernel_DownloadManager_klass(); @@ -1313,8 +1300,8 @@ // public static String getBootClassPathEntryForClass(String className); JavaCalls::call_static(&result, KlassHandle(THREAD, dlm), - vmSymbolHandles::getBootClassPathEntryForClass_name(), - vmSymbolHandles::string_string_signature(), + vmSymbols::getBootClassPathEntryForClass_name(), + vmSymbols::string_string_signature(), class_string, CHECK_(nk)); @@ -1344,7 +1331,7 @@ #endif // KERNEL -instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS) { +instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) { instanceKlassHandle nh = instanceKlassHandle(); // null Handle if (class_loader.is_null()) { @@ -1419,16 +1406,16 @@ JavaCalls::call_special(&result, class_loader, spec_klass, - vmSymbolHandles::loadClassInternal_name(), - vmSymbolHandles::string_class_signature(), + vmSymbols::loadClassInternal_name(), + vmSymbols::string_class_signature(), string, CHECK_(nh)); } else { JavaCalls::call_virtual(&result, class_loader, spec_klass, - vmSymbolHandles::loadClass_name(), - vmSymbolHandles::string_class_signature(), + vmSymbols::loadClass_name(), + vmSymbols::string_class_signature(), string, CHECK_(nh)); } @@ -1444,7 +1431,7 @@ // For user defined Java class loaders, check that the name returned is // the same as that requested. This check is done for the bootstrap // loader when parsing the class file. - if (class_name() == k->name()) { + if (class_name == k->name()) { return k; } } @@ -1477,7 +1464,7 @@ // classloader lock held // Parallel classloaders will call find_or_define_instance_class // which will require a token to perform the define class - symbolHandle name_h(THREAD, k->name()); + Symbol* name_h = k->name(); unsigned int d_hash = dictionary()->compute_hash(name_h, class_loader_h); int d_index = dictionary()->hash_to_index(d_hash); check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK); @@ -1536,10 +1523,10 @@ // findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they // potentially waste time reading and parsing the bytestream. // Note: VM callers should ensure consistency of k/class_name,class_loader -instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle class_name, Handle class_loader, instanceKlassHandle k, TRAPS) { +instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* class_name, Handle class_loader, instanceKlassHandle k, TRAPS) { instanceKlassHandle nh = instanceKlassHandle(); // null Handle - symbolHandle name_h(THREAD, k->name()); // passed in class_name may be null + Symbol* name_h = k->name(); // passed in class_name may be null unsigned int d_hash = dictionary()->compute_hash(name_h, class_loader); int d_index = dictionary()->hash_to_index(d_hash); @@ -1560,8 +1547,7 @@ } // Acquire define token for this class/classloader - symbolHandle nullsymbolHandle; - probe = placeholders()->find_and_add(p_index, p_hash, name_h, class_loader, PlaceholderTable::DEFINE_CLASS, nullsymbolHandle, THREAD); + probe = placeholders()->find_and_add(p_index, p_hash, name_h, class_loader, PlaceholderTable::DEFINE_CLASS, NULL, THREAD); // Wait if another thread defining in parallel // All threads wait - even those that will throw duplicate class: otherwise // caller is surprised by LinkageError: duplicate, but findLoadedClass fails @@ -1653,7 +1639,7 @@ // Lookup klassOop SystemDictionary::find_class(int index, unsigned int hash, - symbolHandle class_name, + Symbol* class_name, Handle class_loader) { assert_locked_or_safepoint(SystemDictionary_lock); assert (index == dictionary()->index_for(class_name, class_loader), @@ -1665,18 +1651,17 @@ // Basic find on classes in the midst of being loaded -symbolOop SystemDictionary::find_placeholder(int index, unsigned int hash, - symbolHandle class_name, - Handle class_loader) { +Symbol* SystemDictionary::find_placeholder(Symbol* class_name, + Handle class_loader) { assert_locked_or_safepoint(SystemDictionary_lock); - - return placeholders()->find_entry(index, hash, class_name, class_loader); + unsigned int p_hash = placeholders()->compute_hash(class_name, class_loader); + int p_index = placeholders()->hash_to_index(p_hash); + return placeholders()->find_entry(p_index, p_hash, class_name, class_loader); } // Used for assertions and verification only -oop SystemDictionary::find_class_or_placeholder(symbolHandle class_name, - Handle class_loader) { +klassOop SystemDictionary::find_class(Symbol* class_name, Handle class_loader) { #ifndef ASSERT guarantee(VerifyBeforeGC || VerifyDuringGC || @@ -1684,22 +1669,11 @@ VerifyAfterGC, "too expensive"); #endif assert_locked_or_safepoint(SystemDictionary_lock); - symbolOop class_name_ = class_name(); - oop class_loader_ = class_loader(); // First look in the loaded class array unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader); int d_index = dictionary()->hash_to_index(d_hash); - oop lookup = find_class(d_index, d_hash, class_name, class_loader); - - if (lookup == NULL) { - // Next try the placeholders - unsigned int p_hash = placeholders()->compute_hash(class_name,class_loader); - int p_index = placeholders()->hash_to_index(p_hash); - lookup = find_placeholder(p_index, p_hash, class_name, class_loader); - } - - return lookup; + return find_class(d_index, d_hash, class_name, class_loader); } @@ -1757,12 +1731,6 @@ // Visit extra methods invoke_method_table()->oops_do(blk); - - // Loader constraints. We must keep the symbolOop used in the name alive. - constraints()->always_strong_classes_do(blk); - - // Resolution errors keep the symbolOop for the error alive - resolution_errors()->always_strong_classes_do(blk); } @@ -1808,9 +1776,6 @@ void SystemDictionary::preloaded_oops_do(OopClosure* f) { - f->do_oop((oop*) &wk_klass_name_limits[0]); - f->do_oop((oop*) &wk_klass_name_limits[1]); - for (int k = (int)FIRST_WKID; k < (int)WKID_LIMIT; k++) { f->do_oop((oop*) &_well_known_klasses[k]); } @@ -1862,7 +1827,7 @@ dictionary()->classes_do(f, CHECK); } -void SystemDictionary::placeholders_do(void f(symbolOop, oop)) { +void SystemDictionary::placeholders_do(void f(Symbol*, oop)) { placeholders()->entries_do(f); } @@ -1882,7 +1847,7 @@ // class is loaded. klassOop aos = _abstract_ownable_synchronizer_klass; if (aos == NULL) { - klassOop k = resolve_or_fail(vmSymbolHandles::java_util_concurrent_locks_AbstractOwnableSynchronizer(), true, CHECK); + klassOop k = resolve_or_fail(vmSymbols::java_util_concurrent_locks_AbstractOwnableSynchronizer(), true, CHECK); // Force a fence to prevent any read before the write completes OrderAccess::fence(); _abstract_ownable_synchronizer_klass = k; @@ -1924,7 +1889,7 @@ assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob"); int info = wk_init_info[id - FIRST_WKID]; int sid = (info >> CEIL_LG_OPTION_LIMIT); - symbolHandle symbol = vmSymbolHandles::symbol_handle_at((vmSymbols::SID)sid); + Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid); klassOop* klassp = &_well_known_klasses[id]; bool must_load = (init_opt < SystemDictionary::Opt); bool try_load = true; @@ -1954,7 +1919,7 @@ initialize_wk_klass((WKID)id, opt, CHECK); // Update limits, so find_well_known_klass can be very fast: - symbolOop s = vmSymbols::symbol_at((vmSymbols::SID)sid); + Symbol* s = vmSymbols::symbol_at((vmSymbols::SID)sid); if (wk_klass_name_limits[1] == NULL) { wk_klass_name_limits[0] = wk_klass_name_limits[1] = s; } else if (wk_klass_name_limits[1] < s) { @@ -2081,7 +2046,7 @@ TRAPS) { const char *linkage_error = NULL; { - symbolHandle name (THREAD, k->name()); + Symbol* name = k->name(); MutexLocker mu(SystemDictionary_lock, THREAD); klassOop check = find_class(d_index, d_hash, name, class_loader); @@ -2102,10 +2067,8 @@ } #ifdef ASSERT - unsigned int p_hash = placeholders()->compute_hash(name, class_loader); - int p_index = placeholders()->hash_to_index(p_hash); - symbolOop ph_check = find_placeholder(p_index, p_hash, name, class_loader); - assert(ph_check == NULL || ph_check == name(), "invalid symbol"); + Symbol* ph_check = find_placeholder(name, class_loader); + assert(ph_check == NULL || ph_check == name, "invalid symbol"); #endif if (linkage_error == NULL) { @@ -2141,7 +2104,7 @@ TRAPS) { // Compile_lock prevents systemDictionary updates during compilations assert_locked_or_safepoint(Compile_lock); - symbolHandle name (THREAD, k->name()); + Symbol* name = k->name(); { MutexLocker mu1(SystemDictionary_lock, THREAD); @@ -2181,7 +2144,7 @@ // while only one thread can define a class at one time, multiple // classes can resolve the superclass for a class at one time, // and the placeholder is used to track that -// symbolOop ph_check = find_placeholder(p_index, p_hash, name, class_loader); +// Symbol* ph_check = find_placeholder(name, class_loader); // assert (ph_check == NULL, "should not have a placeholder entry"); #endif SystemDictionary_lock->notify_all(); @@ -2190,7 +2153,7 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass( - symbolHandle class_name, Handle class_loader, TRAPS) { + Symbol* class_name, Handle class_loader, TRAPS) { // First see if it has been loaded directly. // Force the protection domain to be null. (This removes protection checks.) @@ -2203,23 +2166,20 @@ // Now look to see if it has been loaded elsewhere, and is subject to // a loader constraint that would require this loader to return the // klass that is already loaded. - if (FieldType::is_array(class_name())) { + if (FieldType::is_array(class_name)) { // For array classes, their klassOops are not kept in the // constraint table. The element klassOops are. - jint dimension; - symbolOop object_key; - BasicType t = FieldType::get_array_info(class_name(), &dimension, - &object_key, CHECK_(NULL)); + FieldArrayInfo fd; + BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL)); if (t != T_OBJECT) { klass = Universe::typeArrayKlassObj(t); } else { - symbolHandle elem_name(THREAD, object_key); MutexLocker mu(SystemDictionary_lock, THREAD); - klass = constraints()->find_constrained_klass(elem_name, class_loader); + klass = constraints()->find_constrained_klass(fd.object_key(), class_loader); } // If element class already loaded, allocate array klass if (klass != NULL) { - klass = Klass::cast(klass)->array_klass_or_null(dimension); + klass = Klass::cast(klass)->array_klass_or_null(fd.dimension()); } } else { MutexLocker mu(SystemDictionary_lock, THREAD); @@ -2231,25 +2191,23 @@ } -bool SystemDictionary::add_loader_constraint(symbolHandle class_name, +bool SystemDictionary::add_loader_constraint(Symbol* class_name, Handle class_loader1, Handle class_loader2, Thread* THREAD) { - symbolHandle constraint_name; - if (!FieldType::is_array(class_name())) { + Symbol* constraint_name = NULL; + if (!FieldType::is_array(class_name)) { constraint_name = class_name; } else { // For array classes, their klassOops are not kept in the // constraint table. The element classes are. - jint dimension; - symbolOop object_key; - BasicType t = FieldType::get_array_info(class_name(), &dimension, - &object_key, CHECK_(false)); + FieldArrayInfo fd; + BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(false)); // primitive types always pass if (t != T_OBJECT) { return true; } else { - constraint_name = symbolHandle(THREAD, object_key); + constraint_name = fd.object_key(); } } unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1); @@ -2272,7 +2230,7 @@ // Add entry to resolution error table to record the error when the first // attempt to resolve a reference to a class has failed. -void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, symbolHandle error) { +void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, Symbol* error) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { @@ -2282,13 +2240,13 @@ } // Lookup resolution error table. Returns error if found, otherwise NULL. -symbolOop SystemDictionary::find_resolution_error(constantPoolHandle pool, int which) { +Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { MutexLocker ml(SystemDictionary_lock, Thread::current()); ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which); - return (entry != NULL) ? entry->error() : (symbolOop)NULL; + return (entry != NULL) ? entry->error() : (Symbol*)NULL; } } @@ -2344,7 +2302,7 @@ // NULL if no constraint failed. The returned C string needs cleaning up // with a ResourceMark in the caller. No exception except OOME is thrown. // Arrays are not added to the loader constraint table, their elements are. -char* SystemDictionary::check_signature_loaders(symbolHandle signature, +char* SystemDictionary::check_signature_loaders(Symbol* signature, Handle loader1, Handle loader2, bool is_method, TRAPS) { // Nothing to do if loaders are the same. @@ -2352,13 +2310,14 @@ return NULL; } + ResourceMark rm(THREAD); SignatureStream sig_strm(signature, is_method); while (!sig_strm.is_done()) { if (sig_strm.is_object()) { - symbolOop s = sig_strm.as_symbol(CHECK_NULL); - symbolHandle sig (THREAD, s); + Symbol* s = sig_strm.as_symbol(CHECK_NULL); + Symbol* sig = s; if (!add_loader_constraint(sig, loader1, loader2, THREAD)) { - return sig()->as_C_string(); + return sig->as_C_string(); } } sig_strm.next(); @@ -2367,12 +2326,12 @@ } -methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name, - symbolHandle signature, +methodOop SystemDictionary::find_method_handle_invoke(Symbol* name, + Symbol* signature, KlassHandle accessing_klass, TRAPS) { if (!EnableMethodHandles) return NULL; - vmSymbols::SID name_id = vmSymbols::find_sid(name()); + vmSymbols::SID name_id = vmSymbols::find_sid(name); assert(name_id != vmSymbols::NO_SID, "must be a known name"); unsigned int hash = invoke_method_table()->compute_hash(signature, name_id); int index = invoke_method_table()->hash_to_index(hash); @@ -2385,7 +2344,7 @@ return NULL; // do not attempt from within compiler bool for_invokeGeneric = (name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name)); bool found_on_bcp = false; - Handle mt = find_method_handle_type(signature(), accessing_klass, + Handle mt = find_method_handle_type(signature, accessing_klass, for_invokeGeneric, found_on_bcp, CHECK_NULL); KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass(); @@ -2416,7 +2375,7 @@ // signature, as interpreted relative to the given class loader. // Because of class loader constraints, all method handle usage must be // consistent with this loader. -Handle SystemDictionary::find_method_handle_type(symbolHandle signature, +Handle SystemDictionary::find_method_handle_type(Symbol* signature, KlassHandle accessing_klass, bool for_invokeGeneric, bool& return_bcp_flag, @@ -2424,11 +2383,12 @@ Handle class_loader, protection_domain; bool is_on_bcp = true; // keep this true as long as we can materialize from the boot classloader Handle empty; - int npts = ArgumentCount(signature()).size(); + int npts = ArgumentCount(signature).size(); objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty)); int arg = 0; Handle rt; // the return type from the signature - for (SignatureStream ss(signature()); !ss.is_done(); ss.next()) { + ResourceMark rm(THREAD); + for (SignatureStream ss(signature); !ss.is_done(); ss.next()) { oop mirror = NULL; if (is_on_bcp) { mirror = ss.as_java_mirror(class_loader, protection_domain, @@ -2500,17 +2460,18 @@ Handle SystemDictionary::link_method_handle_constant(KlassHandle caller, int ref_kind, //e.g., JVM_REF_invokeVirtual KlassHandle callee, - symbolHandle name_sym, - symbolHandle signature, + Symbol* name_sym, + Symbol* signature, TRAPS) { Handle empty; - Handle name = java_lang_String::create_from_symbol(name_sym(), CHECK_(empty)); + Handle name = java_lang_String::create_from_symbol(name_sym, CHECK_(empty)); Handle type; if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') { bool ignore_is_on_bcp = false; type = find_method_handle_type(signature, caller, false, ignore_is_on_bcp, CHECK_(empty)); } else { - SignatureStream ss(signature(), false); + ResourceMark rm(THREAD); + SignatureStream ss(signature, false); if (!ss.is_done()) { oop mirror = ss.as_java_mirror(caller->class_loader(), caller->protection_domain(), SignatureStream::NCDFError, CHECK_(empty)); @@ -2542,7 +2503,7 @@ // Ask Java code to find or construct a java.dyn.CallSite for the given // name and signature, as interpreted relative to the given class loader. Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method, - symbolHandle name, + Symbol* name, methodHandle signature_invoker, Handle info, methodHandle caller_method, @@ -2557,7 +2518,7 @@ MethodHandles::init_MemberName(caller_mname(), caller_method()); // call sun.dyn.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos) - oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle! + oop name_str_oop = StringTable::intern(name, CHECK_(empty)); // not a handle! JavaCallArguments args(Handle(THREAD, bootstrap_method())); args.push_oop(name_str_oop); args.push_oop(signature_invoker->method_handle_type()); @@ -2740,16 +2701,20 @@ void SystemDictionary::verify_obj_klass_present(Handle obj, - symbolHandle class_name, + Symbol* class_name, Handle class_loader) { GCMutexLocker mu(SystemDictionary_lock); - oop probe = find_class_or_placeholder(class_name, class_loader); + Symbol* name; + + klassOop probe = find_class(class_name, class_loader); if (probe == NULL) { probe = SystemDictionary::find_shared_class(class_name); + if (probe == NULL) { + name = find_placeholder(class_name, class_loader); + } } - guarantee(probe != NULL && - (!probe->is_klass() || probe == obj()), - "Loaded klasses should be in SystemDictionary"); + guarantee(probe != NULL || name != NULL, + "Loaded klasses should be in SystemDictionary"); } #ifndef PRODUCT diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -28,14 +28,14 @@ #include "classfile/classFileStream.hpp" #include "classfile/classLoader.hpp" #include "oops/objArrayOop.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/java.hpp" #include "runtime/reflectionUtils.hpp" #include "utilities/hashtable.hpp" // The system dictionary stores all loaded classes and maps: // -// [class name,class loader] -> class i.e. [symbolOop,oop] -> klassOop +// [class name,class loader] -> class i.e. [Symbol*,oop] -> klassOop // // Classes are loaded lazily. The default VM class loader is // represented as NULL. @@ -226,26 +226,26 @@ // throw_error flag. For most uses the throw_error argument should be set // to true. - static klassOop resolve_or_fail(symbolHandle class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS); + static klassOop resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS); // Convenient call for null loader and protection domain. - static klassOop resolve_or_fail(symbolHandle class_name, bool throw_error, TRAPS); + static klassOop resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS); private: // handle error translation for resolve_or_null results - static klassOop handle_resolution_exception(symbolHandle class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS); + static klassOop handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS); public: // Returns a class with a given class name and class loader. // Loads the class if needed. If not found NULL is returned. - static klassOop resolve_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS); + static klassOop resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS); // Version with null loader and protection domain - static klassOop resolve_or_null(symbolHandle class_name, TRAPS); + static klassOop resolve_or_null(Symbol* class_name, TRAPS); // Resolve a superclass or superinterface. Called from ClassFileParser, // parse_interfaces, resolve_instance_class_or_null, load_shared_class // "child_name" is the class whose super class or interface is being resolved. - static klassOop resolve_super_or_fail(symbolHandle child_name, - symbolHandle class_name, + static klassOop resolve_super_or_fail(Symbol* child_name, + Symbol* class_name, Handle class_loader, Handle protection_domain, bool is_superclass, @@ -253,7 +253,7 @@ // Parse new stream. This won't update the system dictionary or // class hierarchy, simply parse the stream. Used by JVMTI RedefineClasses. - static klassOop parse_stream(symbolHandle class_name, + static klassOop parse_stream(Symbol* class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, @@ -261,7 +261,7 @@ KlassHandle nullHandle; return parse_stream(class_name, class_loader, protection_domain, st, nullHandle, NULL, THREAD); } - static klassOop parse_stream(symbolHandle class_name, + static klassOop parse_stream(Symbol* class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, @@ -270,23 +270,23 @@ TRAPS); // Resolve from stream (called by jni_DefineClass and JVM_DefineClass) - static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader, + static klassOop resolve_from_stream(Symbol* class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, bool verify, TRAPS); // Lookup an already loaded class. If not found NULL is returned. - static klassOop find(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS); + static klassOop find(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS); // Lookup an already loaded instance or array class. // Do not make any queries to class loaders; consult only the cache. // If not found NULL is returned. - static klassOop find_instance_or_array_klass(symbolHandle class_name, + static klassOop find_instance_or_array_klass(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS); // If the given name is known to vmSymbols, return the well-know klass: - static klassOop find_well_known_klass(symbolOop class_name); + static klassOop find_well_known_klass(Symbol* class_name); // Lookup an instance or array class that has already been loaded // either into the given class loader, or else into another class @@ -309,7 +309,7 @@ // satisfied, and it is safe for classes in the given class loader // to manipulate strongly-typed values of the found class, subject // to local linkage and access checks. - static klassOop find_constrained_instance_or_array_klass(symbolHandle class_name, + static klassOop find_constrained_instance_or_array_klass(Symbol* class_name, Handle class_loader, TRAPS); @@ -324,7 +324,7 @@ // (added for helpers that use HandleMarks and ResourceMarks) static void classes_do(void f(klassOop, oop, TRAPS), TRAPS); // All entries in the placeholder table and their class loaders - static void placeholders_do(void f(symbolOop, oop)); + static void placeholders_do(void f(Symbol*, oop)); // Iterate over all methods in all klasses in dictionary static void methods_do(void f(methodOop)); @@ -383,12 +383,12 @@ static void verify(); #ifdef ASSERT - static bool is_internal_format(symbolHandle class_name); + static bool is_internal_format(Symbol* class_name); #endif // Verify class is in dictionary static void verify_obj_klass_present(Handle obj, - symbolHandle class_name, + Symbol* class_name, Handle class_loader); // Initialization @@ -469,19 +469,19 @@ // Note: java_lang_Class::primitive_type is the inverse of java_mirror // Check class loader constraints - static bool add_loader_constraint(symbolHandle name, Handle loader1, + static bool add_loader_constraint(Symbol* name, Handle loader1, Handle loader2, TRAPS); - static char* check_signature_loaders(symbolHandle signature, Handle loader1, + static char* check_signature_loaders(Symbol* signature, Handle loader1, Handle loader2, bool is_method, TRAPS); // JSR 292 // find the java.dyn.MethodHandles::invoke method for a given signature - static methodOop find_method_handle_invoke(symbolHandle name, - symbolHandle signature, + static methodOop find_method_handle_invoke(Symbol* name, + Symbol* signature, KlassHandle accessing_klass, TRAPS); // ask Java to compute a java.dyn.MethodType object for a given signature - static Handle find_method_handle_type(symbolHandle signature, + static Handle find_method_handle_type(Symbol* signature, KlassHandle accessing_klass, bool for_invokeGeneric, bool& return_bcp_flag, @@ -490,13 +490,13 @@ static Handle link_method_handle_constant(KlassHandle caller, int ref_kind, //e.g., JVM_REF_invokeVirtual KlassHandle callee, - symbolHandle name, - symbolHandle signature, + Symbol* name, + Symbol* signature, TRAPS); // ask Java to create a dynamic call site, while linking an invokedynamic op static Handle make_dynamic_call_site(Handle bootstrap_method, // Callee information: - symbolHandle name, + Symbol* name, methodHandle signature_invoker, Handle info, // Caller information: @@ -519,8 +519,8 @@ // Record the error when the first attempt to resolve a reference from a constant // pool entry to a class fails. - static void add_resolution_error(constantPoolHandle pool, int which, symbolHandle error); - static symbolOop find_resolution_error(constantPoolHandle pool, int which); + static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error); + static Symbol* find_resolution_error(constantPoolHandle pool, int which); private: @@ -580,29 +580,29 @@ static SymbolPropertyTable* invoke_method_table() { return _invoke_method_table; } // Basic loading operations - static klassOop resolve_instance_class_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS); - static klassOop resolve_array_class_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS); - static instanceKlassHandle handle_parallel_super_load(symbolHandle class_name, symbolHandle supername, Handle class_loader, Handle protection_domain, Handle lockObject, TRAPS); + static klassOop resolve_instance_class_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS); + static klassOop resolve_array_class_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS); + static instanceKlassHandle handle_parallel_super_load(Symbol* class_name, Symbol* supername, Handle class_loader, Handle protection_domain, Handle lockObject, TRAPS); // Wait on SystemDictionary_lock; unlocks lockObject before // waiting; relocks lockObject with correct recursion count // after waiting, but before reentering SystemDictionary_lock // to preserve lock order semantics. static void double_lock_wait(Handle lockObject, TRAPS); static void define_instance_class(instanceKlassHandle k, TRAPS); - static instanceKlassHandle find_or_define_instance_class(symbolHandle class_name, + static instanceKlassHandle find_or_define_instance_class(Symbol* class_name, Handle class_loader, instanceKlassHandle k, TRAPS); - static instanceKlassHandle load_shared_class(symbolHandle class_name, + static instanceKlassHandle load_shared_class(Symbol* class_name, Handle class_loader, TRAPS); static instanceKlassHandle load_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS); - static instanceKlassHandle load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS); + static instanceKlassHandle load_instance_class(Symbol* class_name, Handle class_loader, TRAPS); static Handle compute_loader_lock_object(Handle class_loader, TRAPS); static void check_loader_lock_contention(Handle loader_lock, TRAPS); static bool is_parallelCapable(Handle class_loader); static bool is_parallelDefine(Handle class_loader); - static klassOop find_shared_class(symbolHandle class_name); + static klassOop find_shared_class(Symbol* class_name); // Setup link to hierarchy static void add_to_hierarchy(instanceKlassHandle k, TRAPS); @@ -613,34 +613,29 @@ // Basic find on loaded classes static klassOop find_class(int index, unsigned int hash, - symbolHandle name, Handle loader); + Symbol* name, Handle loader); + static klassOop find_class(Symbol* class_name, Handle class_loader); // Basic find on classes in the midst of being loaded - static symbolOop find_placeholder(int index, unsigned int hash, - symbolHandle name, Handle loader); - - // Basic find operation of loaded classes and classes in the midst - // of loading; used for assertions and verification only. - static oop find_class_or_placeholder(symbolHandle class_name, - Handle class_loader); + static Symbol* find_placeholder(Symbol* name, Handle loader); // Updating entry in dictionary // Add a completely loaded class - static void add_klass(int index, symbolHandle class_name, + static void add_klass(int index, Symbol* class_name, Handle class_loader, KlassHandle obj); // Add a placeholder for a class being loaded static void add_placeholder(int index, - symbolHandle class_name, + Symbol* class_name, Handle class_loader); static void remove_placeholder(int index, - symbolHandle class_name, + Symbol* class_name, Handle class_loader); // Performs cleanups after resolve_super_or_fail. This typically needs // to be called on failure. // Won't throw, but can block. - static void resolution_cleanups(symbolHandle class_name, + static void resolution_cleanups(Symbol* class_name, Handle class_loader, TRAPS); @@ -670,7 +665,6 @@ static bool _has_checkPackageAccess; }; -// Cf. vmSymbols vs. vmSymbolHandles class SystemDictionaryHandles : AllStatic { public: #define WK_KLASS_HANDLE_DECLARE(name, ignore_symbol, option) \ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/verificationType.cpp --- a/src/share/vm/classfile/verificationType.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/verificationType.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/symbolTable.hpp" #include "classfile/verificationType.hpp" +#include "classfile/verifier.hpp" VerificationType VerificationType::from_tag(u1 tag) { switch (tag) { @@ -41,7 +42,8 @@ } bool VerificationType::is_reference_assignable_from( - const VerificationType& from, instanceKlassHandle context, TRAPS) const { + const VerificationType& from, ClassVerifier* context, TRAPS) const { + instanceKlassHandle klass = context->current_class(); if (from.is_null()) { // null is assignable to any reference return true; @@ -56,8 +58,8 @@ return true; } klassOop obj = SystemDictionary::resolve_or_fail( - name_handle(), Handle(THREAD, context->class_loader()), - Handle(THREAD, context->protection_domain()), true, CHECK_false); + name(), Handle(THREAD, klass->class_loader()), + Handle(THREAD, klass->protection_domain()), true, CHECK_false); KlassHandle this_class(THREAD, obj); if (this_class->is_interface()) { @@ -66,13 +68,13 @@ return true; } else if (from.is_object()) { klassOop from_class = SystemDictionary::resolve_or_fail( - from.name_handle(), Handle(THREAD, context->class_loader()), - Handle(THREAD, context->protection_domain()), true, CHECK_false); + from.name(), Handle(THREAD, klass->class_loader()), + Handle(THREAD, klass->protection_domain()), true, CHECK_false); return instanceKlass::cast(from_class)->is_subclass_of(this_class()); } } else if (is_array() && from.is_array()) { - VerificationType comp_this = get_component(CHECK_false); - VerificationType comp_from = from.get_component(CHECK_false); + VerificationType comp_this = get_component(context, CHECK_false); + VerificationType comp_from = from.get_component(context, CHECK_false); if (!comp_this.is_bogus() && !comp_from.is_bogus()) { return comp_this.is_assignable_from(comp_from, context, CHECK_false); } @@ -80,9 +82,9 @@ return false; } -VerificationType VerificationType::get_component(TRAPS) const { +VerificationType VerificationType::get_component(ClassVerifier *context, TRAPS) const { assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array"); - symbolOop component; + Symbol* component; switch (name()->byte_at(1)) { case 'Z': return VerificationType(Boolean); case 'B': return VerificationType(Byte); @@ -93,12 +95,12 @@ case 'F': return VerificationType(Float); case 'D': return VerificationType(Double); case '[': - component = SymbolTable::lookup( + component = context->create_temporary_symbol( name(), 1, name()->utf8_length(), CHECK_(VerificationType::bogus_type())); return VerificationType::reference_type(component); case 'L': - component = SymbolTable::lookup( + component = context->create_temporary_symbol( name(), 2, name()->utf8_length() - 1, CHECK_(VerificationType::bogus_type())); return VerificationType::reference_type(component); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/verificationType.hpp --- a/src/share/vm/classfile/verificationType.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/verificationType.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -29,7 +29,7 @@ #include "memory/allocation.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/handles.hpp" #include "runtime/signature.hpp" @@ -47,6 +47,8 @@ ITEM_Bogus = (uint)-1 }; +class ClassVerifier; + class VerificationType VALUE_OBJ_CLASS_SPEC { private: // Least significant bits of _handle are always 0, so we use these as @@ -56,7 +58,7 @@ // will catch this and we'll have to add a descriminator tag to this // structure. union { - symbolOop* _handle; + Symbol* _sym; uintptr_t _data; } _u; @@ -73,7 +75,7 @@ TypeMask = 0x00000003, // Topmost types encoding - Reference = 0x0, // _handle contains the name + Reference = 0x0, // _sym contains the name Primitive = 0x1, // see below for primitive list Uninitialized = 0x2, // 0x00ffff00 contains bci TypeQuery = 0x3, // Meta-types used for category testing @@ -85,7 +87,7 @@ Category2_2ndFlag = 0x04, // Second word of a two-word value // special reference values - Null = 0x00000000, // A reference with a 0 handle is null + Null = 0x00000000, // A reference with a 0 sym is null // Primitives categories (the second byte determines the category) Category1 = (Category1Flag << 1 * BitsPerByte) | Primitive, @@ -152,17 +154,14 @@ static VerificationType category2_2nd_check() { return VerificationType(Category2_2ndQuery); } - // For reference types, store the actual oop* handle - static VerificationType reference_type(symbolHandle sh) { - assert(((uintptr_t)sh.raw_value() & 0x3) == 0, "Oops must be aligned"); + // For reference types, store the actual Symbol + static VerificationType reference_type(Symbol* sh) { + assert(((uintptr_t)sh & 0x3) == 0, "Oops must be aligned"); // If the above assert fails in the future because oop* isn't aligned, // then this type encoding system will have to change to have a tag value // to descriminate between oops and primitives. - return VerificationType((uintptr_t)((symbolOop*)sh.raw_value())); + return VerificationType((uintptr_t)sh); } - static VerificationType reference_type(symbolOop s, TRAPS) - { return reference_type(symbolHandle(THREAD, s)); } - static VerificationType uninitialized_type(u2 bci) { return VerificationType(bci << 1 * BitsPerByte | Uninitialized); } static VerificationType uninitialized_this_type() @@ -242,13 +241,9 @@ return ((_u._data & BciMask) >> 1 * BitsPerByte); } - symbolHandle name_handle() const { + Symbol* name() const { assert(is_reference() && !is_null(), "Must be a non-null reference"); - return symbolHandle(_u._handle, true); - } - symbolOop name() const { - assert(is_reference() && !is_null(), "Must be a non-null reference"); - return *(_u._handle); + return _u._sym; } bool equals(const VerificationType& t) const { @@ -269,7 +264,7 @@ // is assignable to another. Returns true if one can assign 'from' to // this. bool is_assignable_from( - const VerificationType& from, instanceKlassHandle context, TRAPS) const { + const VerificationType& from, ClassVerifier* context, TRAPS) const { if (equals(from) || is_bogus()) { return true; } else { @@ -298,7 +293,7 @@ } } - VerificationType get_component(TRAPS) const; + VerificationType get_component(ClassVerifier* context, TRAPS) const; int dimensions() const { assert(is_array(), "Must be an array"); @@ -312,7 +307,7 @@ private: bool is_reference_assignable_from( - const VerificationType&, instanceKlassHandle, TRAPS) const; + const VerificationType&, ClassVerifier*, TRAPS) const; }; #endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/verifier.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -98,10 +98,10 @@ } bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) { + HandleMark hm; ResourceMark rm(THREAD); - HandleMark hm; - symbolHandle exception_name; + Symbol* exception_name = NULL; const size_t message_buffer_len = klass->name()->utf8_length() + 1024; char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len); @@ -141,7 +141,7 @@ tty->print("Verification for %s has", klassName); tty->print_cr(" exception pending %s ", instanceKlass::cast(PENDING_EXCEPTION->klass())->external_name()); - } else if (!exception_name.is_null()) { + } else if (exception_name != NULL) { tty->print_cr("Verification for %s failed", klassName); } tty->print_cr("End class verification for: %s", klassName); @@ -150,7 +150,7 @@ if (HAS_PENDING_EXCEPTION) { return false; // use the existing exception - } else if (exception_name.is_null()) { + } else if (exception_name == NULL) { return true; // verifcation succeeded } else { // VerifyError or ClassFormatError to be created and thrown ResourceMark rm(THREAD); @@ -172,7 +172,7 @@ } bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { - symbolOop name = klass->name(); + Symbol* name = klass->name(); klassOop refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass(); return (should_verify_for(klass->class_loader(), should_verify_class) && @@ -202,7 +202,7 @@ ); } -symbolHandle Verifier::inference_verify( +Symbol* Verifier::inference_verify( instanceKlassHandle klass, char* message, size_t message_len, TRAPS) { JavaThread* thread = (JavaThread*)THREAD; JNIEnv *env = thread->jni_environment(); @@ -245,18 +245,17 @@ // These numbers are chosen so that VerifyClassCodes interface doesn't need // to be changed (still return jboolean (unsigned char)), and result is // 1 when verification is passed. - symbolHandle nh(NULL); if (result == 0) { return vmSymbols::java_lang_VerifyError(); } else if (result == 1) { - return nh; // verified. + return NULL; // verified. } else if (result == 2) { - THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, nh); + THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, NULL); } else if (result == 3) { return vmSymbols::java_lang_ClassFormatError(); } else { ShouldNotReachHere(); - return nh; + return NULL; } } @@ -266,12 +265,19 @@ ClassVerifier::ClassVerifier( instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS) - : _thread(THREAD), _exception_type(symbolHandle()), _message(msg), + : _thread(THREAD), _exception_type(NULL), _message(msg), _message_buffer_len(msg_len), _klass(klass) { _this_type = VerificationType::reference_type(klass->name()); + // Create list to hold symbols in reference area. + _symbols = new GrowableArray(100, 0, NULL); } ClassVerifier::~ClassVerifier() { + // Decrement the reference count for any symbols created. + for (int i = 0; i < _symbols->length(); i++) { + Symbol* s = _symbols->at(i); + s->decrement_refcount(); + } } VerificationType ClassVerifier::object_type() const { @@ -308,7 +314,6 @@ } void ClassVerifier::verify_method(methodHandle m, TRAPS) { - ResourceMark rm(THREAD); _method = m; // initialize _method if (_verify_verbose) { tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string()); @@ -615,7 +620,7 @@ VerificationType::null_type(), CHECK_VERIFY(this)); } else { VerificationType component = - atype.get_component(CHECK_VERIFY(this)); + atype.get_component(this, CHECK_VERIFY(this)); current_frame.push_stack(component, CHECK_VERIFY(this)); } no_control_flow = false; break; @@ -1386,7 +1391,7 @@ VerificationType throwable = VerificationType::reference_type(vmSymbols::java_lang_Throwable()); bool is_subclass = throwable.is_assignable_from( - catch_type, current_class(), CHECK_VERIFY(this)); + catch_type, this, CHECK_VERIFY(this)); if (!is_subclass) { // 4286534: should throw VerifyError according to recent spec change verify_error( @@ -1473,8 +1478,6 @@ if(bci >= start_pc && bci < end_pc) { u1 flags = current_frame->flags(); if (this_uninit) { flags |= FLAG_THIS_UNINIT; } - - ResourceMark rm(THREAD); StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); if (catch_type_index != 0) { // We know that this index refers to a subclass of Throwable @@ -1575,7 +1578,7 @@ va_end(va); } -klassOop ClassVerifier::load_class(symbolHandle name, TRAPS) { +klassOop ClassVerifier::load_class(Symbol* name, TRAPS) { // Get current loader and protection domain first. oop loader = current_class()->class_loader(); oop protection_domain = current_class()->protection_domain(); @@ -1587,8 +1590,8 @@ bool ClassVerifier::is_protected_access(instanceKlassHandle this_class, klassOop target_class, - symbolOop field_name, - symbolOop field_sig, + Symbol* field_name, + Symbol* field_sig, bool is_method) { No_Safepoint_Verifier nosafepoint; @@ -1736,7 +1739,7 @@ } bool ClassVerifier::name_in_supers( - symbolOop ref_name, instanceKlassHandle current) { + Symbol* ref_name, instanceKlassHandle current) { klassOop super = current->super(); while (super != NULL) { if (super->klass_part()->name() == ref_name) { @@ -1755,8 +1758,8 @@ verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this)); // Get field name and signature - symbolHandle field_name = symbolHandle(THREAD, cp->name_ref_at(index)); - symbolHandle field_sig = symbolHandle(THREAD, cp->signature_ref_at(index)); + Symbol* field_name = cp->name_ref_at(index); + Symbol* field_sig = cp->signature_ref_at(index); if (!SignatureVerifier::is_valid_type_signature(field_sig)) { class_format_error( @@ -1823,11 +1826,11 @@ fieldDescriptor fd; if (stack_object_type == VerificationType::uninitialized_this_type() && target_class_type.equals(current_type()) && - _klass->find_local_field(field_name(), field_sig(), &fd)) { + _klass->find_local_field(field_name, field_sig, &fd)) { stack_object_type = current_type(); } is_assignable = target_class_type.is_assignable_from( - stack_object_type, current_class(), CHECK_VERIFY(this)); + stack_object_type, this, CHECK_VERIFY(this)); if (!is_assignable) { verify_error(bci, "Bad type on operand stack in putfield"); return; @@ -1836,9 +1839,9 @@ check_protected: { if (_this_type == stack_object_type) break; // stack_object_type must be assignable to _current_class_type - symbolHandle ref_class_name = symbolHandle(THREAD, - cp->klass_name_at(cp->klass_ref_index_at(index))); - if (!name_in_supers(ref_class_name(), current_class())) + Symbol* ref_class_name = + cp->klass_name_at(cp->klass_ref_index_at(index)); + if (!name_in_supers(ref_class_name, current_class())) // stack_object_type must be assignable to _current_class_type since: // 1. stack_object_type must be assignable to ref_class. // 2. ref_class must be _current_class or a subclass of it. It can't @@ -1846,12 +1849,12 @@ break; klassOop ref_class_oop = load_class(ref_class_name, CHECK); - if (is_protected_access(current_class(), ref_class_oop, field_name(), - field_sig(), false)) { + if (is_protected_access(current_class(), ref_class_oop, field_name, + field_sig, false)) { // It's protected access, check if stack object is assignable to // current class. is_assignable = current_type().is_assignable_from( - stack_object_type, current_class(), CHECK_VERIFY(this)); + stack_object_type, this, CHECK_VERIFY(this)); if (!is_assignable) { verify_error(bci, "Bad access to protected data in getfield"); return; @@ -1911,7 +1914,7 @@ instanceKlassHandle mh(THREAD, m->method_holder()); if (m->is_protected() && !mh->is_same_class_package(_klass())) { bool assignable = current_type().is_assignable_from( - objectref_type, current_class(), CHECK_VERIFY(this)); + objectref_type, this, CHECK_VERIFY(this)); if (!assignable) { verify_error(bci, "Bad access to protected method"); return; @@ -1941,8 +1944,8 @@ verify_cp_type(index, cp, types, CHECK_VERIFY(this)); // Get method name and signature - symbolHandle method_name(THREAD, cp->name_ref_at(index)); - symbolHandle method_sig(THREAD, cp->signature_ref_at(index)); + Symbol* method_name = cp->name_ref_at(index); + Symbol* method_sig = cp->signature_ref_at(index); if (!SignatureVerifier::is_valid_method_signature(method_sig)) { class_format_error( @@ -2035,7 +2038,7 @@ if (method_name->byte_at(0) == '<') { // Make sure can only be invoked by invokespecial if (opcode != Bytecodes::_invokespecial || - method_name() != vmSymbols::object_initializer_name()) { + method_name != vmSymbols::object_initializer_name()) { verify_error(bci, "Illegal call to internal method"); return; } @@ -2044,7 +2047,7 @@ && !ref_class_type.equals(VerificationType::reference_type( current_class()->super()->klass_part()->name()))) { bool subtype = ref_class_type.is_assignable_from( - current_type(), current_class(), CHECK_VERIFY(this)); + current_type(), this, CHECK_VERIFY(this)); if (!subtype) { verify_error(bci, "Bad invokespecial instruction: " "current class isn't assignable to reference class."); @@ -2058,7 +2061,7 @@ // Check objectref on operand stack if (opcode != Bytecodes::_invokestatic && opcode != Bytecodes::_invokedynamic) { - if (method_name() == vmSymbols::object_initializer_name()) { // method + if (method_name == vmSymbols::object_initializer_name()) { // method verify_invoke_init(bcs, ref_class_type, current_frame, code_length, this_uninit, cp, CHECK_VERIFY(this)); } else { // other methods @@ -2070,22 +2073,22 @@ current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this)); if (current_type() != stack_object_type) { assert(cp->cache() == NULL, "not rewritten yet"); - symbolHandle ref_class_name = symbolHandle(THREAD, - cp->klass_name_at(cp->klass_ref_index_at(index))); + Symbol* ref_class_name = + cp->klass_name_at(cp->klass_ref_index_at(index)); // See the comments in verify_field_instructions() for // the rationale behind this. - if (name_in_supers(ref_class_name(), current_class())) { + if (name_in_supers(ref_class_name, current_class())) { klassOop ref_class = load_class(ref_class_name, CHECK); if (is_protected_access( - _klass, ref_class, method_name(), method_sig(), true)) { + _klass, ref_class, method_name, method_sig, true)) { // It's protected access, check if stack object is // assignable to current class. bool is_assignable = current_type().is_assignable_from( - stack_object_type, current_class(), CHECK_VERIFY(this)); + stack_object_type, this, CHECK_VERIFY(this)); if (!is_assignable) { if (ref_class_type.name() == vmSymbols::java_lang_Object() && stack_object_type.is_array() - && method_name() == vmSymbols::clone_name()) { + && method_name == vmSymbols::clone_name()) { // Special case: arrays pretend to implement public Object // clone(). } else { @@ -2105,7 +2108,7 @@ } // Push the result type. if (sig_stream.type() != T_VOID) { - if (method_name() == vmSymbols::object_initializer_name()) { + if (method_name == vmSymbols::object_initializer_name()) { // method must have a void return type verify_error(bci, "Return type must be void in method"); return; @@ -2130,7 +2133,7 @@ } // from_bt[index] contains the array signature which has a length of 2 - symbolHandle sig = oopFactory::new_symbol_handle( + Symbol* sig = create_temporary_symbol( from_bt[index], 2, CHECK_(VerificationType::bogus_type())); return VerificationType::reference_type(sig); } @@ -2143,7 +2146,6 @@ VerificationType component_type = cp_index_to_type(index, cp, CHECK_VERIFY(this)); - ResourceMark rm(THREAD); int length; char* arr_sig_str; if (component_type.is_array()) { // it's an array @@ -2163,7 +2165,7 @@ strncpy(&arr_sig_str[2], component_name, length - 2); arr_sig_str[length - 1] = ';'; } - symbolHandle arr_sig = oopFactory::new_symbol_handle( + Symbol* arr_sig = create_temporary_symbol( arr_sig_str, length, CHECK_VERIFY(this)); VerificationType new_array_type = VerificationType::reference_type(arr_sig); current_frame->push_stack(new_array_type, CHECK_VERIFY(this)); @@ -2256,9 +2258,25 @@ verify_error(bci, "Method expects a return value"); return; } - bool match = return_type.is_assignable_from(type, _klass, CHECK_VERIFY(this)); + bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this)); if (!match) { verify_error(bci, "Bad return type"); return; } } + +// The verifier creates symbols which are substrings of Symbols. +// These are stored in the verifier until the end of verification so that +// they can be reference counted. +Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin, + int end, TRAPS) { + Symbol* sym = SymbolTable::new_symbol(s, begin, end, CHECK_NULL); + _symbols->push(sym); + return sym; +} + +Symbol* ClassVerifier::create_temporary_symbol(const char *s, int length, TRAPS) { + Symbol* sym = SymbolTable::new_symbol(s, length, CHECK_NULL); + _symbols->push(sym); + return sym; +} diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/verifier.hpp --- a/src/share/vm/classfile/verifier.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/verifier.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -59,7 +59,7 @@ private: static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class); - static symbolHandle inference_verify( + static Symbol* inference_verify( instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS); }; @@ -69,8 +69,8 @@ // Summary of verifier's memory usage: // StackMapTable is stack allocated. -// StackMapFrame are resource allocated. There is one ResourceMark -// for each method. +// StackMapFrame are resource allocated. There is only one ResourceMark +// for each class verification, which is created at the top level. // There is one mutable StackMapFrame (current_frame) which is updated // by abstract bytecode interpretation. frame_in_exception_handler() returns // a frame that has a mutable one-item stack (ready for pushing the @@ -80,8 +80,6 @@ // locals/stack arrays in StackMapFrame are resource allocated. // locals/stack arrays can be shared between StackMapFrame's, except // the mutable StackMapFrame (current_frame). -// Care needs to be taken to make sure resource objects don't outlive -// the lifetime of their ResourceMark. // These macros are used similarly to CHECK macros but also check // the status of the verifier and return if that has an error. @@ -94,9 +92,10 @@ class ClassVerifier : public StackObj { private: Thread* _thread; - symbolHandle _exception_type; + Symbol* _exception_type; char* _message; size_t _message_buffer_len; + GrowableArray* _symbols; // keep a list of symbols created void verify_method(methodHandle method, TRAPS); char* generate_code_data(methodHandle m, u4 code_length, TRAPS); @@ -110,7 +109,7 @@ bool is_protected_access( instanceKlassHandle this_class, klassOop target_class, - symbolOop field_name, symbolOop field_sig, bool is_method); + Symbol* field_name, Symbol* field_sig, bool is_method); void verify_cp_index(constantPoolHandle cp, int index, TRAPS); void verify_cp_type( @@ -165,7 +164,7 @@ void verify_astore(u2 index, StackMapFrame* current_frame, TRAPS); void verify_iinc (u2 index, StackMapFrame* current_frame, TRAPS); - bool name_in_supers(symbolOop ref_name, instanceKlassHandle current); + bool name_in_supers(Symbol* ref_name, instanceKlassHandle current); VerificationType object_type() const; @@ -206,8 +205,8 @@ void verify_class(TRAPS); // Return status modes - symbolHandle result() const { return _exception_type; } - bool has_error() const { return !(result().is_null()); } + Symbol* result() const { return _exception_type; } + bool has_error() const { return result() != NULL; } // Called when verify or class format errors are encountered. // May throw an exception based upon the mode. @@ -216,16 +215,22 @@ void class_format_error(const char* fmt, ...); void format_error_message(const char* fmt, int offset, va_list args); - klassOop load_class(symbolHandle name, TRAPS); + klassOop load_class(Symbol* name, TRAPS); int change_sig_to_verificationType( SignatureStream* sig_type, VerificationType* inference_type, TRAPS); VerificationType cp_index_to_type(int index, constantPoolHandle cp, TRAPS) { - return VerificationType::reference_type( - symbolHandle(THREAD, cp->klass_name_at(index))); + return VerificationType::reference_type(cp->klass_name_at(index)); } + // Keep a list of temporary symbols created during verification because + // their reference counts need to be decrememented when the verifier object + // goes out of scope. Since these symbols escape the scope in which they're + // created, we can't use a TempNewSymbol. + Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS); + Symbol* create_temporary_symbol(const char *s, int length, TRAPS); + static bool _verify_verbose; // for debugging }; @@ -236,9 +241,14 @@ case T_OBJECT: case T_ARRAY: { - symbolOop name = sig_type->as_symbol(CHECK_0); + Symbol* name = sig_type->as_symbol(CHECK_0); + // Create another symbol to save as signature stream unreferences + // this symbol. + Symbol* name_copy = + create_temporary_symbol(name, 0, name->utf8_length(), CHECK_0); + assert(name_copy == name, "symbols don't match"); *inference_type = - VerificationType::reference_type(symbolHandle(THREAD, name)); + VerificationType::reference_type(name_copy); return 1; } case T_LONG: diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/vmSymbols.cpp --- a/src/share/vm/classfile/vmSymbols.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/vmSymbols.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -30,11 +30,11 @@ #include "utilities/xmlstream.hpp" -symbolOop vmSymbols::_symbols[vmSymbols::SID_LIMIT]; +Symbol* vmSymbols::_symbols[vmSymbols::SID_LIMIT]; -symbolOop vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ }; +Symbol* vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ }; -inline int compare_symbol(symbolOop a, symbolOop b) { +inline int compare_symbol(Symbol* a, Symbol* b) { if (a == b) return 0; // follow the natural address order: return (address)a > (address)b ? +1 : -1; @@ -43,8 +43,8 @@ static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT]; extern "C" { static int compare_vmsymbol_sid(const void* void_a, const void* void_b) { - symbolOop a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a)); - symbolOop b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b)); + Symbol* a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a)); + Symbol* b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b)); return compare_symbol(a, b); } } @@ -79,7 +79,7 @@ if (!UseSharedSpaces) { const char* string = &vm_symbol_bodies[0]; for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { - symbolOop sym = oopFactory::new_symbol(string, CHECK); + Symbol* sym = SymbolTable::new_symbol(string, CHECK); _symbols[index] = sym; string += strlen(string); // skip string body string += 1; // skip trailing null @@ -100,7 +100,7 @@ #ifdef ASSERT // Check for duplicates: for (int i1 = (int)FIRST_SID; i1 < (int)SID_LIMIT; i1++) { - symbolOop sym = symbol_at((SID)i1); + Symbol* sym = symbol_at((SID)i1); for (int i2 = (int)FIRST_SID; i2 < i1; i2++) { if (symbol_at((SID)i2) == sym) { tty->print("*** Duplicate VM symbol SIDs %s(%d) and %s(%d): \"", @@ -128,16 +128,16 @@ // Spot-check correspondence between strings, symbols, and enums: assert(_symbols[NO_SID] == NULL, "must be"); const char* str = "java/lang/Object"; - symbolOop sym = oopFactory::new_symbol(str, CHECK); - assert(strcmp(str, (char*)sym->base()) == 0, ""); - assert(sym == java_lang_Object(), ""); + TempNewSymbol jlo = SymbolTable::new_symbol(str, CHECK); + assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, ""); + assert(jlo == java_lang_Object(), ""); SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object); - assert(find_sid(sym) == sid, ""); - assert(symbol_at(sid) == sym, ""); + assert(find_sid(jlo) == sid, ""); + assert(symbol_at(sid) == jlo, ""); // Make sure find_sid produces the right answer in each case. for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { - sym = symbol_at((SID)index); + Symbol* sym = symbol_at((SID)index); sid = find_sid(sym); assert(sid == (SID)index, "symbol index works"); // Note: If there are duplicates, this assert will fail. @@ -147,8 +147,8 @@ // The string "format" happens (at the moment) not to be a vmSymbol, // though it is a method name in java.lang.String. str = "format"; - sym = oopFactory::new_symbol(str, CHECK); - sid = find_sid(sym); + TempNewSymbol fmt = SymbolTable::new_symbol(str, CHECK); + sid = find_sid(fmt); assert(sid == NO_SID, "symbol index works (negative test)"); } #endif @@ -172,22 +172,23 @@ -void vmSymbols::oops_do(OopClosure* f, bool do_all) { +void vmSymbols::symbols_do(SymbolClosure* f) { for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { - f->do_oop((oop*) &_symbols[index]); + f->do_symbol(&_symbols[index]); } for (int i = 0; i < T_VOID+1; i++) { - if (_type_signatures[i] != NULL) { - assert(i >= T_BOOLEAN, "checking"); - f->do_oop((oop*)&_type_signatures[i]); - } else if (do_all) { - f->do_oop((oop*)&_type_signatures[i]); - } + f->do_symbol(&_type_signatures[i]); } } +void vmSymbols::serialize(SerializeOopClosure* soc) { + soc->do_region((u_char*)&_symbols[FIRST_SID], + (SID_LIMIT - FIRST_SID) * sizeof(_symbols[0])); + soc->do_region((u_char*)_type_signatures, sizeof(_type_signatures)); +} -BasicType vmSymbols::signature_type(symbolOop s) { + +BasicType vmSymbols::signature_type(Symbol* s) { assert(s != NULL, "checking"); for (int i = T_BOOLEAN; i < T_VOID+1; i++) { if (s == _type_signatures[i]) { @@ -205,7 +206,7 @@ // (Typical counts are calls=7000 and probes=17000.) #endif -vmSymbols::SID vmSymbols::find_sid(symbolOop symbol) { +vmSymbols::SID vmSymbols::find_sid(Symbol* symbol) { // Handle the majority of misses by a bounds check. // Then, use a binary search over the index. // Expected trip count is less than log2_SID_LIMIT, about eight. @@ -260,7 +261,7 @@ // (We have already proven that there are no duplicates in the list.) SID sid2 = NO_SID; for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { - symbolOop sym2 = symbol_at((SID)index); + Symbol* sym2 = symbol_at((SID)index); if (sym2 == symbol) { sid2 = (SID)index; break; @@ -319,9 +320,9 @@ methodOop vmIntrinsics::method_for(vmIntrinsics::ID id) { if (id == _none) return NULL; - symbolOop cname = vmSymbols::symbol_at(class_for(id)); - symbolOop mname = vmSymbols::symbol_at(name_for(id)); - symbolOop msig = vmSymbols::symbol_at(signature_for(id)); + Symbol* cname = vmSymbols::symbol_at(class_for(id)); + Symbol* mname = vmSymbols::symbol_at(name_for(id)); + Symbol* msig = vmSymbols::symbol_at(signature_for(id)); if (cname == NULL || mname == NULL || msig == NULL) return NULL; klassOop k = SystemDictionary::find_well_known_klass(cname); if (k == NULL) return NULL; @@ -490,17 +491,17 @@ #ifndef PRODUCT // verify_method performs an extra check on a matched intrinsic method -static bool match_method(methodOop m, symbolOop n, symbolOop s) { +static bool match_method(methodOop m, Symbol* n, Symbol* s) { return (m->name() == n && m->signature() == s); } -static vmIntrinsics::ID match_method_with_klass(methodOop m, symbolOop mk) { +static vmIntrinsics::ID match_method_with_klass(methodOop m, Symbol* mk) { #define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \ - { symbolOop k = vmSymbols::klassname(); \ + { Symbol* k = vmSymbols::klassname(); \ if (mk == k) { \ - symbolOop n = vmSymbols::namepart(); \ - symbolOop s = vmSymbols::sigpart(); \ + Symbol* n = vmSymbols::namepart(); \ + Symbol* s = vmSymbols::sigpart(); \ if (match_method(m, n, s)) \ return vmIntrinsics::id; \ } } @@ -511,7 +512,7 @@ } void vmIntrinsics::verify_method(ID actual_id, methodOop m) { - symbolOop mk = Klass::cast(m->method_holder())->name(); + Symbol* mk = Klass::cast(m->method_holder())->name(); ID declared_id = match_method_with_klass(m, mk); if (declared_id == actual_id) return; // success diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -25,17 +25,15 @@ #ifndef SHARE_VM_CLASSFILE_VMSYMBOLS_HPP #define SHARE_VM_CLASSFILE_VMSYMBOLS_HPP -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" +#include "memory/iterator.hpp" -// The classes vmSymbols and vmSymbolHandles are a name spaces for fast lookup of -// symbols commonly used in the VM. The first class return a symbolOop, while the -// second class returns a SymbolHandle. The underlying data structure is shared -// between the two classes. +// The class vmSymbols is a name space for fast lookup of +// symbols commonly used in the VM. // // Sample usage: // -// symbolOop obj = vmSymbols::java_lang_Object()(); -// SymbolHandle handle = vmSymbolHandles::java_lang_Object(); +// Symbol* obj = vmSymbols::java_lang_Object(); // Useful sub-macros exported by this header file: @@ -459,7 +457,7 @@ VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, do_alias) \ \ /* returned by the C1 compiler in case there's not enough memory to allocate a new symbol*/ \ - template(dummy_symbol_oop, "illegal symbol") \ + template(dummy_symbol, "illegal symbol") \ \ /* used by ClassFormatError when class name is not known yet */ \ template(unknown_class_name, "") \ @@ -938,10 +936,9 @@ // Class vmSymbols class vmSymbols: AllStatic { - friend class vmSymbolHandles; friend class vmIntrinsics; public: - // enum for figuring positions and size of array holding symbolOops + // enum for figuring positions and size of array holding Symbol*s enum SID { NO_SID = 0, @@ -963,39 +960,42 @@ private: // The symbol array - static symbolOop _symbols[]; + static Symbol* _symbols[]; // Field signatures indexed by BasicType. - static symbolOop _type_signatures[T_VOID+1]; + static Symbol* _type_signatures[T_VOID+1]; public: // Initialization static void initialize(TRAPS); // Accessing - #define VM_SYMBOL_DECLARE(name, ignore) \ - static symbolOop name() { return _symbols[VM_SYMBOL_ENUM_NAME(name)]; } + #define VM_SYMBOL_DECLARE(name, ignore) \ + static Symbol* name() { \ + return _symbols[VM_SYMBOL_ENUM_NAME(name)]; \ + } VM_SYMBOLS_DO(VM_SYMBOL_DECLARE, VM_SYMBOL_DECLARE) #undef VM_SYMBOL_DECLARE - // GC support - static void oops_do(OopClosure* f, bool do_all = false); + // Sharing support + static void symbols_do(SymbolClosure* f); + static void serialize(SerializeOopClosure* soc); - static symbolOop type_signature(BasicType t) { + static Symbol* type_signature(BasicType t) { assert((uint)t < T_VOID+1, "range check"); assert(_type_signatures[t] != NULL, "domain check"); return _type_signatures[t]; } // inverse of type_signature; returns T_OBJECT if s is not recognized - static BasicType signature_type(symbolOop s); + static BasicType signature_type(Symbol* s); - static symbolOop symbol_at(SID id) { + static Symbol* symbol_at(SID id) { assert(id >= FIRST_SID && id < SID_LIMIT, "oob"); assert(_symbols[id] != NULL, "init"); return _symbols[id]; } // Returns symbol's SID if one is assigned, else NO_SID. - static SID find_sid(symbolOop symbol); + static SID find_sid(Symbol* symbol); #ifndef PRODUCT // No need for this in the product: @@ -1003,34 +1003,6 @@ #endif //PRODUCT }; - -// Class vmSymbolHandles - -class vmSymbolHandles: AllStatic { - friend class vmIntrinsics; - friend class ciObjectFactory; - - public: - // Accessing - #define VM_SYMBOL_HANDLE_DECLARE(name, ignore) \ - static symbolHandle name() { return symbol_handle_at(vmSymbols::VM_SYMBOL_ENUM_NAME(name)); } - VM_SYMBOLS_DO(VM_SYMBOL_HANDLE_DECLARE, VM_SYMBOL_HANDLE_DECLARE) - #undef VM_SYMBOL_HANDLE_DECLARE - - static symbolHandle symbol_handle_at(vmSymbols::SID id) { - return symbolHandle(&vmSymbols::_symbols[(int)id], false); - } - - static symbolHandle type_signature(BasicType t) { - assert(vmSymbols::type_signature(t) != NULL, "domain check"); - return symbolHandle(&vmSymbols::_type_signatures[t], false); - } - // inverse of type_signature; returns T_OBJECT if s is not recognized - static BasicType signature_type(symbolHandle s) { - return vmSymbols::signature_type(s()); - } -}; - // VM Intrinsic ID's uniquely identify some very special methods class vmIntrinsics: AllStatic { friend class vmSymbols; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/code/compiledIC.cpp --- a/src/share/vm/code/compiledIC.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/code/compiledIC.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -34,7 +34,7 @@ #include "memory/oopFactory.hpp" #include "oops/methodOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/icache.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/code/dependencies.cpp --- a/src/share/vm/code/dependencies.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/code/dependencies.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -628,8 +628,8 @@ private: // optional method descriptor to check for: - symbolOop _name; - symbolOop _signature; + Symbol* _name; + Symbol* _signature; // special classes which are not allowed to be witnesses: klassOop _participants[PARTICIPANT_LIMIT+1]; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/code/nmethod.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -57,9 +57,9 @@ { \ methodOop m = (method); \ if (m != NULL) { \ - symbolOop klass_name = m->klass_name(); \ - symbolOop name = m->name(); \ - symbolOop signature = m->signature(); \ + Symbol* klass_name = m->klass_name(); \ + Symbol* name = m->name(); \ + Symbol* signature = m->signature(); \ HS_DTRACE_PROBE6(hotspot, compiled__method__unload, \ klass_name->bytes(), klass_name->utf8_length(), \ name->bytes(), name->utf8_length(), \ @@ -1865,7 +1865,7 @@ SimpleScopeDesc ssd(this, fr.pc()); Bytecode_invoke call(ssd.method(), ssd.bci()); bool has_receiver = call.has_receiver(); - symbolOop signature = call.signature(); + Symbol* signature = call.signature(); fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f); } #endif // !SHARK @@ -2636,7 +2636,7 @@ } else { bool did_name = false; if (!at_this && ss.is_object()) { - symbolOop name = ss.as_symbol_or_null(); + Symbol* name = ss.as_symbol_or_null(); if (name != NULL) { name->print_value_on(stream); did_name = true; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/compiler/compileBroker.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -66,9 +66,9 @@ #define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method) \ { \ char* comp_name = (char*)(compiler)->name(); \ - symbolOop klass_name = (method)->klass_name(); \ - symbolOop name = (method)->name(); \ - symbolOop signature = (method)->signature(); \ + Symbol* klass_name = (method)->klass_name(); \ + Symbol* name = (method)->name(); \ + Symbol* signature = (method)->signature(); \ HS_DTRACE_PROBE8(hotspot, method__compile__begin, \ comp_name, strlen(comp_name), \ klass_name->bytes(), klass_name->utf8_length(), \ @@ -79,9 +79,9 @@ #define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success) \ { \ char* comp_name = (char*)(compiler)->name(); \ - symbolOop klass_name = (method)->klass_name(); \ - symbolOop name = (method)->name(); \ - symbolOop signature = (method)->signature(); \ + Symbol* klass_name = (method)->klass_name(); \ + Symbol* name = (method)->name(); \ + Symbol* signature = (method)->signature(); \ HS_DTRACE_PROBE9(hotspot, method__compile__end, \ comp_name, strlen(comp_name), \ klass_name->bytes(), klass_name->utf8_length(), \ @@ -689,7 +689,7 @@ CompilerThread* compiler_thread = NULL; klassOop k = - SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(), + SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_0); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0); @@ -700,8 +700,8 @@ JavaValue result(T_VOID); JavaCalls::call_special(&result, thread_oop, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), thread_group, string, CHECK_0); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/compiler/compileLog.hpp --- a/src/share/vm/compiler/compileLog.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/compiler/compileLog.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -63,7 +63,7 @@ stringStream* context() { return &_context; } void name(ciSymbol* s); // name='s' - void name(symbolHandle s) { xmlStream::name(s); } + void name(Symbol* s) { xmlStream::name(s); } // Output an object description, return obj->ident(). int identify(ciObject* obj); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/compiler/compilerOracle.cpp --- a/src/share/vm/compiler/compilerOracle.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/compiler/compilerOracle.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -30,7 +30,7 @@ #include "oops/klass.hpp" #include "oops/methodOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" #include "runtime/jniHandles.hpp" @@ -46,33 +46,33 @@ }; protected: - jobject _class_name; + Symbol* _class_name; + Symbol* _method_name; + Symbol* _signature; Mode _class_mode; - jobject _method_name; Mode _method_mode; - jobject _signature; MethodMatcher* _next; - static bool match(symbolHandle candidate, symbolHandle match, Mode match_mode); + static bool match(Symbol* candidate, Symbol* match, Mode match_mode); - symbolHandle class_name() const { return (symbolOop)JNIHandles::resolve_non_null(_class_name); } - symbolHandle method_name() const { return (symbolOop)JNIHandles::resolve_non_null(_method_name); } - symbolHandle signature() const { return (symbolOop)JNIHandles::resolve(_signature); } + Symbol* class_name() const { return _class_name; } + Symbol* method_name() const { return _method_name; } + Symbol* signature() const { return _signature; } public: - MethodMatcher(symbolHandle class_name, Mode class_mode, - symbolHandle method_name, Mode method_mode, - symbolHandle signature, MethodMatcher* next); - MethodMatcher(symbolHandle class_name, symbolHandle method_name, MethodMatcher* next); + MethodMatcher(Symbol* class_name, Mode class_mode, + Symbol* method_name, Mode method_mode, + Symbol* signature, MethodMatcher* next); + MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next); // utility method MethodMatcher* find(methodHandle method) { - symbolHandle class_name = Klass::cast(method->method_holder())->name(); - symbolHandle method_name = method->name(); + Symbol* class_name = Klass::cast(method->method_holder())->name(); + Symbol* method_name = method->name(); for (MethodMatcher* current = this; current != NULL; current = current->_next) { if (match(class_name, current->class_name(), current->_class_mode) && match(method_name, current->method_name(), current->_method_mode) && - (current->signature().is_null() || current->signature()() == method->signature())) { + (current->signature() == NULL || current->signature() == method->signature())) { return current; } } @@ -85,14 +85,14 @@ MethodMatcher* next() const { return _next; } - static void print_symbol(symbolHandle h, Mode mode) { + static void print_symbol(Symbol* h, Mode mode) { ResourceMark rm; if (mode == Suffix || mode == Substring || mode == Any) { tty->print("*"); } if (mode != Any) { - h()->print_symbol_on(tty); + h->print_symbol_on(tty); } if (mode == Prefix || mode == Substring) { tty->print("*"); @@ -103,7 +103,7 @@ print_symbol(class_name(), _class_mode); tty->print("."); print_symbol(method_name(), _method_mode); - if (!signature().is_null()) { + if (signature() != NULL) { tty->print(" "); signature()->print_symbol_on(tty); } @@ -115,9 +115,9 @@ } }; -MethodMatcher::MethodMatcher(symbolHandle class_name, symbolHandle method_name, MethodMatcher* next) { - _class_name = JNIHandles::make_global(class_name); - _method_name = JNIHandles::make_global(method_name); +MethodMatcher::MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next) { + _class_name = class_name; + _method_name = method_name; _next = next; _class_mode = MethodMatcher::Exact; _method_mode = MethodMatcher::Exact; @@ -125,24 +125,24 @@ } -MethodMatcher::MethodMatcher(symbolHandle class_name, Mode class_mode, - symbolHandle method_name, Mode method_mode, - symbolHandle signature, MethodMatcher* next): +MethodMatcher::MethodMatcher(Symbol* class_name, Mode class_mode, + Symbol* method_name, Mode method_mode, + Symbol* signature, MethodMatcher* next): _class_mode(class_mode) , _method_mode(method_mode) , _next(next) - , _class_name(JNIHandles::make_global(class_name())) - , _method_name(JNIHandles::make_global(method_name())) - , _signature(JNIHandles::make_global(signature())) { + , _class_name(class_name) + , _method_name(method_name) + , _signature(signature) { } -bool MethodMatcher::match(symbolHandle candidate, symbolHandle match, Mode match_mode) { +bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) { if (match_mode == Any) { return true; } if (match_mode == Exact) { - return candidate() == match(); + return candidate == match; } ResourceMark rm; @@ -171,9 +171,9 @@ class MethodOptionMatcher: public MethodMatcher { const char * option; public: - MethodOptionMatcher(symbolHandle class_name, Mode class_mode, - symbolHandle method_name, Mode method_mode, - symbolHandle signature, const char * opt, MethodMatcher* next): + MethodOptionMatcher(Symbol* class_name, Mode class_mode, + Symbol* method_name, Mode method_mode, + Symbol* signature, const char * opt, MethodMatcher* next): MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) { option = opt; } @@ -256,9 +256,9 @@ static MethodMatcher* add_predicate(OracleCommand command, - symbolHandle class_name, MethodMatcher::Mode c_mode, - symbolHandle method_name, MethodMatcher::Mode m_mode, - symbolHandle signature) { + Symbol* class_name, MethodMatcher::Mode c_mode, + Symbol* method_name, MethodMatcher::Mode m_mode, + Symbol* signature) { assert(command != OptionCommand, "must use add_option_string"); if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL) tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged."); @@ -268,9 +268,9 @@ -static MethodMatcher* add_option_string(symbolHandle class_name, MethodMatcher::Mode c_mode, - symbolHandle method_name, MethodMatcher::Mode m_mode, - symbolHandle signature, +static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode, + Symbol* method_name, MethodMatcher::Mode m_mode, + Symbol* signature, const char* option) { lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode, signature, option, lists[OptionCommand]); @@ -497,9 +497,9 @@ if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) { EXCEPTION_MARK; - symbolHandle c_name = oopFactory::new_symbol_handle(class_name, CHECK); - symbolHandle m_name = oopFactory::new_symbol_handle(method_name, CHECK); - symbolHandle signature; + Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK); + Symbol* m_name = SymbolTable::new_symbol(method_name, CHECK); + Symbol* signature = NULL; line += bytes_read; // there might be a signature following the method. @@ -507,7 +507,7 @@ if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) { sig[0] = '('; line += bytes_read; - signature = oopFactory::new_symbol_handle(sig, CHECK); + signature = SymbolTable::new_symbol(sig, CHECK); } if (command == OptionCommand) { @@ -714,9 +714,9 @@ } EXCEPTION_MARK; - symbolHandle c_name = oopFactory::new_symbol_handle(className, CHECK); - symbolHandle m_name = oopFactory::new_symbol_handle(methodName, CHECK); - symbolHandle signature; + Symbol* c_name = SymbolTable::new_symbol(className, CHECK); + Symbol* m_name = SymbolTable::new_symbol(methodName, CHECK); + Symbol* signature = NULL; add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature); if (PrintVMOptions) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/compiler/compilerOracle.hpp --- a/src/share/vm/compiler/compilerOracle.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/compiler/compilerOracle.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,8 +31,6 @@ // CompilerOracle is an interface for turning on and off compilation // for some methods -class symbolHandle; - class CompilerOracle : AllStatic { private: static bool _quiet; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -5921,9 +5921,10 @@ { TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty); - // Now clean up stale oops in SymbolTable and StringTable - SymbolTable::unlink(&_is_alive_closure); + // Now clean up stale oops in StringTable StringTable::unlink(&_is_alive_closure); + // Clean up unreferenced symbols in symbol table. + SymbolTable::unlink(); } } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1055,7 +1055,12 @@ do { double start_vtime_sec = os::elapsedVTime(); double start_time_sec = os::elapsedTime(); - the_task->do_marking_step(10.0); + double mark_step_duration_ms = G1ConcMarkStepDurationMillis; + + the_task->do_marking_step(mark_step_duration_ms, + true /* do_stealing */, + true /* do_termination */); + double end_time_sec = os::elapsedTime(); double end_vtime_sec = os::elapsedVTime(); double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec; @@ -1111,7 +1116,8 @@ _restart_for_overflow = false; - set_phase(MAX2((size_t) 1, parallel_marking_threads()), true); + size_t active_workers = MAX2((size_t) 1, parallel_marking_threads()); + set_phase(active_workers, true /* concurrent */); CMConcurrentMarkingTask markingTask(this, cmThread()); if (parallel_marking_threads() > 0) @@ -1176,6 +1182,12 @@ /* silent */ false, /* use_prev_marking */ false); } + assert(!restart_for_overflow(), "sanity"); + } + + // Reset the marking state if marking completed + if (!restart_for_overflow()) { + set_non_marking_state(); } #if VERIFY_OBJS_PROCESSED @@ -1500,21 +1512,19 @@ size_t _max_live_bytes; size_t _regions_claimed; size_t _freed_bytes; - FreeRegionList _local_cleanup_list; - HumongousRegionSet _humongous_proxy_set; + FreeRegionList* _local_cleanup_list; + HumongousRegionSet* _humongous_proxy_set; + HRRSCleanupTask* _hrrs_cleanup_task; double _claimed_region_time; double _max_region_time; public: G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1, - int worker_num); + int worker_num, + FreeRegionList* local_cleanup_list, + HumongousRegionSet* humongous_proxy_set, + HRRSCleanupTask* hrrs_cleanup_task); size_t freed_bytes() { return _freed_bytes; } - FreeRegionList* local_cleanup_list() { - return &_local_cleanup_list; - } - HumongousRegionSet* humongous_proxy_set() { - return &_humongous_proxy_set; - } bool doHeapRegion(HeapRegion *r); @@ -1541,7 +1551,12 @@ void work(int i) { double start = os::elapsedTime(); - G1NoteEndOfConcMarkClosure g1_note_end(_g1h, i); + FreeRegionList local_cleanup_list("Local Cleanup List"); + HumongousRegionSet humongous_proxy_set("Local Cleanup Humongous Proxy Set"); + HRRSCleanupTask hrrs_cleanup_task; + G1NoteEndOfConcMarkClosure g1_note_end(_g1h, i, &local_cleanup_list, + &humongous_proxy_set, + &hrrs_cleanup_task); if (G1CollectedHeap::use_parallel_gc_threads()) { _g1h->heap_region_par_iterate_chunked(&g1_note_end, i, HeapRegion::NoteEndClaimValue); @@ -1553,15 +1568,17 @@ // Now update the lists _g1h->update_sets_after_freeing_regions(g1_note_end.freed_bytes(), NULL /* free_list */, - g1_note_end.humongous_proxy_set(), + &humongous_proxy_set, true /* par */); { MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); _max_live_bytes += g1_note_end.max_live_bytes(); _freed_bytes += g1_note_end.freed_bytes(); - _cleanup_list->add_as_tail(g1_note_end.local_cleanup_list()); - assert(g1_note_end.local_cleanup_list()->is_empty(), "post-condition"); + _cleanup_list->add_as_tail(&local_cleanup_list); + assert(local_cleanup_list.is_empty(), "post-condition"); + + HeapRegionRemSet::finish_cleanup_task(&hrrs_cleanup_task); } double end = os::elapsedTime(); if (G1PrintParCleanupStats) { @@ -1602,13 +1619,17 @@ G1NoteEndOfConcMarkClosure:: G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1, - int worker_num) + int worker_num, + FreeRegionList* local_cleanup_list, + HumongousRegionSet* humongous_proxy_set, + HRRSCleanupTask* hrrs_cleanup_task) : _g1(g1), _worker_num(worker_num), _max_live_bytes(0), _regions_claimed(0), _freed_bytes(0), _claimed_region_time(0.0), _max_region_time(0.0), - _local_cleanup_list("Local Cleanup List"), - _humongous_proxy_set("Local Cleanup Humongous Proxy Set") { } + _local_cleanup_list(local_cleanup_list), + _humongous_proxy_set(humongous_proxy_set), + _hrrs_cleanup_task(hrrs_cleanup_task) { } bool G1NoteEndOfConcMarkClosure::doHeapRegion(HeapRegion *hr) { // We use a claim value of zero here because all regions @@ -1619,11 +1640,12 @@ _regions_claimed++; hr->note_end_of_marking(); _max_live_bytes += hr->max_live_bytes(); - _g1->free_region_if_totally_empty(hr, - &_freed_bytes, - &_local_cleanup_list, - &_humongous_proxy_set, - true /* par */); + _g1->free_region_if_empty(hr, + &_freed_bytes, + _local_cleanup_list, + _humongous_proxy_set, + _hrrs_cleanup_task, + true /* par */); double region_time = (os::elapsedTime() - start); _claimed_region_time += region_time; if (region_time > _max_region_time) _max_region_time = region_time; @@ -1659,6 +1681,8 @@ double start = os::elapsedTime(); + HeapRegionRemSet::reset_for_cleanup_tasks(); + // Do counting once more with the world stopped for good measure. G1ParFinalCountTask g1_par_count_task(g1h, nextMarkBitMap(), &_region_bm, &_card_bm); @@ -1853,6 +1877,8 @@ assert(local_free_list.is_empty(), "post-condition"); } +// Support closures for reference procssing in G1 + bool G1CMIsAliveClosure::do_object_b(oop obj) { HeapWord* addr = (HeapWord*)obj; return addr != NULL && @@ -1873,11 +1899,17 @@ virtual void do_oop( oop* p) { do_oop_work(p); } template void do_oop_work(T* p) { - oop thisOop = oopDesc::load_decode_heap_oop(p); - HeapWord* addr = (HeapWord*)thisOop; - if (_g1->is_in_g1_reserved(addr) && _g1->is_obj_ill(thisOop)) { + oop obj = oopDesc::load_decode_heap_oop(p); + HeapWord* addr = (HeapWord*)obj; + + if (_cm->verbose_high()) + gclog_or_tty->print_cr("\t[0] we're looking at location " + "*"PTR_FORMAT" = "PTR_FORMAT, + p, (void*) obj); + + if (_g1->is_in_g1_reserved(addr) && _g1->is_obj_ill(obj)) { _bitMap->mark(addr); - _cm->mark_stack_push(thisOop); + _cm->mark_stack_push(obj); } } }; @@ -1899,6 +1931,199 @@ } }; +// 'Keep Alive' closure used by parallel reference processing. +// An instance of this closure is used in the parallel reference processing +// code rather than an instance of G1CMKeepAliveClosure. We could have used +// the G1CMKeepAliveClosure as it is MT-safe. Also reference objects are +// placed on to discovered ref lists once so we can mark and push with no +// need to check whether the object has already been marked. Using the +// G1CMKeepAliveClosure would mean, however, having all the worker threads +// operating on the global mark stack. This means that an individual +// worker would be doing lock-free pushes while it processes its own +// discovered ref list followed by drain call. If the discovered ref lists +// are unbalanced then this could cause interference with the other +// workers. Using a CMTask (and its embedded local data structures) +// avoids that potential interference. +class G1CMParKeepAliveAndDrainClosure: public OopClosure { + ConcurrentMark* _cm; + CMTask* _task; + CMBitMap* _bitMap; + int _ref_counter_limit; + int _ref_counter; + public: + G1CMParKeepAliveAndDrainClosure(ConcurrentMark* cm, + CMTask* task, + CMBitMap* bitMap) : + _cm(cm), _task(task), _bitMap(bitMap), + _ref_counter_limit(G1RefProcDrainInterval) + { + assert(_ref_counter_limit > 0, "sanity"); + _ref_counter = _ref_counter_limit; + } + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop( oop* p) { do_oop_work(p); } + + template void do_oop_work(T* p) { + if (!_cm->has_overflown()) { + oop obj = oopDesc::load_decode_heap_oop(p); + if (_cm->verbose_high()) + gclog_or_tty->print_cr("\t[%d] we're looking at location " + "*"PTR_FORMAT" = "PTR_FORMAT, + _task->task_id(), p, (void*) obj); + + _task->deal_with_reference(obj); + _ref_counter--; + + if (_ref_counter == 0) { + // We have dealt with _ref_counter_limit references, pushing them and objects + // reachable from them on to the local stack (and possibly the global stack). + // Call do_marking_step() to process these entries. We call the routine in a + // loop, which we'll exit if there's nothing more to do (i.e. we're done + // with the entries that we've pushed as a result of the deal_with_reference + // calls above) or we overflow. + // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() flag + // while there may still be some work to do. (See the comment at the + // beginning of CMTask::do_marking_step() for those conditions - one of which + // is reaching the specified time target.) It is only when + // CMTask::do_marking_step() returns without setting the has_aborted() flag + // that the marking has completed. + do { + double mark_step_duration_ms = G1ConcMarkStepDurationMillis; + _task->do_marking_step(mark_step_duration_ms, + false /* do_stealing */, + false /* do_termination */); + } while (_task->has_aborted() && !_cm->has_overflown()); + _ref_counter = _ref_counter_limit; + } + } else { + if (_cm->verbose_high()) + gclog_or_tty->print_cr("\t[%d] CM Overflow", _task->task_id()); + } + } +}; + +class G1CMParDrainMarkingStackClosure: public VoidClosure { + ConcurrentMark* _cm; + CMTask* _task; + public: + G1CMParDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task) : + _cm(cm), _task(task) + {} + + void do_void() { + do { + if (_cm->verbose_high()) + gclog_or_tty->print_cr("\t[%d] Drain: Calling do marking_step", _task->task_id()); + + // We call CMTask::do_marking_step() to completely drain the local and + // global marking stacks. The routine is called in a loop, which we'll + // exit if there's nothing more to do (i.e. we'completely drained the + // entries that were pushed as a result of applying the + // G1CMParKeepAliveAndDrainClosure to the entries on the discovered ref + // lists above) or we overflow the global marking stack. + // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() flag + // while there may still be some work to do. (See the comment at the + // beginning of CMTask::do_marking_step() for those conditions - one of which + // is reaching the specified time target.) It is only when + // CMTask::do_marking_step() returns without setting the has_aborted() flag + // that the marking has completed. + + _task->do_marking_step(1000000000.0 /* something very large */, + true /* do_stealing */, + true /* do_termination */); + } while (_task->has_aborted() && !_cm->has_overflown()); + } +}; + +// Implementation of AbstractRefProcTaskExecutor for G1 +class G1RefProcTaskExecutor: public AbstractRefProcTaskExecutor { +private: + G1CollectedHeap* _g1h; + ConcurrentMark* _cm; + CMBitMap* _bitmap; + WorkGang* _workers; + int _active_workers; + +public: + G1RefProcTaskExecutor(G1CollectedHeap* g1h, + ConcurrentMark* cm, + CMBitMap* bitmap, + WorkGang* workers, + int n_workers) : + _g1h(g1h), _cm(cm), _bitmap(bitmap), + _workers(workers), _active_workers(n_workers) + { } + + // Executes the given task using concurrent marking worker threads. + virtual void execute(ProcessTask& task); + virtual void execute(EnqueueTask& task); +}; + +class G1RefProcTaskProxy: public AbstractGangTask { + typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; + ProcessTask& _proc_task; + G1CollectedHeap* _g1h; + ConcurrentMark* _cm; + CMBitMap* _bitmap; + +public: + G1RefProcTaskProxy(ProcessTask& proc_task, + G1CollectedHeap* g1h, + ConcurrentMark* cm, + CMBitMap* bitmap) : + AbstractGangTask("Process reference objects in parallel"), + _proc_task(proc_task), _g1h(g1h), _cm(cm), _bitmap(bitmap) + {} + + virtual void work(int i) { + CMTask* marking_task = _cm->task(i); + G1CMIsAliveClosure g1_is_alive(_g1h); + G1CMParKeepAliveAndDrainClosure g1_par_keep_alive(_cm, marking_task, _bitmap); + G1CMParDrainMarkingStackClosure g1_par_drain(_cm, marking_task); + + _proc_task.work(i, g1_is_alive, g1_par_keep_alive, g1_par_drain); + } +}; + +void G1RefProcTaskExecutor::execute(ProcessTask& proc_task) { + assert(_workers != NULL, "Need parallel worker threads."); + + G1RefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm, _bitmap); + + // We need to reset the phase for each task execution so that + // the termination protocol of CMTask::do_marking_step works. + _cm->set_phase(_active_workers, false /* concurrent */); + _g1h->set_par_threads(_active_workers); + _workers->run_task(&proc_task_proxy); + _g1h->set_par_threads(0); +} + +class G1RefEnqueueTaskProxy: public AbstractGangTask { + typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; + EnqueueTask& _enq_task; + +public: + G1RefEnqueueTaskProxy(EnqueueTask& enq_task) : + AbstractGangTask("Enqueue reference objects in parallel"), + _enq_task(enq_task) + { } + + virtual void work(int i) { + _enq_task.work(i); + } +}; + +void G1RefProcTaskExecutor::execute(EnqueueTask& enq_task) { + assert(_workers != NULL, "Need parallel worker threads."); + + G1RefEnqueueTaskProxy enq_task_proxy(enq_task); + + _g1h->set_par_threads(_active_workers); + _workers->run_task(&enq_task_proxy); + _g1h->set_par_threads(0); +} + void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { ResourceMark rm; HandleMark hm; @@ -1917,24 +2142,59 @@ G1CMDrainMarkingStackClosure g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive); - // XXXYYY Also: copy the parallel ref processing code from CMS. - rp->process_discovered_references(&g1_is_alive, - &g1_keep_alive, - &g1_drain_mark_stack, - NULL); + // We use the work gang from the G1CollectedHeap and we utilize all + // the worker threads. + int active_workers = MAX2(MIN2(g1h->workers()->total_workers(), (int)_max_task_num), 1); + + G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(), + g1h->workers(), active_workers); + + if (rp->processing_is_mt()) { + // Set the degree of MT here. If the discovery is done MT, there + // may have been a different number of threads doing the discovery + // and a different number of discovered lists may have Ref objects. + // That is OK as long as the Reference lists are balanced (see + // balance_all_queues() and balance_queues()). + rp->set_mt_degree(active_workers); + + rp->process_discovered_references(&g1_is_alive, + &g1_keep_alive, + &g1_drain_mark_stack, + &par_task_executor); + + // The work routines of the parallel keep_alive and drain_marking_stack + // will set the has_overflown flag if we overflow the global marking + // stack. + } else { + rp->process_discovered_references(&g1_is_alive, + &g1_keep_alive, + &g1_drain_mark_stack, + NULL); + + } + assert(_markStack.overflow() || _markStack.isEmpty(), - "mark stack should be empty (unless it overflowed)"); + "mark stack should be empty (unless it overflowed)"); if (_markStack.overflow()) { + // Should have been done already when we tried to push an + // entry on to the global mark stack. But let's do it again. set_has_overflown(); } - rp->enqueue_discovered_references(); + if (rp->processing_is_mt()) { + assert(rp->num_q() == active_workers, "why not"); + rp->enqueue_discovered_references(&par_task_executor); + } else { + rp->enqueue_discovered_references(); + } + rp->verify_no_references_recorded(); assert(!rp->discovery_enabled(), "should have been disabled"); - // Now clean up stale oops in SymbolTable and StringTable - SymbolTable::unlink(&g1_is_alive); + // Now clean up stale oops in StringTable StringTable::unlink(&g1_is_alive); + // Clean up unreferenced symbols in symbol table. + SymbolTable::unlink(); } void ConcurrentMark::swapMarkBitMaps() { @@ -1955,7 +2215,9 @@ CMTask* task = _cm->task(worker_i); task->record_start_time(); do { - task->do_marking_step(1000000000.0 /* something very large */); + task->do_marking_step(1000000000.0 /* something very large */, + true /* do_stealing */, + true /* do_termination */); } while (task->has_aborted() && !_cm->has_overflown()); // If we overflow, then we do not want to restart. We instead // want to abort remark and do concurrent marking again. @@ -1978,7 +2240,7 @@ G1CollectedHeap::StrongRootsScope srs(g1h); // this is remark, so we'll use up all available threads int active_workers = ParallelGCThreads; - set_phase(active_workers, false); + set_phase(active_workers, false /* concurrent */); CMRemarkTask remarkTask(this); // We will start all available threads, even if we decide that the @@ -1992,7 +2254,7 @@ G1CollectedHeap::StrongRootsScope srs(g1h); // this is remark, so we'll use up all available threads int active_workers = 1; - set_phase(active_workers, false); + set_phase(active_workers, false /* concurrent */); CMRemarkTask remarkTask(this); // We will start all available threads, even if we decide that the @@ -2005,9 +2267,6 @@ print_stats(); - if (!restart_for_overflow()) - set_non_marking_state(); - #if VERIFY_OBJS_PROCESSED if (_scan_obj_cl.objs_processed != ThreadLocalObjQueue::objs_enqueued) { gclog_or_tty->print_cr("Processed = %d, enqueued = %d.", @@ -3124,7 +3383,7 @@ // do nothing } #else // _CHECK_BOTH_FINGERS_ - // we will only check the global finger + // we will only check the global finger if (objAddr < global_finger) { // see long comment above @@ -3249,7 +3508,7 @@ double elapsed_time_ms = curr_time_ms - _start_time_ms; if (elapsed_time_ms > _time_target_ms) { set_has_aborted(); - _has_aborted_timed_out = true; + _has_timed_out = true; statsOnly( ++_aborted_timed_out ); return; } @@ -3754,7 +4013,9 @@ *****************************************************************************/ -void CMTask::do_marking_step(double time_target_ms) { +void CMTask::do_marking_step(double time_target_ms, + bool do_stealing, + bool do_termination) { assert(time_target_ms >= 1.0, "minimum granularity is 1ms"); assert(concurrent() == _cm->concurrent(), "they should be the same"); @@ -3794,7 +4055,7 @@ // clear all flags clear_has_aborted(); - _has_aborted_timed_out = false; + _has_timed_out = false; _draining_satb_buffers = false; ++_calls; @@ -3970,7 +4231,7 @@ drain_global_stack(false); // Attempt at work stealing from other task's queues. - if (!has_aborted()) { + if (do_stealing && !has_aborted()) { // We have not aborted. This means that we have finished all that // we could. Let's try to do some stealing... @@ -4011,7 +4272,7 @@ // We still haven't aborted. Now, let's try to get into the // termination protocol. - if (!has_aborted()) { + if (do_termination && !has_aborted()) { // We cannot check whether the global stack is empty, since other // tasks might be concurrently pushing objects on it. We also cannot // check if the region stack is empty because if a thread is aborting @@ -4087,7 +4348,7 @@ statsOnly( ++_aborted ); - if (_has_aborted_timed_out) { + if (_has_timed_out) { double diff_ms = elapsed_time_ms - _time_target_ms; // Keep statistics of how well we did with respect to hitting // our target only if we actually timed out (if we aborted for diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/concurrentMark.hpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -353,6 +353,10 @@ friend class CMConcurrentMarkingTask; friend class G1ParNoteEndTask; friend class CalcLiveObjectsClosure; + friend class G1RefProcTaskProxy; + friend class G1RefProcTaskExecutor; + friend class G1CMParKeepAliveAndDrainClosure; + friend class G1CMParDrainMarkingStackClosure; protected: ConcurrentMarkThread* _cmThread; // the thread doing the work @@ -936,7 +940,7 @@ // if this is true, then the task has aborted for some reason bool _has_aborted; // set when the task aborts because it has met its time quota - bool _has_aborted_timed_out; + bool _has_timed_out; // true when we're draining SATB buffers; this avoids the task // aborting due to SATB buffers being available (as we're already // dealing with them) @@ -1041,7 +1045,7 @@ // trying not to exceed the given duration. However, it might exit // prematurely, according to some conditions (i.e. SATB buffers are // available for processing). - void do_marking_step(double target_ms); + void do_marking_step(double target_ms, bool do_stealing, bool do_termination); // These two calls start and stop the timer void record_start_time() { @@ -1063,7 +1067,8 @@ bool has_aborted() { return _has_aborted; } void set_has_aborted() { _has_aborted = true; } void clear_has_aborted() { _has_aborted = false; } - bool claimed() { return _claimed; } + bool has_timed_out() { return _has_timed_out; } + bool claimed() { return _claimed; } // Support routines for the partially scanned region that may be // recorded as a result of aborting while draining the CMRegionStack diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -251,7 +251,9 @@ // Now do the remainder of the cleanup operation. _cm->completeCleanup(); + _sts.join(); g1_policy->record_concurrent_mark_cleanup_completed(); + _sts.leave(); double cleanup_end_sec = os::elapsedTime(); if (PrintGC) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -4925,10 +4925,11 @@ COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); } -void G1CollectedHeap::free_region_if_totally_empty(HeapRegion* hr, +void G1CollectedHeap::free_region_if_empty(HeapRegion* hr, size_t* pre_used, FreeRegionList* free_list, HumongousRegionSet* humongous_proxy_set, + HRRSCleanupTask* hrrs_cleanup_task, bool par) { if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young()) { if (hr->isHumongous()) { @@ -4937,6 +4938,8 @@ } else { free_region(hr, pre_used, free_list, par); } + } else { + hr->rem_set()->do_cleanup_work(hrrs_cleanup_task); } } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -40,6 +40,7 @@ class HeapRegion; class HeapRegionSeq; +class HRRSCleanupTask; class PermanentGenerationSpec; class GenerationSpec; class OopsInHeapRegionClosure; @@ -1099,11 +1100,12 @@ // all dead. It calls either free_region() or // free_humongous_region() depending on the type of the region that // is passed to it. - void free_region_if_totally_empty(HeapRegion* hr, - size_t* pre_used, - FreeRegionList* free_list, - HumongousRegionSet* humongous_proxy_set, - bool par); + void free_region_if_empty(HeapRegion* hr, + size_t* pre_used, + FreeRegionList* free_list, + HumongousRegionSet* humongous_proxy_set, + HRRSCleanupTask* hrrs_cleanup_task, + bool par); // It appends the free list to the master free list and updates the // master humongous list according to the contents of the proxy diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/g1MarkSweep.cpp --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -172,9 +172,10 @@ assert(GenMarkSweep::_marking_stack.is_empty(), "just drained"); - // Visit symbol and interned string tables and delete unmarked oops - SymbolTable::unlink(&GenMarkSweep::is_alive); + // Visit interned string tables and delete unmarked oops StringTable::unlink(&GenMarkSweep::is_alive); + // Clean up unreferenced symbols in symbol table. + SymbolTable::unlink(); assert(GenMarkSweep::_marking_stack.is_empty(), "stack should be empty by now"); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/g1_globals.hpp --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -81,6 +81,14 @@ product(intx, G1MarkRegionStackSize, 1024 * 1024, \ "Size of the region stack for concurrent marking.") \ \ + product(double, G1ConcMarkStepDurationMillis, 10.0, \ + "Target duration of individual concurrent marking steps " \ + "in milliseconds.") \ + \ + product(intx, G1RefProcDrainInterval, 10, \ + "The number of discovered reference objects to process before " \ + "draining concurrent marking work queues.") \ + \ develop(bool, G1SATBBarrierPrintNullPreVals, false, \ "If true, count frac of ptr writes with null pre-vals.") \ \ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -463,7 +463,6 @@ } static void par_contract_all(); - }; void PosParPRT::par_contract_all() { @@ -1070,6 +1069,11 @@ } +void +OtherRegionsTable::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) { + _sparse_table.do_cleanup_work(hrrs_cleanup_task); +} + // Determines how many threads can add records to an rset in parallel. // This can be done by either mutator threads together with the // concurrent refinement threads or GC threads. @@ -1384,6 +1388,19 @@ } } +void HeapRegionRemSet::reset_for_cleanup_tasks() { + SparsePRT::reset_for_cleanup_tasks(); +} + +void HeapRegionRemSet::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) { + _other_regions.do_cleanup_work(hrrs_cleanup_task); +} + +void +HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) { + SparsePRT::finish_cleanup_task(hrrs_cleanup_task); +} + #ifndef PRODUCT void HeapRegionRemSet::test() { os::sleep(Thread::current(), (jlong)5000, false); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,10 @@ class PosParPRT; class SparsePRT; +// Essentially a wrapper around SparsePRTCleanupTask. See +// sparsePRT.hpp for more details. +class HRRSCleanupTask : public SparsePRTCleanupTask { +}; // The "_coarse_map" is a bitmap with one bit for each region, where set // bits indicate that the corresponding region may contain some pointer @@ -156,6 +160,8 @@ // "from_hr" is being cleared; remove any entries from it. void clear_incoming_entry(HeapRegion* from_hr); + void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task); + // Declare the heap size (in # of regions) to the OtherRegionsTable. // (Uses it to initialize from_card_cache). static void init_from_card_cache(size_t max_regions); @@ -165,10 +171,8 @@ static void shrink_from_card_cache(size_t new_n_regs); static void print_from_card_cache(); - }; - class HeapRegionRemSet : public CHeapObj { friend class VMStructs; friend class HeapRegionRemSetIterator; @@ -342,11 +346,16 @@ static void print_recorded(); static void record_event(Event evnt); + // These are wrappers for the similarly-named methods on + // SparsePRT. Look at sparsePRT.hpp for more details. + static void reset_for_cleanup_tasks(); + void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task); + static void finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task); + // Run unit tests. #ifndef PRODUCT static void test(); #endif - }; class HeapRegionRemSetIterator : public CHeapObj { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/heapRegionSeq.cpp --- a/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -195,10 +195,10 @@ assert(0 <= res && res < _regions.length(), err_msg("res: %d should be valid", res)); _alloc_search_start = res + (int) num; + assert(0 < _alloc_search_start && _alloc_search_start <= _regions.length(), + err_msg("_alloc_search_start: %d should be valid", + _alloc_search_start)); } - assert(0 < _alloc_search_start && _alloc_search_start <= _regions.length(), - err_msg("_alloc_search_start: %d should be valid", - _alloc_search_start)); return res; } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/sparsePRT.cpp --- a/src/share/vm/gc_implementation/g1/sparsePRT.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/sparsePRT.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -415,6 +415,38 @@ return NULL; } +void SparsePRT::reset_for_cleanup_tasks() { + _head_expanded_list = NULL; +} + +void SparsePRT::do_cleanup_work(SparsePRTCleanupTask* sprt_cleanup_task) { + if (should_be_on_expanded_list()) { + sprt_cleanup_task->add(this); + } +} + +void SparsePRT::finish_cleanup_task(SparsePRTCleanupTask* sprt_cleanup_task) { + assert(ParGCRareEvent_lock->owned_by_self(), "pre-condition"); + SparsePRT* head = sprt_cleanup_task->head(); + SparsePRT* tail = sprt_cleanup_task->tail(); + if (head != NULL) { + assert(tail != NULL, "if head is not NULL, so should tail"); + + tail->set_next_expanded(_head_expanded_list); + _head_expanded_list = head; + } else { + assert(tail == NULL, "if head is NULL, so should tail"); + } +} + +bool SparsePRT::should_be_on_expanded_list() { + if (_expanded) { + assert(_cur != _next, "if _expanded is true, cur should be != _next"); + } else { + assert(_cur == _next, "if _expanded is false, cur should be == _next"); + } + return expanded(); +} void SparsePRT::cleanup_all() { // First clean up all expanded tables so they agree on next and cur. @@ -484,6 +516,7 @@ _cur->clear(); } _next = _cur; + _expanded = false; } void SparsePRT::cleanup() { @@ -518,3 +551,15 @@ } add_to_expanded_list(this); } + +void SparsePRTCleanupTask::add(SparsePRT* sprt) { + assert(sprt->should_be_on_expanded_list(), "pre-condition"); + + sprt->set_next_expanded(NULL); + if (_tail != NULL) { + _tail->set_next_expanded(sprt); + } else { + _head = sprt; + } + _tail = sprt; +} diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/g1/sparsePRT.hpp --- a/src/share/vm/gc_implementation/g1/sparsePRT.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/g1/sparsePRT.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -212,8 +212,11 @@ // mutex. class SparsePRTIter; +class SparsePRTCleanupTask; class SparsePRT VALUE_OBJ_CLASS_SPEC { + friend class SparsePRTCleanupTask; + // Iterations are done on the _cur hash table, since they only need to // see entries visible at the start of a collection pause. // All other operations are done using the _next hash table. @@ -238,6 +241,8 @@ SparsePRT* next_expanded() { return _next_expanded; } void set_next_expanded(SparsePRT* nxt) { _next_expanded = nxt; } + bool should_be_on_expanded_list(); + static SparsePRT* _head_expanded_list; public: @@ -284,12 +289,36 @@ static void add_to_expanded_list(SparsePRT* sprt); static SparsePRT* get_from_expanded_list(); + // The purpose of these three methods is to help the GC workers + // during the cleanup pause to recreate the expanded list, purging + // any tables from it that belong to regions that are freed during + // cleanup (if we don't purge those tables, there is a race that + // causes various crashes; see CR 7014261). + // + // We chose to recreate the expanded list, instead of purging + // entries from it by iterating over it, to avoid this serial phase + // at the end of the cleanup pause. + // + // The three methods below work as follows: + // * reset_for_cleanup_tasks() : Nulls the expanded list head at the + // start of the cleanup pause. + // * do_cleanup_work() : Called by the cleanup workers for every + // region that is not free / is being freed by the cleanup + // pause. It creates a list of expanded tables whose head / tail + // are on the thread-local SparsePRTCleanupTask object. + // * finish_cleanup_task() : Called by the cleanup workers after + // they complete their cleanup task. It adds the local list into + // the global expanded list. It assumes that the + // ParGCRareEvent_lock is being held to ensure MT-safety. + static void reset_for_cleanup_tasks(); + void do_cleanup_work(SparsePRTCleanupTask* sprt_cleanup_task); + static void finish_cleanup_task(SparsePRTCleanupTask* sprt_cleanup_task); + bool contains_card(RegionIdx_t region_id, CardIdx_t card_index) const { return _next->contains_card(region_id, card_index); } }; - class SparsePRTIter: public RSHashTableIter { public: void init(const SparsePRT* sprt) { @@ -300,4 +329,22 @@ } }; +// This allows each worker during a cleanup pause to create a +// thread-local list of sparse tables that have been expanded and need +// to be processed at the beginning of the next GC pause. This lists +// are concatenated into the single expanded list at the end of the +// cleanup pause. +class SparsePRTCleanupTask VALUE_OBJ_CLASS_SPEC { +private: + SparsePRT* _head; + SparsePRT* _tail; + +public: + SparsePRTCleanupTask() : _head(NULL), _tail(NULL) { } + + void add(SparsePRT* sprt); + SparsePRT* head() { return _head; } + SparsePRT* tail() { return _tail; } +}; + #endif // SHARE_VM_GC_IMPLEMENTATION_G1_SPARSEPRT_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -116,10 +116,6 @@ SystemDictionary::always_strong_oops_do(&mark_and_push_closure); break; - case vm_symbols: - vmSymbols::oops_do(&mark_and_push_closure); - break; - case code_cache: // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure)); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -98,9 +98,8 @@ management = 6, jvmti = 7, system_dictionary = 8, - vm_symbols = 9, - reference_processing = 10, - code_cache = 11 + reference_processing = 9, + code_cache = 10 }; private: RootType _root_type; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -527,7 +527,6 @@ Management::oops_do(mark_and_push_closure()); JvmtiExport::oops_do(mark_and_push_closure()); SystemDictionary::always_strong_oops_do(mark_and_push_closure()); - vmSymbols::oops_do(mark_and_push_closure()); // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure())); } @@ -558,9 +557,10 @@ follow_mdo_weak_refs(); assert(_marking_stack.is_empty(), "just drained"); - // Visit symbol and interned string tables and delete unmarked oops - SymbolTable::unlink(is_alive_closure()); + // Visit interned string tables and delete unmarked oops StringTable::unlink(is_alive_closure()); + // Clean up unreferenced symbols in symbol table. + SymbolTable::unlink(); assert(_marking_stack.is_empty(), "stack should be empty by now"); } @@ -634,7 +634,6 @@ JvmtiExport::oops_do(adjust_root_pointer_closure()); // SO_AllClasses SystemDictionary::oops_do(adjust_root_pointer_closure()); - vmSymbols::oops_do(adjust_root_pointer_closure()); //CodeCache::scavenge_root_nmethods_oops_do(adjust_root_pointer_closure()); // Now adjust pointers in remaining weak roots. (All of which should @@ -643,7 +642,6 @@ JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure()); CodeCache::oops_do(adjust_pointer_closure()); - SymbolTable::oops_do(adjust_root_pointer_closure()); StringTable::oops_do(adjust_root_pointer_closure()); ref_processor()->weak_oops_do(adjust_root_pointer_closure()); PSScavenge::reference_processor()->weak_oops_do(adjust_root_pointer_closure()); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -2375,7 +2375,6 @@ q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management)); q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary)); q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti)); - q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::vm_symbols)); q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache)); if (parallel_gc_threads > 1) { @@ -2425,9 +2424,10 @@ // Revisit memoized MDO's and clear any unmarked weak refs follow_mdo_weak_refs(); - // Visit symbol and interned string tables and delete unmarked oops - SymbolTable::unlink(is_alive_closure()); + // Visit interned string tables and delete unmarked oops StringTable::unlink(is_alive_closure()); + // Clean up unreferenced symbols in symbol table. + SymbolTable::unlink(); assert(cm->marking_stacks_empty(), "marking stacks should be empty"); } @@ -2456,7 +2456,6 @@ JvmtiExport::oops_do(adjust_root_pointer_closure()); // SO_AllClasses SystemDictionary::oops_do(adjust_root_pointer_closure()); - vmSymbols::oops_do(adjust_root_pointer_closure()); // Now adjust pointers in remaining weak roots. (All of which should // have been cleared if they pointed to non-surviving objects.) @@ -2464,7 +2463,6 @@ JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure()); CodeCache::oops_do(adjust_pointer_closure()); - SymbolTable::oops_do(adjust_root_pointer_closure()); StringTable::oops_do(adjust_root_pointer_closure()); ref_processor()->weak_oops_do(adjust_root_pointer_closure()); // Roots were visited so references into the young gen in roots diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/shared/concurrentGCThread.cpp --- a/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -187,7 +187,7 @@ SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) { klassOop k = - SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(), + SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); @@ -200,8 +200,8 @@ JavaValue result(T_VOID); JavaCalls::call_special(&result, thread_oop, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), thread_group, string, CHECK_NULL); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/gc_implementation/shared/markSweep.cpp --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -111,7 +111,7 @@ MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure; -void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); } +void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { assert(*p == NULL || (*p)->is_oop(), ""); mark_and_push(p); } void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); } void MarkSweep::follow_stack() { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/interpreter/bytecode.cpp --- a/src/share/vm/interpreter/bytecode.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/interpreter/bytecode.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -124,21 +124,20 @@ } -symbolOop Bytecode_member_ref::signature() const { +Symbol* Bytecode_member_ref::signature() const { constantPoolOop constants = method()->constants(); return constants->signature_ref_at(index()); } -symbolOop Bytecode_member_ref::name() const { +Symbol* Bytecode_member_ref::name() const { constantPoolOop constants = method()->constants(); return constants->name_ref_at(index()); } -BasicType Bytecode_member_ref::result_type(Thread *thread) const { - symbolHandle sh(thread, signature()); - ResultTypeFinder rts(sh); +BasicType Bytecode_member_ref::result_type() const { + ResultTypeFinder rts(signature()); rts.iterate(); return rts.type(); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/interpreter/bytecode.hpp --- a/src/share/vm/interpreter/bytecode.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/interpreter/bytecode.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -193,10 +193,10 @@ public: int index() const; // cache index (loaded from instruction) int pool_index() const; // constant pool index - symbolOop name() const; // returns the name of the method or field - symbolOop signature() const; // returns the signature of the method or field + Symbol* name() const; // returns the name of the method or field + Symbol* signature() const; // returns the signature of the method or field - BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke + BasicType result_type() const; // returns the result type of the getfield or invoke }; // Abstraction for invoke_{virtual, static, interface, special} diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/interpreter/bytecodeTracer.cpp --- a/src/share/vm/interpreter/bytecodeTracer.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/interpreter/bytecodeTracer.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -188,7 +188,7 @@ _closure->trace(method, bcp, st); } -void print_symbol(symbolOop sym, outputStream* st) { +void print_symbol(Symbol* sym, outputStream* st) { char buf[40]; int len = sym->utf8_length(); if (len >= (int)sizeof(buf)) { @@ -205,10 +205,9 @@ } else if (java_lang_String::is_instance(value)) { EXCEPTION_MARK; Handle h_value (THREAD, value); - symbolHandle sym = java_lang_String::as_symbol(h_value, CATCH); - print_symbol(sym(), st); - } else if (value->is_symbol()) { - print_symbol(symbolOop(value), st); + Symbol* sym = java_lang_String::as_symbol(h_value, CATCH); + print_symbol(sym, st); + sym->decrement_refcount(); } else { st->print_cr(" " PTR_FORMAT, (intptr_t) value); } @@ -316,7 +315,7 @@ } else if (tag.is_method_type()) { int i2 = constants->method_type_index_at(i); st->print(" %d", i2); - print_oop(constants->symbol_at(i2), st); + print_symbol(constants->symbol_at(i2), st); } else if (tag.is_method_handle()) { int kind = constants->method_handle_ref_kind_at(i); int i2 = constants->method_handle_index_at(i); @@ -354,11 +353,11 @@ return; } - symbolOop name = constants->uncached_name_ref_at(i); - symbolOop signature = constants->uncached_signature_ref_at(i); + Symbol* name = constants->uncached_name_ref_at(i); + Symbol* signature = constants->uncached_signature_ref_at(i); const char* sep = (tag.is_field() ? "/" : ""); if (has_klass) { - symbolOop klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i)); + Symbol* klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i)); st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string()); } else { if (tag.is_invoke_dynamic()) { @@ -438,7 +437,7 @@ case Bytecodes::_anewarray: { int klass_index = get_index_u2(); constantPoolOop constants = method()->constants(); - symbolOop name = constants->klass_name_at(klass_index); + Symbol* name = constants->klass_name_at(klass_index); st->print_cr(" %s ", name->as_C_string()); } break; @@ -446,7 +445,7 @@ int klass_index = get_index_u2(); int nof_dims = get_index_u1(); constantPoolOop constants = method()->constants(); - symbolOop name = constants->klass_name_at(klass_index); + Symbol* name = constants->klass_name_at(klass_index); st->print_cr(" %s %d", name->as_C_string(), nof_dims); } break; @@ -552,7 +551,7 @@ case Bytecodes::_instanceof: { int i = get_index_u2(); constantPoolOop constants = method()->constants(); - symbolOop name = constants->klass_name_at(i); + Symbol* name = constants->klass_name_at(i); st->print_cr(" %d <%s>", i, name->as_C_string()); } break; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/interpreter/interpreter.cpp --- a/src/share/vm/interpreter/interpreter.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/interpreter/interpreter.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -302,7 +302,7 @@ Thread *thread = Thread::current(); ResourceMark rm(thread); methodHandle mh(thread, method); - type = Bytecode_invoke(mh, bci).result_type(thread); + type = Bytecode_invoke(mh, bci).result_type(); // since the cache entry might not be initialized: // (NOT needed for the old calling convension) if (!is_top_frame) { @@ -316,7 +316,7 @@ Thread *thread = Thread::current(); ResourceMark rm(thread); methodHandle mh(thread, method); - type = Bytecode_invoke(mh, bci).result_type(thread); + type = Bytecode_invoke(mh, bci).result_type(); // since the cache entry might not be initialized: // (NOT needed for the old calling convension) if (!is_top_frame) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/interpreter/interpreterRuntime.cpp --- a/src/share/vm/interpreter/interpreterRuntime.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -39,7 +39,7 @@ #include "oops/methodDataOop.hpp" #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/nativeLookup.hpp" #include "runtime/biasedLocking.hpp" @@ -295,7 +295,7 @@ IRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message)) // lookup exception klass - symbolHandle s = oopFactory::new_symbol_handle(name, CHECK); + TempNewSymbol s = SymbolTable::new_symbol(name, CHECK); if (ProfileTraps) { if (s == vmSymbols::java_lang_ArithmeticException()) { note_trap(thread, Deoptimization::Reason_div0_check, CHECK); @@ -304,7 +304,7 @@ } } // create exception - Handle exception = Exceptions::new_exception(thread, s(), message); + Handle exception = Exceptions::new_exception(thread, s, message); thread->set_vm_result(exception()); IRT_END @@ -313,12 +313,12 @@ ResourceMark rm(thread); const char* klass_name = Klass::cast(obj->klass())->external_name(); // lookup exception klass - symbolHandle s = oopFactory::new_symbol_handle(name, CHECK); + TempNewSymbol s = SymbolTable::new_symbol(name, CHECK); if (ProfileTraps) { note_trap(thread, Deoptimization::Reason_class_check, CHECK); } // create exception, with klass name as detail message - Handle exception = Exceptions::new_exception(thread, s(), klass_name); + Handle exception = Exceptions::new_exception(thread, s, klass_name); thread->set_vm_result(exception()); IRT_END @@ -326,13 +326,13 @@ IRT_ENTRY(void, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index)) char message[jintAsStringSize]; // lookup exception klass - symbolHandle s = oopFactory::new_symbol_handle(name, CHECK); + TempNewSymbol s = SymbolTable::new_symbol(name, CHECK); if (ProfileTraps) { note_trap(thread, Deoptimization::Reason_range_check, CHECK); } // create exception sprintf(message, "%d", index); - THROW_MSG(s(), message); + THROW_MSG(s, message); IRT_END IRT_ENTRY(void, InterpreterRuntime::throw_ClassCastException( @@ -673,7 +673,7 @@ ResourceMark rm(thread); methodHandle m (thread, method(thread)); Bytecode_invoke call(m, bci(thread)); - symbolHandle signature (thread, call.signature()); + Symbol* signature = call.signature(); receiver = Handle(thread, thread->last_frame().interpreter_callee_receiver(signature)); assert(Universe::heap()->is_in_reserved_or_null(receiver()), @@ -797,7 +797,7 @@ if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null()) return; - symbolHandle call_site_name(THREAD, pool->name_ref_at(site_index)); + Symbol* call_site_name = pool->name_ref_at(site_index); Handle call_site = SystemDictionary::make_dynamic_call_site(bootm, diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -56,7 +56,7 @@ //------------------------------------------------------------------------------------------------------------------------ // Implementation of FieldAccessInfo -void FieldAccessInfo::set(KlassHandle klass, symbolHandle name, int field_index, int field_offset, +void FieldAccessInfo::set(KlassHandle klass, Symbol* name, int field_index, int field_offset, BasicType field_type, AccessFlags access_flags) { _klass = klass; _name = name; @@ -148,7 +148,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_IllegalAccessError(), + vmSymbols::java_lang_IllegalAccessError(), "tried to access class %s from class %s", sel_klass->external_name(), ref_klass->external_name() @@ -174,8 +174,8 @@ // // According to JVM spec. $5.4.3c & $5.4.3d -void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) { - methodOop result_oop = klass->uncached_lookup_method(name(), signature()); +void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { + methodOop result_oop = klass->uncached_lookup_method(name, signature); if (EnableMethodHandles && result_oop != NULL) { switch (result_oop->intrinsic_id()) { case vmIntrinsics::_invokeExact: @@ -189,39 +189,39 @@ } // returns first instance method -void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) { - methodOop result_oop = klass->uncached_lookup_method(name(), signature()); +void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { + methodOop result_oop = klass->uncached_lookup_method(name, signature); result = methodHandle(THREAD, result_oop); while (!result.is_null() && result->is_static()) { klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super()); - result = methodHandle(THREAD, klass->uncached_lookup_method(name(), signature())); + result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature)); } } -int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) { +int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { ResourceMark rm(THREAD); klassVtable *vt = instanceKlass::cast(klass())->vtable(); - return vt->index_of_miranda(name(), signature()); + return vt->index_of_miranda(name, signature); } -void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) { +void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { instanceKlass *ik = instanceKlass::cast(klass()); - result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name(), signature())); + result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature)); } void LinkResolver::lookup_implicit_method(methodHandle& result, - KlassHandle klass, symbolHandle name, symbolHandle signature, + KlassHandle klass, Symbol* name, Symbol* signature, KlassHandle current_klass, TRAPS) { if (EnableMethodHandles && klass() == SystemDictionary::MethodHandle_klass() && - methodOopDesc::is_method_handle_invoke_name(name())) { + methodOopDesc::is_method_handle_invoke_name(name)) { if (!MethodHandles::enabled()) { // Make sure the Java part of the runtime has been booted up. klassOop natives = SystemDictionary::MethodHandleNatives_klass(); if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) { - SystemDictionary::resolve_or_fail(vmSymbolHandles::sun_dyn_MethodHandleNatives(), + SystemDictionary::resolve_or_fail(vmSymbols::sun_dyn_MethodHandleNatives(), Handle(), Handle(), true, @@ -233,7 +233,7 @@ current_klass, CHECK); if (result_oop != NULL) { - assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature(), "consistent"); + assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature, "consistent"); result = methodHandle(THREAD, result_oop); } } @@ -273,7 +273,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_IllegalAccessError(), + vmSymbols::java_lang_IllegalAccessError(), "tried to access method %s.%s%s from class %s", sel_klass->external_name(), sel_method->name()->as_C_string(), @@ -290,8 +290,8 @@ // resolve klass resolve_klass(resolved_klass, pool, index, CHECK); - symbolHandle method_name (THREAD, pool->name_ref_at(index)); - symbolHandle method_signature (THREAD, pool->signature_ref_at(index)); + Symbol* method_name = pool->name_ref_at(index); + Symbol* method_signature = pool->signature_ref_at(index); KlassHandle current_klass(THREAD, pool->pool_holder()); resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); @@ -301,9 +301,9 @@ // The class is java.dyn.MethodHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); - symbolHandle method_name = vmSymbolHandles::invokeExact_name(); + Symbol* method_name = vmSymbols::invokeExact_name(); - symbolHandle method_signature(THREAD, pool->signature_ref_at(index)); + Symbol* method_signature = pool->signature_ref_at(index); KlassHandle current_klass (THREAD, pool->pool_holder()); resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); @@ -313,8 +313,8 @@ // resolve klass resolve_klass(resolved_klass, pool, index, CHECK); - symbolHandle method_name (THREAD, pool->name_ref_at(index)); - symbolHandle method_signature (THREAD, pool->signature_ref_at(index)); + Symbol* method_name = pool->name_ref_at(index); + Symbol* method_signature = pool->signature_ref_at(index); KlassHandle current_klass(THREAD, pool->pool_holder()); resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); @@ -322,7 +322,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, - symbolHandle method_name, symbolHandle method_signature, + Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { // 1. check if klass is not interface @@ -349,8 +349,8 @@ ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), - method_name(), - method_signature())); + method_name, + method_signature)); } } @@ -359,8 +359,8 @@ ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), - method_name(), - method_signature())); + method_name, + method_signature)); } // 6. access checks, access checking may be turned off when calling from within the VM. @@ -387,7 +387,7 @@ " \"%s\" the class loader (instance of %s) of the current class, %s," " and the class loader (instance of %s) for resolved class, %s, have" " different Class objects for the type %s used in the signature"; - char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name(),method_signature()); + char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); const char* loader1 = SystemDictionary::loader_name(loader()); char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); const char* loader2 = SystemDictionary::loader_name(class_loader()); @@ -406,8 +406,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, - symbolHandle method_name, - symbolHandle method_signature, + Symbol* method_name, + Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { @@ -429,8 +429,8 @@ ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), - method_name(), - method_signature())); + method_name, + method_signature)); } } @@ -449,7 +449,7 @@ "current class, %s, and the class loader (instance of %s) for " "resolved class, %s, have different Class objects for the type %s " "used in the signature"; - char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name(),method_signature()); + char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); const char* loader1 = SystemDictionary::loader_name(loader()); char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); const char* loader2 = SystemDictionary::loader_name(class_loader()); @@ -482,7 +482,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_IllegalAccessError(), + vmSymbols::java_lang_IllegalAccessError(), "tried to access field %s.%s from class %s", sel_klass->external_name(), fd.name()->as_C_string(), @@ -511,9 +511,8 @@ resolve_klass_no_update(resolved_klass, pool, index, CHECK); } // Load these early in case the resolve of the containing klass fails - symbolOop field = pool->name_ref_at(index); - symbolHandle field_h (THREAD, field); // preserve in case we need the name - symbolOop sig = pool->signature_ref_at(index); + Symbol* field = pool->name_ref_at(index); + Symbol* sig = pool->signature_ref_at(index); // Check if there's a resolved klass containing the field if( resolved_klass.is_null() ) { ResourceMark rm(THREAD); @@ -559,7 +558,7 @@ HandleMark hm(THREAD); Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader()); Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader()); - symbolHandle signature_ref (THREAD, pool->signature_ref_at(index)); + Symbol* signature_ref = pool->signature_ref_at(index); { ResourceMark rm(THREAD); char* failed_type_name = @@ -572,7 +571,7 @@ " \"%s\" the class loader (instance of %s) of the referring class, " "%s, and the class loader (instance of %s) for the field's resolved " "type, %s, have different Class objects for that type"; - char* field_name = field_h()->as_C_string(); + char* field_name = field->as_C_string(); const char* loader1 = SystemDictionary::loader_name(ref_loader()); char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string(); const char* loader2 = SystemDictionary::loader_name(sel_loader()); @@ -589,7 +588,7 @@ // return information. note that the klass is set to the actual klass containing the // field, otherwise access of static fields in superclasses will not work. KlassHandle holder (THREAD, fd.field_holder()); - symbolHandle name (THREAD, fd.name()); + Symbol* name = fd.name(); result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags()); } @@ -605,8 +604,8 @@ // recv_klass the receiver klass -void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, symbolHandle method_name, - symbolHandle method_signature, KlassHandle current_klass, +void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, + Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_class, TRAPS) { methodHandle resolved_method; linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); @@ -624,7 +623,7 @@ // throws linktime exceptions void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass, - symbolHandle method_name, symbolHandle method_signature, + Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); @@ -641,8 +640,8 @@ } -void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, symbolHandle method_name, - symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS) { +void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, + Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { methodHandle resolved_method; linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK); @@ -650,7 +649,7 @@ // throws linktime exceptions void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, - symbolHandle method_name, symbolHandle method_signature, + Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); @@ -661,7 +660,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_NoSuchMethodError(), + vmSymbols::java_lang_NoSuchMethodError(), "%s: method %s%s not found", resolved_klass->external_name(), resolved_method->name()->as_C_string(), @@ -703,8 +702,8 @@ // Lookup super method KlassHandle super_klass(THREAD, current_klass->super()); lookup_instance_method_in_klasses(sel_method, super_klass, - symbolHandle(THREAD, resolved_method->name()), - symbolHandle(THREAD, resolved_method->signature()), CHECK); + resolved_method->name(), + resolved_method->signature(), CHECK); // check if found if (sel_method.is_null()) { ResourceMark rm(THREAD); @@ -739,7 +738,7 @@ } void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass, - symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, + Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS) { methodHandle resolved_method; linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); @@ -748,7 +747,7 @@ // throws linktime exceptions void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass, - symbolHandle method_name, symbolHandle method_signature, + Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { // normal method resolution resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); @@ -798,8 +797,8 @@ // do lookup based on receiver klass using the vtable index if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method vtable_index = vtable_index_of_miranda_method(resolved_klass, - symbolHandle(THREAD, resolved_method->name()), - symbolHandle(THREAD, resolved_method->signature()), CHECK); + resolved_method->name(), + resolved_method->signature(), CHECK); assert(vtable_index >= 0 , "we should have valid vtable index at this point"); instanceKlass* inst = instanceKlass::cast(recv_klass()); @@ -847,7 +846,7 @@ } void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, - symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, + Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS) { methodHandle resolved_method; linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); @@ -855,8 +854,8 @@ } // throws linktime exceptions -void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, - symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS) { +void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, + Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { // normal interface method resolution resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); @@ -883,8 +882,8 @@ // do lookup based on receiver klass methodHandle sel_method; lookup_instance_method_in_klasses(sel_method, recv_klass, - symbolHandle(THREAD, resolved_method->name()), - symbolHandle(THREAD, resolved_method->signature()), CHECK); + resolved_method->name(), + resolved_method->signature(), CHECK); // check if method exists if (sel_method.is_null()) { ResourceMark rm(THREAD); @@ -916,8 +915,8 @@ methodHandle LinkResolver::linktime_resolve_interface_method_or_null( KlassHandle resolved_klass, - symbolHandle method_name, - symbolHandle method_signature, + Symbol* method_name, + Symbol* method_signature, KlassHandle current_klass, bool check_access) { EXCEPTION_MARK; @@ -933,8 +932,8 @@ methodHandle LinkResolver::linktime_resolve_virtual_method_or_null( KlassHandle resolved_klass, - symbolHandle method_name, - symbolHandle method_signature, + Symbol* method_name, + Symbol* method_signature, KlassHandle current_klass, bool check_access) { EXCEPTION_MARK; @@ -951,8 +950,8 @@ methodHandle LinkResolver::resolve_virtual_call_or_null( KlassHandle receiver_klass, KlassHandle resolved_klass, - symbolHandle name, - symbolHandle signature, + Symbol* name, + Symbol* signature, KlassHandle current_klass) { EXCEPTION_MARK; CallInfo info; @@ -967,8 +966,8 @@ methodHandle LinkResolver::resolve_interface_call_or_null( KlassHandle receiver_klass, KlassHandle resolved_klass, - symbolHandle name, - symbolHandle signature, + Symbol* name, + Symbol* signature, KlassHandle current_klass) { EXCEPTION_MARK; CallInfo info; @@ -983,8 +982,8 @@ int LinkResolver::resolve_virtual_vtable_index( KlassHandle receiver_klass, KlassHandle resolved_klass, - symbolHandle name, - symbolHandle signature, + Symbol* name, + Symbol* signature, KlassHandle current_klass) { EXCEPTION_MARK; CallInfo info; @@ -998,8 +997,8 @@ methodHandle LinkResolver::resolve_static_call_or_null( KlassHandle resolved_klass, - symbolHandle name, - symbolHandle signature, + Symbol* name, + Symbol* signature, KlassHandle current_klass) { EXCEPTION_MARK; CallInfo info; @@ -1011,7 +1010,7 @@ return info.selected_method(); } -methodHandle LinkResolver::resolve_special_call_or_null(KlassHandle resolved_klass, symbolHandle name, symbolHandle signature, +methodHandle LinkResolver::resolve_special_call_or_null(KlassHandle resolved_klass, Symbol* name, Symbol* signature, KlassHandle current_klass) { EXCEPTION_MARK; CallInfo info; @@ -1039,22 +1038,22 @@ return; } -void LinkResolver::resolve_pool(KlassHandle& resolved_klass, symbolHandle& method_name, symbolHandle& method_signature, +void LinkResolver::resolve_pool(KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) { // resolve klass resolve_klass(resolved_klass, pool, index, CHECK); // Get name, signature, and static klass - method_name = symbolHandle(THREAD, pool->name_ref_at(index)); - method_signature = symbolHandle(THREAD, pool->signature_ref_at(index)); + method_name = pool->name_ref_at(index); + method_signature = pool->signature_ref_at(index); current_klass = KlassHandle(THREAD, pool->pool_holder()); } void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { KlassHandle resolved_klass; - symbolHandle method_name; - symbolHandle method_signature; + Symbol* method_name = NULL; + Symbol* method_signature = NULL; KlassHandle current_klass; resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); @@ -1063,8 +1062,8 @@ void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { KlassHandle resolved_klass; - symbolHandle method_name; - symbolHandle method_signature; + Symbol* method_name = NULL; + Symbol* method_signature = NULL; KlassHandle current_klass; resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK); @@ -1076,8 +1075,8 @@ TRAPS) { KlassHandle resolved_klass; - symbolHandle method_name; - symbolHandle method_signature; + Symbol* method_name = NULL; + Symbol* method_signature = NULL; KlassHandle current_klass; resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); @@ -1087,8 +1086,8 @@ void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) { KlassHandle resolved_klass; - symbolHandle method_name; - symbolHandle method_signature; + Symbol* method_name = NULL; + Symbol* method_signature = NULL; KlassHandle current_klass; resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); @@ -1102,8 +1101,8 @@ // This guy is reached from InterpreterRuntime::resolve_invokedynamic. // At this point, we only need the signature, and can ignore the name. - symbolHandle method_signature(THREAD, pool->signature_ref_at(raw_index)); // raw_index works directly - symbolHandle method_name = vmSymbolHandles::invokeExact_name(); + Symbol* method_signature = pool->signature_ref_at(raw_index); // raw_index works directly + Symbol* method_name = vmSymbols::invokeExact_name(); KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/interpreter/linkResolver.hpp --- a/src/share/vm/interpreter/linkResolver.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/interpreter/linkResolver.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -45,17 +45,17 @@ class FieldAccessInfo: public LinkInfo { protected: KlassHandle _klass; - symbolHandle _name; + Symbol* _name; AccessFlags _access_flags; int _field_index; // original index in the klass int _field_offset; BasicType _field_type; public: - void set(KlassHandle klass, symbolHandle name, int field_index, int field_offset, + void set(KlassHandle klass, Symbol* name, int field_index, int field_offset, BasicType field_type, AccessFlags access_flags); KlassHandle klass() const { return _klass; } - symbolHandle name() const { return _name; } + Symbol* name() const { return _name; } int field_index() const { return _field_index; } int field_offset() const { return _field_offset; } BasicType field_type() const { return _field_type; } @@ -107,26 +107,26 @@ class LinkResolver: AllStatic { private: - static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS); - static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS); - static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS); - static void lookup_implicit_method (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, + static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); + static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); + static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); + static void lookup_implicit_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, KlassHandle current_klass, TRAPS); - static int vtable_index_of_miranda_method(KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS); + static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); static void resolve_klass_no_update (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); // no update of constantPool entry - static void resolve_pool (KlassHandle& resolved_klass, symbolHandle& method_name, symbolHandle& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); + static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); - static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS); - static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); - static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS); - static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS); - static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature,KlassHandle current_klass, bool check_access, TRAPS); - static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature,KlassHandle current_klass, bool check_access, TRAPS); + static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS); static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS); @@ -152,24 +152,24 @@ // runtime resolving: // resolved_klass = specified class (i.e., static receiver class) // current_klass = sending method holder (i.e., class containing the method containing the call being resolved) - static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS); - static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS); - static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS); - static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS); + static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS); + static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS); + static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS); // same as above for compile-time resolution; but returns null handle instead of throwing an exception on error // also, does not initialize klass (i.e., no side effects) - static methodHandle resolve_virtual_call_or_null (KlassHandle receiver_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass); - static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass); - static methodHandle resolve_static_call_or_null (KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass); - static methodHandle resolve_special_call_or_null (KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass); + static methodHandle resolve_virtual_call_or_null (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass); + static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass); + static methodHandle resolve_static_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass); + static methodHandle resolve_special_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass); // same as above for compile-time resolution; returns vtable_index if current_klass if linked - static int resolve_virtual_vtable_index (KlassHandle receiver_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass); + static int resolve_virtual_vtable_index (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass); // static resolving for compiler (does not throw exceptions, returns null handle if unsuccessful) - static methodHandle linktime_resolve_virtual_method_or_null (KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access); - static methodHandle linktime_resolve_interface_method_or_null(KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access); + static methodHandle linktime_resolve_virtual_method_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access); + static methodHandle linktime_resolve_interface_method_or_null(KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access); // runtime resolving from constant pool static void resolve_invokestatic (CallInfo& result, constantPoolHandle pool, int index, TRAPS); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/classify.cpp --- a/src/share/vm/memory/classify.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/classify.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -68,8 +68,6 @@ type = typeArray_type; } else if (obj->is_objArray()) { type = objArray_type; - } else if (obj->is_symbol()) { - type = symbol_type; } else if (obj->is_klass()) { Klass* k = ((klassOop)obj)->klass_part(); if (k->oop_is_instance()) { @@ -158,8 +156,6 @@ name = "_typeArrayKlassKlassObj"; } else if (obj == Universe::instanceKlassKlassObj()) { name = "_instanceKlassKlassObj"; - } else if (obj == Universe::symbolKlassObj()) { - name = "_symbolKlassObj"; } else if (obj == Universe::methodKlassObj()) { name = "_methodKlassObj"; } else if (obj == Universe::constMethodKlassObj()) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/compactingPermGenGen.cpp --- a/src/share/vm/memory/compactingPermGenGen.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/compactingPermGenGen.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -95,17 +95,11 @@ // their stack to the class without having added the class to the // dictionary yet. This means the class will be marked during phase 1 // but will not be unmarked during the application of the -// RecursiveAdjustSharedObjectClosure to the SystemDictionary. Note -// that we must not call find_shared_class with non-read-only symbols -// as doing so can cause hash codes to be computed, destroying -// forwarding pointers. -class TraversePlaceholdersClosure : public OopClosure { - protected: - template inline void do_oop_work(T* p) { - oop obj = oopDesc::load_decode_heap_oop_not_null(p); - if (obj->klass() == Universe::symbolKlassObj() && - obj->is_shared_readonly()) { - symbolHandle sym((symbolOop) obj); +// RecursiveAdjustSharedObjectClosure to the SystemDictionary. +class TraversePlaceholdersClosure { + public: + static void placeholders_do(Symbol* sym, oop loader) { + if (CompactingPermGenGen::is_shared(sym)) { oop k = SystemDictionary::find_shared_class(sym); if (k != NULL) { RecursiveAdjustSharedObjectClosure clo; @@ -113,13 +107,8 @@ } } } - public: - virtual void do_oop(oop* p) { TraversePlaceholdersClosure::do_oop_work(p); } - virtual void do_oop(narrowOop* p) { TraversePlaceholdersClosure::do_oop_work(p); } - }; - void CompactingPermGenGen::initialize_performance_counters() { const char* gen_name = "perm"; @@ -335,8 +324,7 @@ Universe::oops_do(&blk); StringTable::oops_do(&blk); SystemDictionary::always_strong_classes_do(&blk); - TraversePlaceholdersClosure tpc; - SystemDictionary::placeholders_do(&tpc); + SystemDictionary::placeholders_do(TraversePlaceholdersClosure::placeholders_do); } } } @@ -490,5 +478,3 @@ } return true; } - -void** CompactingPermGenGen::_vtbl_list; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/compactingPermGenGen.hpp --- a/src/share/vm/memory/compactingPermGenGen.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/compactingPermGenGen.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -96,9 +96,6 @@ static HeapWord* misccode_end; static HeapWord* shared_end; - // List of klassOops whose vtbl entries are used to patch others. - static void** _vtbl_list; - // Performance Counters GenerationCounters* _gen_counters; CSpaceCounters* _space_counters; @@ -153,32 +150,25 @@ VirtualSpace* mc_space() { return &_mc_vs; } ContiguousSpace* unshared_space() const { return _the_space; } - static bool inline is_shared(const oopDesc* p) { - return (HeapWord*)p >= shared_bottom && (HeapWord*)p < shared_end; + static bool inline is_shared(const void* p) { + return p >= shared_bottom && p < shared_end; } // RedefineClasses note: this tester is used to check residence of // the specified oop in the shared readonly space and not whether // the oop is readonly. - static bool inline is_shared_readonly(const oopDesc* p) { - return (HeapWord*)p >= readonly_bottom && (HeapWord*)p < readonly_end; + static bool inline is_shared_readonly(const void* p) { + return p >= readonly_bottom && p < readonly_end; } // RedefineClasses note: this tester is used to check residence of // the specified oop in the shared readwrite space and not whether // the oop is readwrite. - static bool inline is_shared_readwrite(const oopDesc* p) { - return (HeapWord*)p >= readwrite_bottom && (HeapWord*)p < readwrite_end; + static bool inline is_shared_readwrite(const void* p) { + return p >= readwrite_bottom && p < readwrite_end; } - bool is_in_unshared(const void* p) const { - return OneContigSpaceCardGeneration::is_in(p); - } - - bool is_in_shared(const void* p) const { - return p >= shared_bottom && p < shared_end; - } - + // Checks if the pointer is either in unshared space or in shared space inline bool is_in(const void* p) const { - return is_in_unshared(p) || is_in_shared(p); + return OneContigSpaceCardGeneration::is_in(p) || is_shared(p); } inline PermanentGenerationSpec* spec() const { return _spec; } @@ -236,6 +226,9 @@ void** vtable, char** md_top, char* md_end, char** mc_top, char* mc_end); + static void* find_matching_vtbl_ptr(void** vtbl_list, + void* new_vtable_start, + void* obj); void verify(bool allow_dirty); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/dump.cpp --- a/src/share/vm/memory/dump.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/dump.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -133,6 +133,69 @@ return false; } + +class MoveSymbols : public SymbolClosure { +private: + char* _start; + char* _end; + char* _top; + int _count; + + bool in_shared_space(Symbol* sym) const { + return (char*)sym >= _start && (char*)sym < _end; + } + + Symbol* get_shared_copy(Symbol* sym) { + return sym->refcount() > 0 ? NULL : (Symbol*)(_start - sym->refcount()); + } + + Symbol* make_shared_copy(Symbol* sym) { + Symbol* new_sym = (Symbol*)_top; + int size = sym->object_size(); + _top += size * HeapWordSize; + if (_top <= _end) { + Copy::disjoint_words((HeapWord*)sym, (HeapWord*)new_sym, size); + // Encode a reference to the copy as a negative distance from _start + // When a symbol is being copied to a shared space + // during CDS archive creation, the original symbol is marked + // as relocated by putting a negative value to its _refcount field, + // This value is also used to find where exactly the shared copy is + // (see MoveSymbols::get_shared_copy), so that the other references + // to this symbol could be changed to point to the shared copy. + sym->_refcount = (int)(_start - (char*)new_sym); + // Mark the symbol in the shared archive as immortal so it is read only + // and not refcounted. + new_sym->_refcount = -1; + _count++; + } else { + report_out_of_shared_space(SharedMiscData); + } + return new_sym; + } + +public: + MoveSymbols(char* top, char* end) : + _start(top), _end(end), _top(top), _count(0) { } + + char* get_top() const { return _top; } + int count() const { return _count; } + + void do_symbol(Symbol** p) { + Symbol* sym = load_symbol(p); + if (sym != NULL && !in_shared_space(sym)) { + Symbol* new_sym = get_shared_copy(sym); + if (new_sym == NULL) { + // The symbol has not been relocated yet; copy it to _top address + assert(sym->refcount() > 0, "should have positive reference count"); + new_sym = make_shared_copy(sym); + } + // Make the reference point to the shared copy of the symbol + store_symbol(p, new_sym); + } + } +}; + + // Closure: mark objects closure. class MarkObjectsOopClosure : public OopClosure { @@ -164,7 +227,7 @@ } -// Closure: mark common read-only objects, excluding symbols +// Closure: mark common read-only objects class MarkCommonReadOnly : public ObjectClosure { private: @@ -216,54 +279,52 @@ }; -// Closure: mark common symbols +// Closure: find symbol references in Java Heap objects -class MarkCommonSymbols : public ObjectClosure { +class CommonSymbolsClosure : public ObjectClosure { private: - MarkObjectsOopClosure mark_all; + SymbolClosure* _closure; public: + CommonSymbolsClosure(SymbolClosure* closure) : _closure(closure) { } + void do_object(oop obj) { - // Mark symbols refered to by method objects. + // Traverse symbols referenced by method objects. if (obj->is_method()) { methodOop m = methodOop(obj); - mark_object(m->name()); - mark_object(m->signature()); + constantPoolOop constants = m->constants(); + _closure->do_symbol(constants->symbol_at_addr(m->name_index())); + _closure->do_symbol(constants->symbol_at_addr(m->signature_index())); } - // Mark symbols referenced by klass objects which are read-only. + // Traverse symbols referenced by klass objects which are read-only. else if (obj->is_klass()) { + Klass* k = Klass::cast((klassOop)obj); + k->shared_symbols_iterate(_closure); if (obj->blueprint()->oop_is_instanceKlass()) { instanceKlass* ik = instanceKlass::cast((klassOop)obj); - mark_object(ik->name()); - mark_object(ik->generic_signature()); - mark_object(ik->source_file_name()); - mark_object(ik->source_debug_extension()); - typeArrayOop inner_classes = ik->inner_classes(); if (inner_classes != NULL) { - int length = inner_classes->length(); - for (int i = 0; - i < length; - i += instanceKlass::inner_class_next_offset) { + constantPoolOop constants = ik->constants(); + int n = inner_classes->length(); + for (int i = 0; i < n; i += instanceKlass::inner_class_next_offset) { int ioff = i + instanceKlass::inner_class_inner_name_offset; int index = inner_classes->ushort_at(ioff); if (index != 0) { - mark_object(ik->constants()->symbol_at(index)); + _closure->do_symbol(constants->symbol_at_addr(index)); } } } - ik->field_names_and_sigs_iterate(&mark_all); } } - // Mark symbols referenced by other constantpool entries. + // Traverse symbols referenced by other constantpool entries. - if (obj->is_constantPool()) { - constantPoolOop(obj)->shared_symbols_iterate(&mark_all); + else if (obj->is_constantPool()) { + constantPoolOop(obj)->shared_symbols_iterate(_closure); } } }; @@ -404,18 +465,7 @@ int s = obj->size(); oop sh_obj = (oop)_space->allocate(s); if (sh_obj == NULL) { - if (_read_only) { - warning("\nThe permanent generation read only space is not large " - "enough to \npreload requested classes. Use " - "-XX:SharedReadOnlySize= to increase \nthe initial " - "size of the read only space.\n"); - } else { - warning("\nThe permanent generation read write space is not large " - "enough to \npreload requested classes. Use " - "-XX:SharedReadWriteSize= to increase \nthe initial " - "size of the read write space.\n"); - } - exit(2); + report_out_of_shared_space(_read_only ? SharedReadOnly : SharedReadWrite); } if (PrintSharedSpaces && Verbose && WizardMode) { tty->print_cr("\nMoveMarkedObjects: " PTR_FORMAT " -> " PTR_FORMAT " %s", obj, sh_obj, @@ -459,8 +509,6 @@ instanceKlass* ik = instanceKlass::cast((klassOop)obj); int i; - mark_and_move_for_policy(OP_favor_startup, ik->name(), _move_ro); - if (ik->super() != NULL) { do_object(ik->super()); } @@ -469,7 +517,6 @@ mark_and_move_for_policy(OP_favor_startup, interfaces, _move_ro); for(i = 0; i < interfaces->length(); i++) { klassOop k = klassOop(interfaces->obj_at(i)); - mark_and_move_for_policy(OP_favor_startup, k->klass_part()->name(), _move_ro); do_object(k); } @@ -479,14 +526,6 @@ mark_and_move_for_policy(OP_favor_startup, m->constMethod(), _move_ro); mark_and_move_for_policy(OP_favor_runtime, m->constMethod()->exception_table(), _move_ro); mark_and_move_for_policy(OP_favor_runtime, m->constMethod()->stackmap_data(), _move_ro); - - // We don't move the name symbolOop here because it may invalidate - // method ordering, which is dependent on the address of the name - // symbolOop. It will get promoted later with the other symbols. - // Method name is rarely accessed during classloading anyway. - // mark_and_move_for_policy(OP_balanced, m->name(), _move_ro); - - mark_and_move_for_policy(OP_favor_startup, m->signature(), _move_ro); } mark_and_move_for_policy(OP_favor_startup, ik->transitive_interfaces(), _move_ro); @@ -574,45 +613,43 @@ }; -void sort_methods(instanceKlass* ik, TRAPS) { - klassOop super = ik->super(); - if (super != NULL) { - sort_methods(instanceKlass::cast(super), THREAD); - } - - // The methods array must be ordered by symbolOop address. (See - // classFileParser.cpp where methods in a class are originally - // sorted.) Since objects have just be reordered, this must be - // corrected. - methodOopDesc::sort_methods(ik->methods(), - ik->methods_annotations(), - ik->methods_parameter_annotations(), - ik->methods_default_annotations(), - true /* idempotent, slow */); - - // Itable indices are calculated based on methods array order - // (see klassItable::compute_itable_index()). Must reinitialize. - // We assume that since checkconstraints is false, this method - // cannot throw an exception. An exception here would be - // problematic since this is the VMThread, not a JavaThread. - ik->itable()->initialize_itable(false, THREAD); -} - -// Sort methods if the oop is an instanceKlass. +// The methods array must be reordered by Symbol* address. +// (See classFileParser.cpp where methods in a class are originally +// sorted). The addresses of symbols have been changed as a result +// of moving to the shared space. class SortMethodsClosure: public ObjectClosure { +public: + void do_object(oop obj) { + if (obj->blueprint()->oop_is_instanceKlass()) { + instanceKlass* ik = instanceKlass::cast((klassOop)obj); + methodOopDesc::sort_methods(ik->methods(), + ik->methods_annotations(), + ik->methods_parameter_annotations(), + ik->methods_default_annotations(), + true /* idempotent, slow */); + } + } +}; + +// Itable indices are calculated based on methods array order +// (see klassItable::compute_itable_index()). Must reinitialize +// after ALL methods of ALL classes have been reordered. +// We assume that since checkconstraints is false, this method +// cannot throw an exception. An exception here would be +// problematic since this is the VMThread, not a JavaThread. + +class ReinitializeItables: public ObjectClosure { private: Thread* _thread; public: - SortMethodsClosure(Thread* thread) : _thread(thread) {} + ReinitializeItables(Thread* thread) : _thread(thread) {} void do_object(oop obj) { - // instanceKlass objects need some adjustment. if (obj->blueprint()->oop_is_instanceKlass()) { instanceKlass* ik = instanceKlass::cast((klassOop)obj); - - sort_methods(ik, _thread); + ik->itable()->initialize_itable(false, _thread); } } }; @@ -673,18 +710,9 @@ oop* top; char* end; - void out_of_space() { - warning("\nThe shared miscellaneous data space is not large " - "enough to \npreload requested classes. Use " - "-XX:SharedMiscDataSize= to increase \nthe initial " - "size of the miscellaneous data space.\n"); - exit(2); - } - - inline void check_space() { if ((char*)top + sizeof(oop) > end) { - out_of_space(); + report_out_of_shared_space(SharedMiscData); } } @@ -737,7 +765,7 @@ void do_region(u_char* start, size_t size) { if ((char*)top + size > end) { - out_of_space(); + report_out_of_shared_space(SharedMiscData); } assert((intptr_t)start % sizeof(oop) == 0, "bad alignment"); assert(size % sizeof(oop) == 0, "bad size"); @@ -870,46 +898,53 @@ class PatchKlassVtables: public ObjectClosure { private: - void* _vtbl_ptr; - VirtualSpace* _md_vs; GrowableArray* _klass_objects; public: - - PatchKlassVtables(void* vtbl_ptr, VirtualSpace* md_vs) { - _vtbl_ptr = vtbl_ptr; - _md_vs = md_vs; + PatchKlassVtables() { _klass_objects = new GrowableArray(); } - void do_object(oop obj) { if (obj->is_klass()) { _klass_objects->append(klassOop(obj)); } } - - void patch(void** vtbl_list, int vtbl_list_size) { - for (int i = 0; i < _klass_objects->length(); ++i) { + void patch(void** vtbl_list, void* new_vtable_start) { + int n = _klass_objects->length(); + for (int i = 0; i < n; i++) { klassOop obj = (klassOop)_klass_objects->at(i); Klass* k = obj->klass_part(); - void* v = *(void**)k; - - int n; - for (n = 0; n < vtbl_list_size; ++n) { - *(void**)k = NULL; - if (vtbl_list[n] == v) { - *(void**)k = (void**)_vtbl_ptr + - (n * CompactingPermGenGen::num_virtuals); - break; - } - } - guarantee(n < vtbl_list_size, "unable to find matching vtbl pointer"); + *(void**)k = CompactingPermGenGen::find_matching_vtbl_ptr( + vtbl_list, new_vtable_start, k); } } }; +// Walk through all symbols and patch their vtable pointers. +// Note that symbols have vtable pointers only in non-product builds +// (see allocation.hpp). + +#ifndef PRODUCT +class PatchSymbolVtables: public SymbolClosure { +private: + void* _new_vtbl_ptr; + +public: + PatchSymbolVtables(void** vtbl_list, void* new_vtable_start) { + Symbol s; + _new_vtbl_ptr = CompactingPermGenGen::find_matching_vtbl_ptr( + vtbl_list, new_vtable_start, &s); + } + + void do_symbol(Symbol** p) { + Symbol* sym = load_symbol(p); + *(void**)sym = _new_vtbl_ptr; + } +}; +#endif + // Populate the shared space. @@ -969,7 +1004,6 @@ MarkObjectsOopClosure mark_all; MarkCommonReadOnly mark_common_ro; - MarkCommonSymbols mark_common_symbols; MarkStringValues mark_string_values; MarkReadWriteObjects mark_rw; MarkStringObjects mark_strings; @@ -1013,112 +1047,6 @@ MarkAndMoveOrderedReadOnly mark_and_move_ordered_ro(&move_ro); MarkAndMoveOrderedReadWrite mark_and_move_ordered_rw(&move_rw); - // Phase 1a: move commonly used read-only objects to the read-only space. - - if (SharedOptimizeColdStart) { - tty->print("Moving pre-ordered read-only objects to shared space at " PTR_FORMAT " ... ", - _ro_space->top()); - for (int i = 0; i < _class_promote_order->length(); i++) { - oop obj = _class_promote_order->at(i); - mark_and_move_ordered_ro.do_object(obj); - } - tty->print_cr("done. "); - } - - tty->print("Moving read-only objects to shared space at " PTR_FORMAT " ... ", - _ro_space->top()); - gch->object_iterate(&mark_common_ro); - gch->object_iterate(&move_ro); - tty->print_cr("done. "); - - // Phase 1b: move commonly used symbols to the read-only space. - - tty->print("Moving common symbols to shared space at " PTR_FORMAT " ... ", - _ro_space->top()); - gch->object_iterate(&mark_common_symbols); - gch->object_iterate(&move_ro); - tty->print_cr("done. "); - - // Phase 1c: move remaining symbols to the read-only space - // (e.g. String initializers). - - tty->print("Moving remaining symbols to shared space at " PTR_FORMAT " ... ", - _ro_space->top()); - vmSymbols::oops_do(&mark_all, true); - gch->object_iterate(&move_ro); - tty->print_cr("done. "); - - // Phase 1d: move String character arrays to the read-only space. - - tty->print("Moving string char arrays to shared space at " PTR_FORMAT " ... ", - _ro_space->top()); - gch->object_iterate(&mark_string_values); - gch->object_iterate(&move_ro); - tty->print_cr("done. "); - - // Phase 2: move all remaining symbols to the read-only space. The - // remaining symbols are assumed to be string initializers no longer - // referenced. - - void* extra_symbols = _ro_space->top(); - tty->print("Moving additional symbols to shared space at " PTR_FORMAT " ... ", - _ro_space->top()); - SymbolTable::oops_do(&mark_all); - gch->object_iterate(&move_ro); - tty->print_cr("done. "); - tty->print_cr("Read-only space ends at " PTR_FORMAT ", %d bytes.", - _ro_space->top(), _ro_space->used()); - - // Phase 3: move read-write objects to the read-write space, except - // Strings. - - if (SharedOptimizeColdStart) { - tty->print("Moving pre-ordered read-write objects to shared space at " PTR_FORMAT " ... ", - _rw_space->top()); - for (int i = 0; i < _class_promote_order->length(); i++) { - oop obj = _class_promote_order->at(i); - mark_and_move_ordered_rw.do_object(obj); - } - tty->print_cr("done. "); - } - tty->print("Moving read-write objects to shared space at " PTR_FORMAT " ... ", - _rw_space->top()); - Universe::oops_do(&mark_all, true); - SystemDictionary::oops_do(&mark_all); - oop tmp = Universe::arithmetic_exception_instance(); - mark_object(java_lang_Throwable::message(tmp)); - gch->object_iterate(&mark_rw); - gch->object_iterate(&move_rw); - tty->print_cr("done. "); - - // Phase 4: move String objects to the read-write space. - - tty->print("Moving String objects to shared space at " PTR_FORMAT " ... ", - _rw_space->top()); - StringTable::oops_do(&mark_all); - gch->object_iterate(&mark_strings); - gch->object_iterate(&move_rw); - tty->print_cr("done. "); - tty->print_cr("Read-write space ends at " PTR_FORMAT ", %d bytes.", - _rw_space->top(), _rw_space->used()); - -#ifdef DEBUG - // Check: scan for objects which were not moved. - - CheckRemainingObjects check_objects; - gch->object_iterate(&check_objects); - check_objects.status(); -#endif - - // Resolve forwarding in objects and saved C++ structures - tty->print("Updating references to shared objects ... "); - ResolveForwardingClosure resolve; - Universe::oops_do(&resolve); - SystemDictionary::oops_do(&resolve); - StringTable::oops_do(&resolve); - SymbolTable::oops_do(&resolve); - vmSymbols::oops_do(&resolve); - // Set up the share data and shared code segments. char* md_top = _md_vs->low(); @@ -1144,6 +1072,122 @@ &md_top, md_end, &mc_top, mc_end); + // Reserve space for the total size and the number of stored symbols. + + md_top += sizeof(intptr_t) * 2; + + MoveSymbols move_symbols(md_top, md_end); + CommonSymbolsClosure traverse_common_symbols(&move_symbols); + + // Phase 1a: remove symbols with _refcount == 0 + + SymbolTable::unlink(); + + // Phase 1b: move commonly used symbols referenced by oop fields. + + tty->print("Moving common symbols to metadata section at " PTR_FORMAT " ... ", + move_symbols.get_top()); + gch->object_iterate(&traverse_common_symbols); + tty->print_cr("done. "); + + // Phase 1c: move known names and signatures. + + tty->print("Moving vmSymbols to metadata section at " PTR_FORMAT " ... ", + move_symbols.get_top()); + vmSymbols::symbols_do(&move_symbols); + tty->print_cr("done. "); + + // Phase 1d: move the remaining symbols by scanning the whole SymbolTable. + + void* extra_symbols = move_symbols.get_top(); + tty->print("Moving the remaining symbols to metadata section at " PTR_FORMAT " ... ", + move_symbols.get_top()); + SymbolTable::symbols_do(&move_symbols); + tty->print_cr("done. "); + + // Record the total length of all symbols at the beginning of the block. + ((intptr_t*)md_top)[-2] = move_symbols.get_top() - md_top; + ((intptr_t*)md_top)[-1] = move_symbols.count(); + tty->print_cr("Moved %d symbols, %d bytes.", + move_symbols.count(), move_symbols.get_top() - md_top); + // Advance the pointer to the end of symbol store. + md_top = move_symbols.get_top(); + + + // Phase 2: move commonly used read-only objects to the read-only space. + + if (SharedOptimizeColdStart) { + tty->print("Moving pre-ordered read-only objects to shared space at " PTR_FORMAT " ... ", + _ro_space->top()); + for (int i = 0; i < _class_promote_order->length(); i++) { + oop obj = _class_promote_order->at(i); + mark_and_move_ordered_ro.do_object(obj); + } + tty->print_cr("done. "); + } + + tty->print("Moving read-only objects to shared space at " PTR_FORMAT " ... ", + _ro_space->top()); + gch->object_iterate(&mark_common_ro); + gch->object_iterate(&move_ro); + tty->print_cr("done. "); + + // Phase 3: move String character arrays to the read-only space. + + tty->print("Moving string char arrays to shared space at " PTR_FORMAT " ... ", + _ro_space->top()); + gch->object_iterate(&mark_string_values); + gch->object_iterate(&move_ro); + tty->print_cr("done. "); + + // Phase 4: move read-write objects to the read-write space, except + // Strings. + + if (SharedOptimizeColdStart) { + tty->print("Moving pre-ordered read-write objects to shared space at " PTR_FORMAT " ... ", + _rw_space->top()); + for (int i = 0; i < _class_promote_order->length(); i++) { + oop obj = _class_promote_order->at(i); + mark_and_move_ordered_rw.do_object(obj); + } + tty->print_cr("done. "); + } + tty->print("Moving read-write objects to shared space at " PTR_FORMAT " ... ", + _rw_space->top()); + Universe::oops_do(&mark_all, true); + SystemDictionary::oops_do(&mark_all); + oop tmp = Universe::arithmetic_exception_instance(); + mark_object(java_lang_Throwable::message(tmp)); + gch->object_iterate(&mark_rw); + gch->object_iterate(&move_rw); + tty->print_cr("done. "); + + // Phase 5: move String objects to the read-write space. + + tty->print("Moving String objects to shared space at " PTR_FORMAT " ... ", + _rw_space->top()); + StringTable::oops_do(&mark_all); + gch->object_iterate(&mark_strings); + gch->object_iterate(&move_rw); + tty->print_cr("done. "); + tty->print_cr("Read-write space ends at " PTR_FORMAT ", %d bytes.", + _rw_space->top(), _rw_space->used()); + +#ifdef DEBUG + // Check: scan for objects which were not moved. + + CheckRemainingObjects check_objects; + gch->object_iterate(&check_objects); + check_objects.status(); +#endif + + // Resolve forwarding in objects and saved C++ structures + tty->print("Updating references to shared objects ... "); + ResolveForwardingClosure resolve; + Universe::oops_do(&resolve); + SystemDictionary::oops_do(&resolve); + StringTable::oops_do(&resolve); + // Fix (forward) all of the references in these shared objects (which // are required to point ONLY to objects in the shared spaces). // Also, create a list of all objects which might later contain a @@ -1166,9 +1210,13 @@ // pointer resolution, so that methods can be promoted in any order // with respect to their holder classes. - SortMethodsClosure sort(THREAD); + SortMethodsClosure sort; gen->ro_space()->object_iterate(&sort); gen->rw_space()->object_iterate(&sort); + + ReinitializeItables reinit_itables(THREAD); + gen->ro_space()->object_iterate(&reinit_itables); + gen->rw_space()->object_iterate(&reinit_itables); tty->print_cr("done. "); tty->cr(); @@ -1233,9 +1281,16 @@ // Update the vtable pointers in all of the Klass objects in the // heap. They should point to newly generated vtable. - PatchKlassVtables pkvt(vtable, _md_vs); + PatchKlassVtables pkvt; _rw_space->object_iterate(&pkvt); - pkvt.patch(vtbl_list, vtbl_list_size); + pkvt.patch(vtbl_list, vtable); + +#ifndef PRODUCT + // Update the vtable pointers in all symbols, + // but only in non-product builds where symbols DO have virtual methods. + PatchSymbolVtables psvt(vtbl_list, vtable); + SymbolTable::symbols_do(&psvt); +#endif char* saved_vtbl = (char*)malloc(vtbl_list_size * sizeof(void*)); memmove(saved_vtbl, vtbl_list, vtbl_list_size * sizeof(void*)); @@ -1304,6 +1359,19 @@ return JNI_OK; } +void* CompactingPermGenGen::find_matching_vtbl_ptr(void** vtbl_list, + void* new_vtable_start, + void* obj) { + void* old_vtbl_ptr = *(void**)obj; + for (int i = 0; i < vtbl_list_size; i++) { + if (vtbl_list[i] == old_vtbl_ptr) { + return (void**)new_vtable_start + i * num_virtuals; + } + } + ShouldNotReachHere(); + return NULL; +} + class LinkClassesClosure : public ObjectClosure { private: @@ -1431,8 +1499,7 @@ computed_jsum = jsum(computed_jsum, class_name, (const int)name_len - 1); // Got a class name - load it. - symbolHandle class_name_symbol = oopFactory::new_symbol(class_name, - THREAD); + TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name, THREAD); guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol."); klassOop klass = SystemDictionary::resolve_or_null(class_name_symbol, THREAD); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/genCollectedHeap.cpp --- a/src/share/vm/memory/genCollectedHeap.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/genCollectedHeap.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -875,10 +875,7 @@ void GenCollectedHeap::collect_locked(GCCause::Cause cause, int max_level) { if (_preloading_shared_classes) { - warning("\nThe permanent generation is not large enough to preload " - "requested classes.\nUse -XX:PermSize= to increase the initial " - "size of the permanent generation.\n"); - vm_exit(2); + report_out_of_shared_space(SharedPermGen); } // Read the GC count while holding the Heap_lock unsigned int gc_count_before = total_collections(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/genMarkSweep.cpp --- a/src/share/vm/memory/genMarkSweep.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/genMarkSweep.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -296,9 +296,10 @@ follow_mdo_weak_refs(); assert(_marking_stack.is_empty(), "just drained"); - // Visit symbol and interned string tables and delete unmarked oops - SymbolTable::unlink(&is_alive); + // Visit interned string tables and delete unmarked oops StringTable::unlink(&is_alive); + // Clean up unreferenced symbols in symbol table. + SymbolTable::unlink(); assert(_marking_stack.is_empty(), "stack should be empty by now"); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/heapInspection.cpp --- a/src/share/vm/memory/heapInspection.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/heapInspection.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -56,7 +56,6 @@ if (_klass == Universe::objArrayKlassKlassObj()) name = ""; else if (_klass == Universe::instanceKlassKlassObj()) name = ""; else if (_klass == Universe::typeArrayKlassKlassObj()) name = ""; else - if (_klass == Universe::symbolKlassObj()) name = ""; else if (_klass == Universe::boolArrayKlassObj()) name = ""; else if (_klass == Universe::charArrayKlassObj()) name = ""; else if (_klass == Universe::singleArrayKlassObj()) name = ""; else diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/iterator.hpp --- a/src/share/vm/memory/iterator.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/iterator.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -290,6 +290,22 @@ virtual void do_tag(int tag) = 0; }; +class SymbolClosure : public StackObj { + public: + virtual void do_symbol(Symbol**) = 0; + + // Clear LSB in symbol address; it can be set by CPSlot. + static Symbol* load_symbol(Symbol** p) { + return (Symbol*)(intptr_t(*p) & ~1); + } + + // Store symbol, adjusting new pointer if the original pointer was adjusted + // (symbol references in constant pool slots have their LSB set to 1). + static void store_symbol(Symbol** p, Symbol* sym) { + *p = (Symbol*)(intptr_t(sym) | (intptr_t(*p) & 1)); + } +}; + #ifdef ASSERT // This class is used to flag phases of a collection that // can unload classes and which should override the diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/oopFactory.hpp --- a/src/share/vm/memory/oopFactory.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/oopFactory.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -64,34 +64,6 @@ static typeArrayOop new_typeArray(BasicType type, int length, TRAPS); - // Symbols - static symbolOop new_symbol(const char* utf8_buffer, int length, TRAPS) { - assert(utf8_buffer != NULL, "just checking"); - return SymbolTable::lookup(utf8_buffer, length, CHECK_NULL); - } - static void new_symbols(constantPoolHandle cp, int names_count, - const char** name, int* lengths, - int* cp_indices, unsigned int* hashValues, - TRAPS) { - SymbolTable::add(cp, names_count, name, lengths, cp_indices, - hashValues, CHECK); - } - - static symbolOop new_symbol(char* name, TRAPS) { return new_symbol(name, (int)strlen(name), CHECK_NULL); } - static symbolOop new_symbol(const char* name, TRAPS) { return new_symbol(name, (int)strlen(name), CHECK_NULL); } - static symbolOop new_symbol(symbolHandle sym, int begin, int end, TRAPS) { - assert(begin <= end && end <= sym->utf8_length(), "just checking"); - return SymbolTable::lookup(sym, begin, end, CHECK_NULL); - } - - // Create symbols as above but return a handle - static symbolHandle new_symbol_handle(const char* name, int length, TRAPS) { - symbolOop sym = new_symbol(name, length, THREAD); - return symbolHandle(THREAD, sym); - } - static symbolHandle new_symbol_handle(char* name, TRAPS) { return new_symbol_handle(name, (int)strlen(name), CHECK_(symbolHandle())); } - static symbolHandle new_symbol_handle(const char* name, TRAPS) { return new_symbol_handle(name, (int)strlen(name), CHECK_(symbolHandle())); } - // Constant pools static constantPoolOop new_constantPool (int length, bool is_conc_safe, diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/restore.cpp --- a/src/share/vm/memory/restore.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/restore.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -107,15 +107,23 @@ // Skip over (reserve space for) a list of addresses of C++ vtables // for Klass objects. They get filled in later. + void** vtbl_list = (void**)buffer; + buffer += vtbl_list_size * sizeof(void*); + Universe::init_self_patching_vtbl_list(vtbl_list, vtbl_list_size); + // Skip over (reserve space for) dummy C++ vtables Klass objects. // They are used as is. - void** vtbl_list = (void**)buffer; - buffer += vtbl_list_size * sizeof(void*); intptr_t vtable_size = *(intptr_t*)buffer; buffer += sizeof(intptr_t); buffer += vtable_size; + // Skip the recorded symbols. + + intptr_t total_symbol_size = *(intptr_t*)buffer; + buffer += sizeof(intptr_t) * 2; + buffer += total_symbol_size; + // Create the symbol table using the bucket array at this spot in the // misc data space. Since the symbol table is often modified, this // region (of mapped pages) will be copy-on-write. diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/serialize.cpp --- a/src/share/vm/memory/serialize.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/serialize.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -61,7 +61,7 @@ soc->do_tag(sizeof(constantPoolCacheOopDesc)); soc->do_tag(objArrayOopDesc::base_offset_in_bytes()); soc->do_tag(typeArrayOopDesc::base_offset_in_bytes(T_BYTE)); - soc->do_tag(sizeof(symbolOopDesc)); + soc->do_tag(sizeof(Symbol)); soc->do_tag(sizeof(klassOopDesc)); soc->do_tag(sizeof(markOopDesc)); soc->do_tag(sizeof(compiledICHolderOopDesc)); @@ -83,8 +83,12 @@ // Dump/restore miscellaneous oops. Universe::oops_do(soc, true); soc->do_tag(--tag); + CodeCache::oops_do(soc); + soc->do_tag(--tag); - vmSymbols::oops_do(soc, true); soc->do_tag(--tag); - CodeCache::oops_do(soc); soc->do_tag(--tag); + // Dump/restore references to commonly used names and signatures. + vmSymbols::serialize(soc); + soc->do_tag(--tag); + soc->do_tag(666); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/sharedHeap.cpp --- a/src/share/vm/memory/sharedHeap.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/sharedHeap.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -46,7 +46,6 @@ SH_PS_Management_oops_do, SH_PS_SystemDictionary_oops_do, SH_PS_jvmti_oops_do, - SH_PS_vmSymbols_oops_do, SH_PS_SymbolTable_oops_do, SH_PS_StringTable_oops_do, SH_PS_CodeCache_oops_do, @@ -169,11 +168,6 @@ } if (!_process_strong_tasks->is_task_claimed(SH_PS_SymbolTable_oops_do)) { - if (so & SO_Symbols) { - SymbolTable::oops_do(roots); - } - // Verify if the symbol table contents are in the perm gen - NOT_PRODUCT(SymbolTable::oops_do(&assert_is_perm_closure)); } if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) { @@ -210,20 +204,6 @@ NOT_PRODUCT(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_perm)); } - // Roots that should point only into permanent generation. - { - OopClosure* blk = NULL; - if (collecting_perm_gen) { - blk = roots; - } else { - debug_only(blk = &assert_is_perm_closure); - } - if (blk != NULL) { - if (!_process_strong_tasks->is_task_claimed(SH_PS_vmSymbols_oops_do)) - vmSymbols::oops_do(blk); - } - } - if (!collecting_perm_gen) { // All threads perform this; coordination is handled internally. @@ -273,7 +253,6 @@ JNIHandles::weak_oops_do(&always_true, root_closure); CodeCache::blobs_do(code_roots); - SymbolTable::oops_do(root_closure); if (UseSharedSpaces && !DumpSharedSpaces) { SkipAdjustingSharedStrings skip_closure(root_closure); StringTable::oops_do(&skip_closure); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/universe.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -59,7 +59,6 @@ #include "oops/methodKlass.hpp" #include "oops/objArrayKlassKlass.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolKlass.hpp" #include "oops/typeArrayKlass.hpp" #include "oops/typeArrayKlassKlass.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" @@ -108,7 +107,6 @@ klassOop Universe::_doubleArrayKlassObj = NULL; klassOop Universe::_typeArrayKlassObjs[T_VOID+1] = { NULL /*, NULL...*/ }; klassOop Universe::_objectArrayKlassObj = NULL; -klassOop Universe::_symbolKlassObj = NULL; klassOop Universe::_methodKlassObj = NULL; klassOop Universe::_constMethodKlassObj = NULL; klassOop Universe::_methodDataKlassObj = NULL; @@ -155,7 +153,6 @@ oop Universe::_arithmetic_exception_instance = NULL; oop Universe::_virtual_machine_error_instance = NULL; oop Universe::_vm_exception = NULL; -oop Universe::_emptySymbol = NULL; // These variables are guarded by FullGCALot_lock. debug_only(objArrayOop Universe::_fullgc_alot_dummy_array = NULL;) @@ -190,7 +187,6 @@ void Universe::system_classes_do(void f(klassOop)) { - f(symbolKlassObj()); f(methodKlassObj()); f(constMethodKlassObj()); f(methodDataKlassObj()); @@ -242,7 +238,6 @@ } } } - f->do_oop((oop*)&_symbolKlassObj); f->do_oop((oop*)&_methodKlassObj); f->do_oop((oop*)&_constMethodKlassObj); f->do_oop((oop*)&_methodDataKlassObj); @@ -279,7 +274,6 @@ f->do_oop((oop*)&_main_thread_group); f->do_oop((oop*)&_system_thread_group); f->do_oop((oop*)&_vm_exception); - f->do_oop((oop*)&_emptySymbol); debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);) } @@ -312,10 +306,6 @@ _instanceKlassKlassObj = instanceKlassKlass::create_klass(CHECK); _typeArrayKlassKlassObj = typeArrayKlassKlass::create_klass(CHECK); - _symbolKlassObj = symbolKlass::create_klass(CHECK); - - _emptySymbol = oopFactory::new_symbol("", CHECK); - _boolArrayKlassObj = typeArrayKlass::create_klass(T_BOOLEAN, sizeof(jboolean), CHECK); _charArrayKlassObj = typeArrayKlass::create_klass(T_CHAR, sizeof(jchar), CHECK); _singleArrayKlassObj = typeArrayKlass::create_klass(T_FLOAT, sizeof(jfloat), CHECK); @@ -349,13 +339,6 @@ _the_empty_system_obj_array = oopFactory::new_system_objArray(0, CHECK); _the_array_interfaces_array = oopFactory::new_system_objArray(2, CHECK); - _vm_exception = oopFactory::new_symbol("vm exception holder", CHECK); - } else { - FileMapInfo *mapinfo = FileMapInfo::current_info(); - char* buffer = mapinfo->region_base(CompactingPermGenGen::md); - void** vtbl_list = (void**)buffer; - init_self_patching_vtbl_list(vtbl_list, - CompactingPermGenGen::vtbl_list_size); } } @@ -449,15 +432,15 @@ if (JDK_Version::is_partially_initialized()) { uint8_t jdk_version; klassOop k = SystemDictionary::resolve_or_null( - vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD); + vmSymbols::java_lang_management_MemoryUsage(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { k = SystemDictionary::resolve_or_null( - vmSymbolHandles::java_lang_CharSequence(), THREAD); + vmSymbols::java_lang_CharSequence(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { k = SystemDictionary::resolve_or_null( - vmSymbolHandles::java_lang_Shutdown(), THREAD); + vmSymbols::java_lang_Shutdown(), THREAD); CLEAR_PENDING_EXCEPTION; // ignore exceptions if (k == NULL) { jdk_version = 2; @@ -520,11 +503,16 @@ } -static inline void add_vtable(void** list, int* n, Klass* o, int count) { - list[(*n)++] = *(void**)&o->vtbl_value(); - guarantee((*n) <= count, "vtable list too small."); +static inline void* dereference(void* addr) { + return *(void**)addr; } +static inline void add_vtable(void** list, int* n, void* o, int count) { + guarantee((*n) < count, "vtable list too small"); + void* vtable = dereference(o); + assert(dereference(vtable) != NULL, "invalid vtable"); + list[(*n)++] = vtable; +} void Universe::init_self_patching_vtbl_list(void** list, int count) { int n = 0; @@ -535,7 +523,6 @@ { instanceKlass o; add_vtable(list, &n, &o, count); } { instanceRefKlass o; add_vtable(list, &n, &o, count); } { typeArrayKlassKlass o; add_vtable(list, &n, &o, count); } - { symbolKlass o; add_vtable(list, &n, &o, count); } { typeArrayKlass o; add_vtable(list, &n, &o, count); } { methodKlass o; add_vtable(list, &n, &o, count); } { constMethodKlass o; add_vtable(list, &n, &o, count); } @@ -544,6 +531,11 @@ { objArrayKlass o; add_vtable(list, &n, &o, count); } { methodDataKlass o; add_vtable(list, &n, &o, count); } { compiledICHolderKlass o; add_vtable(list, &n, &o, count); } +#ifndef PRODUCT + // In non-product builds CHeapObj is derived from AllocatedObj, + // so symbols in CDS archive should have their vtable pointer patched. + { Symbol o; add_vtable(list, &n, &o, count); } +#endif } @@ -633,8 +625,8 @@ JavaCalls::call_static( &result, finalizer_klass, - vmSymbolHandles::run_finalizers_on_exit_name(), - vmSymbolHandles::void_method_signature(), + vmSymbols::run_finalizers_on_exit_name(), + vmSymbols::void_method_signature(), THREAD ); // Ignore any pending exceptions @@ -1037,7 +1029,7 @@ // Setup preallocated empty java.lang.Class array Universe::_the_empty_class_klass_array = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_false); // Setup preallocated OutOfMemoryError errors - k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_OutOfMemoryError(), true, CHECK_false); + k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false); k_h = instanceKlassHandle(THREAD, k); Universe::_out_of_memory_error_java_heap = k_h->allocate_permanent_instance(CHECK_false); Universe::_out_of_memory_error_perm_gen = k_h->allocate_permanent_instance(CHECK_false); @@ -1047,15 +1039,15 @@ // Setup preallocated NullPointerException // (this is currently used for a cheap & dirty solution in compiler exception handling) - k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_NullPointerException(), true, CHECK_false); + k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_NullPointerException(), true, CHECK_false); Universe::_null_ptr_exception_instance = instanceKlass::cast(k)->allocate_permanent_instance(CHECK_false); // Setup preallocated ArithmeticException // (this is currently used for a cheap & dirty solution in compiler exception handling) - k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_ArithmeticException(), true, CHECK_false); + k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ArithmeticException(), true, CHECK_false); Universe::_arithmetic_exception_instance = instanceKlass::cast(k)->allocate_permanent_instance(CHECK_false); // Virtual Machine Error for when we get into a situation we can't resolve k = SystemDictionary::resolve_or_fail( - vmSymbolHandles::java_lang_VirtualMachineError(), true, CHECK_false); + vmSymbols::java_lang_VirtualMachineError(), true, CHECK_false); bool linked = instanceKlass::cast(k)->link_class_or_fail(CHECK_false); if (!linked) { tty->print_cr("Unable to link/verify VirtualMachineError class"); @@ -1063,6 +1055,9 @@ } Universe::_virtual_machine_error_instance = instanceKlass::cast(k)->allocate_permanent_instance(CHECK_false); + + Universe::_vm_exception = instanceKlass::cast(k)->allocate_permanent_instance(CHECK_false); + } if (!DumpSharedSpaces) { // These are the only Java fields that are currently set during shared space dumping. @@ -1117,7 +1112,7 @@ // Note: No race-condition here, since a resolve will always return the same result // Setup method for security checks - k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_reflect_Method(), true, CHECK_false); + k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_reflect_Method(), true, CHECK_false); k_h = instanceKlassHandle(THREAD, k); k_h->link_class(CHECK_false); m = k_h->find_method(vmSymbols::invoke_name(), vmSymbols::object_object_array_object_signature()); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/memory/universe.hpp --- a/src/share/vm/memory/universe.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/memory/universe.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -139,7 +139,6 @@ static klassOop _objectArrayKlassObj; - static klassOop _symbolKlassObj; static klassOop _methodKlassObj; static klassOop _constMethodKlassObj; static klassOop _methodDataKlassObj; @@ -198,8 +197,6 @@ // the vm thread. static oop _vm_exception; - static oop _emptySymbol; // Canonical empty string ("") symbol - // The particular choice of collected heap. static CollectedHeap* _collectedHeap; @@ -273,7 +270,6 @@ return _typeArrayKlassObjs[t]; } - static klassOop symbolKlassObj() { return _symbolKlassObj; } static klassOop methodKlassObj() { return _methodKlassObj; } static klassOop constMethodKlassObj() { return _constMethodKlassObj; } static klassOop methodDataKlassObj() { return _methodDataKlassObj; } @@ -287,9 +283,8 @@ static klassOop compiledICHolderKlassObj() { return _compiledICHolderKlassObj; } static klassOop systemObjArrayKlassObj() { return _systemObjArrayKlassObj; } - // Known objects in tbe VM - static oop int_mirror() { return check_mirror(_int_mirror); -} + // Known objects in the VM + static oop int_mirror() { return check_mirror(_int_mirror); } static oop float_mirror() { return check_mirror(_float_mirror); } static oop double_mirror() { return check_mirror(_double_mirror); } static oop byte_mirror() { return check_mirror(_byte_mirror); } @@ -327,7 +322,6 @@ static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; } static oop vm_exception() { return _vm_exception; } - static oop emptySymbol() { return _emptySymbol; } // OutOfMemoryError support. Returns an error with the required message. The returned error // may or may not have a backtrace. If error has a backtrace then the stack trace is already diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/arrayKlass.cpp --- a/src/share/vm/oops/arrayKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/arrayKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -64,7 +64,7 @@ return NULL; } -methodOop arrayKlass::uncached_lookup_method(symbolOop name, symbolOop signature) const { +methodOop arrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { // There are no methods in an array klass but the super class (Object) has some assert(super(), "super klass must be present"); return Klass::cast(super())->uncached_lookup_method(name, signature); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/arrayKlass.hpp --- a/src/share/vm/oops/arrayKlass.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/arrayKlass.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -84,7 +84,7 @@ objArrayOop allocate_arrayArray(int n, int length, TRAPS); // Lookup operations - methodOop uncached_lookup_method(symbolOop name, symbolOop signature) const; + methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const; // Casting from klassOop static arrayKlass* cast(klassOop k) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/arrayOop.cpp --- a/src/share/vm/oops/arrayOop.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/arrayOop.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -26,6 +26,6 @@ #include "oops/arrayOop.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" // <> diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/constantPoolKlass.cpp --- a/src/share/vm/oops/constantPoolKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/constantPoolKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -33,7 +33,7 @@ #include "oops/constantPoolOop.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" #ifdef TARGET_OS_FAMILY_linux # include "thread_linux.inline.hpp" @@ -388,8 +388,12 @@ case JVM_CONSTANT_UnresolvedClass : // fall-through case JVM_CONSTANT_UnresolvedClassInError: { // unresolved_klass_at requires lock or safe world. - oop entry = *cp->obj_at_addr(index); - entry->print_value_on(st); + CPSlot entry = cp->slot_at(index); + if (entry.is_oop()) { + entry.get_oop()->print_value_on(st); + } else { + entry.get_symbol()->print_value_on(st); + } } break; case JVM_CONSTANT_MethodHandle : @@ -450,36 +454,43 @@ constantPoolOop cp = constantPoolOop(obj); guarantee(cp->is_perm(), "should be in permspace"); if (!cp->partially_loaded()) { - oop* base = (oop*)cp->base(); for (int i = 0; i< cp->length(); i++) { + CPSlot entry = cp->slot_at(i); if (cp->tag_at(i).is_klass()) { - guarantee((*base)->is_perm(), "should be in permspace"); - guarantee((*base)->is_klass(), "should be klass"); + if (entry.is_oop()) { + guarantee(entry.get_oop()->is_perm(), "should be in permspace"); + guarantee(entry.get_oop()->is_klass(), "should be klass"); + } } if (cp->tag_at(i).is_unresolved_klass()) { - guarantee((*base)->is_perm(), "should be in permspace"); - guarantee((*base)->is_symbol() || (*base)->is_klass(), - "should be symbol or klass"); + if (entry.is_oop()) { + guarantee(entry.get_oop()->is_perm(), "should be in permspace"); + guarantee(entry.get_oop()->is_klass(), "should be klass"); + } } if (cp->tag_at(i).is_symbol()) { - guarantee((*base)->is_perm(), "should be in permspace"); - guarantee((*base)->is_symbol(), "should be symbol"); + guarantee(entry.get_symbol()->refcount() != 0, "should have nonzero reference count"); } if (cp->tag_at(i).is_unresolved_string()) { - guarantee((*base)->is_perm(), "should be in permspace"); - guarantee((*base)->is_symbol() || (*base)->is_instance(), - "should be symbol or instance"); + if (entry.is_oop()) { + guarantee(entry.get_oop()->is_perm(), "should be in permspace"); + guarantee(entry.get_oop()->is_instance(), "should be instance"); + } + else { + guarantee(entry.get_symbol()->refcount() != 0, "should have nonzero reference count"); + } } if (cp->tag_at(i).is_string()) { if (!cp->has_pseudo_string()) { - guarantee((*base)->is_perm(), "should be in permspace"); - guarantee((*base)->is_instance(), "should be instance"); + if (entry.is_oop()) { + guarantee(entry.get_oop()->is_perm(), "should be in permspace"); + guarantee(entry.get_oop()->is_instance(), "should be instance"); + } } else { // can be non-perm, can be non-instance (array) } } // FIXME: verify JSR 292 tags JVM_CONSTANT_MethodHandle, etc. - base++; } guarantee(cp->tags()->is_perm(), "should be in permspace"); guarantee(cp->tags()->is_typeArray(), "should be type array"); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/constantPoolOop.cpp --- a/src/share/vm/oops/constantPoolOop.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/constantPoolOop.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -52,13 +52,14 @@ } klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) { - // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop. + // A resolved constantPool entry will contain a klassOop, otherwise a Symbol*. // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and // tag is not updated atomicly. - oop entry = *(this_oop->obj_at_addr(which)); - if (entry->is_klass()) { + CPSlot entry = this_oop->slot_at(which); + if (entry.is_oop()) { + assert(entry.get_oop()->is_klass(), "must be"); // Already resolved - return entry. - return (klassOop)entry; + return (klassOop)entry.get_oop(); } // Acquire lock on constant oop while doing update. After we get the lock, we check if another object @@ -67,7 +68,7 @@ bool do_resolve = false; bool in_error = false; - symbolHandle name; + Symbol* name = NULL; Handle loader; { ObjectLocker ol(this_oop, THREAD); @@ -76,7 +77,7 @@ in_error = true; } else { do_resolve = true; - name = symbolHandle(THREAD, this_oop->unresolved_klass_at(which)); + name = this_oop->unresolved_klass_at(which); loader = Handle(THREAD, instanceKlass::cast(this_oop->pool_holder())->class_loader()); } } @@ -86,8 +87,8 @@ // The original attempt to resolve this constant pool entry failed so find the // original error and throw it again (JVMS 5.4.3). if (in_error) { - symbolOop error = SystemDictionary::find_resolution_error(this_oop, which); - guarantee(error != (symbolOop)NULL, "tag mismatch with resolution error table"); + Symbol* error = SystemDictionary::find_resolution_error(this_oop, which); + guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table"); ResourceMark rm; // exception text will be the class name const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); @@ -110,7 +111,7 @@ // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). if (HAS_PENDING_EXCEPTION) { ResourceMark rm; - symbolHandle error(PENDING_EXCEPTION->klass()->klass_part()->name()); + Symbol* error = PENDING_EXCEPTION->klass()->klass_part()->name(); bool throw_orig_error = false; { @@ -120,7 +121,7 @@ if (this_oop->tag_at(which).is_klass()) { CLEAR_PENDING_EXCEPTION; entry = this_oop->resolved_klass_at(which); - return (klassOop)entry; + return (klassOop)entry.get_oop(); } if (!PENDING_EXCEPTION-> @@ -135,8 +136,8 @@ this_oop->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError); } else { // some other thread has put the class in error state. - error = symbolHandle(SystemDictionary::find_resolution_error(this_oop, which)); - assert(!error.is_null(), "checking"); + error = SystemDictionary::find_resolution_error(this_oop, which); + assert(error != NULL, "checking"); throw_orig_error = true; } } // unlocked @@ -162,7 +163,7 @@ vframeStream vfst(JavaThread::current()); if (!vfst.at_end()) { line_number = vfst.method()->line_number_from_bci(vfst.bci()); - symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); + Symbol* s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); if (s != NULL) { source_file = s->as_C_string(); } @@ -192,8 +193,8 @@ } entry = this_oop->resolved_klass_at(which); - assert(entry->is_klass(), "must be resolved at this point"); - return (klassOop)entry; + assert(entry.is_oop() && entry.get_oop()->is_klass(), "must be resolved at this point"); + return (klassOop)entry.get_oop(); } @@ -202,13 +203,14 @@ // instanceof operations. Returns NULL if the class has not been loaded or // if the verification of constant pool failed klassOop constantPoolOopDesc::klass_at_if_loaded(constantPoolHandle this_oop, int which) { - oop entry = *this_oop->obj_at_addr(which); - if (entry->is_klass()) { - return (klassOop)entry; + CPSlot entry = this_oop->slot_at(which); + if (entry.is_oop()) { + assert(entry.get_oop()->is_klass(), "must be"); + return (klassOop)entry.get_oop(); } else { - assert(entry->is_symbol(), "must be either symbol or klass"); + assert(entry.is_metadata(), "must be either symbol or klass"); Thread *thread = Thread::current(); - symbolHandle name (thread, (symbolOop)entry); + Symbol* name = entry.get_symbol(); oop loader = instanceKlass::cast(this_oop->pool_holder())->class_loader(); oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); Handle h_prot (thread, protection_domain); @@ -244,12 +246,13 @@ // Note: We cannot update the ConstantPool from the vm_thread. klassOop constantPoolOopDesc::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int index, TRAPS) { int which = this_oop->klass_ref_index_at(index); - oop entry = *this_oop->obj_at_addr(which); - if (entry->is_klass()) { - return (klassOop)entry; + CPSlot entry = this_oop->slot_at(which); + if (entry.is_oop()) { + assert(entry.get_oop()->is_klass(), "must be"); + return (klassOop)entry.get_oop(); } else { - assert(entry->is_symbol(), "must be either symbol or klass"); - symbolHandle name (THREAD, (symbolOop)entry); + assert(entry.is_metadata(), "must be either symbol or klass"); + Symbol* name = entry.get_symbol(); oop loader = instanceKlass::cast(this_oop->pool_holder())->class_loader(); oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); Handle h_loader(THREAD, loader); @@ -263,13 +266,13 @@ } -symbolOop constantPoolOopDesc::impl_name_ref_at(int which, bool uncached) { +Symbol* constantPoolOopDesc::impl_name_ref_at(int which, bool uncached) { int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached)); return symbol_at(name_index); } -symbolOop constantPoolOopDesc::impl_signature_ref_at(int which, bool uncached) { +Symbol* constantPoolOopDesc::impl_signature_ref_at(int which, bool uncached) { int signature_index = signature_ref_index_at(impl_name_and_type_ref_index_at(which, uncached)); return symbol_at(signature_index); } @@ -361,39 +364,40 @@ } -symbolOop constantPoolOopDesc::klass_name_at(int which) { +Symbol* constantPoolOopDesc::klass_name_at(int which) { assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(), "Corrupted constant pool"); - // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop. + // A resolved constantPool entry will contain a klassOop, otherwise a Symbol*. // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and // tag is not updated atomicly. - oop entry = *(obj_at_addr(which)); - if (entry->is_klass()) { + CPSlot entry = slot_at(which); + if (entry.is_oop()) { // Already resolved - return entry's name. - return klassOop(entry)->klass_part()->name(); + assert(entry.get_oop()->is_klass(), "must be"); + return klassOop(entry.get_oop())->klass_part()->name(); } else { - assert(entry->is_symbol(), "must be either symbol or klass"); - return (symbolOop)entry; + assert(entry.is_metadata(), "must be either symbol or klass"); + return entry.get_symbol(); } } -symbolOop constantPoolOopDesc::klass_ref_at_noresolve(int which) { +Symbol* constantPoolOopDesc::klass_ref_at_noresolve(int which) { jint ref_index = klass_ref_index_at(which); return klass_at_noresolve(ref_index); } -symbolOop constantPoolOopDesc::uncached_klass_ref_at_noresolve(int which) { +Symbol* constantPoolOopDesc::uncached_klass_ref_at_noresolve(int which) { jint ref_index = uncached_klass_ref_index_at(which); return klass_at_noresolve(ref_index); } char* constantPoolOopDesc::string_at_noresolve(int which) { // Test entry type in case string is resolved while in here. - oop entry = *(obj_at_addr(which)); - if (entry->is_symbol()) { - return ((symbolOop)entry)->as_C_string(); - } else if (java_lang_String::is_instance(entry)) { - return java_lang_String::as_utf8_string(entry); + CPSlot entry = slot_at(which); + if (entry.is_metadata()) { + return (entry.get_symbol())->as_C_string(); + } else if (java_lang_String::is_instance(entry.get_oop())) { + return java_lang_String::as_utf8_string(entry.get_oop()); } else { return (char*)""; } @@ -498,8 +502,8 @@ { int ref_kind = this_oop->method_handle_ref_kind_at(index); int callee_index = this_oop->method_handle_klass_index_at(index); - symbolHandle name(THREAD, this_oop->method_handle_name_ref_at(index)); - symbolHandle signature(THREAD, this_oop->method_handle_signature_ref_at(index)); + Symbol* name = this_oop->method_handle_name_ref_at(index); + Symbol* signature = this_oop->method_handle_signature_ref_at(index); if (PrintMiscellaneous) tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s", ref_kind, index, this_oop->method_handle_index_at(index), @@ -524,7 +528,7 @@ case JVM_CONSTANT_MethodType: { - symbolHandle signature(THREAD, this_oop->method_type_signature_at(index)); + Symbol* signature = this_oop->method_type_signature_at(index); if (PrintMiscellaneous) tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s", index, this_oop->method_type_index_at(index), @@ -605,30 +609,33 @@ } oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { - oop entry = *(this_oop->obj_at_addr(which)); - if (entry->is_symbol()) { + oop str = NULL; + CPSlot entry = this_oop->slot_at(which); + if (entry.is_metadata()) { ObjectLocker ol(this_oop, THREAD); if (this_oop->tag_at(which).is_unresolved_string()) { // Intern string - symbolOop sym = this_oop->unresolved_string_at(which); - entry = StringTable::intern(sym, CHECK_(constantPoolOop(NULL))); - this_oop->string_at_put(which, entry); + Symbol* sym = this_oop->unresolved_string_at(which); + str = StringTable::intern(sym, CHECK_(constantPoolOop(NULL))); + this_oop->string_at_put(which, str); } else { // Another thread beat us and interned string, read string from constant pool - entry = this_oop->resolved_string_at(which); + str = this_oop->resolved_string_at(which); } + } else { + str = entry.get_oop(); } - assert(java_lang_String::is_instance(entry), "must be string"); - return entry; + assert(java_lang_String::is_instance(str), "must be string"); + return str; } bool constantPoolOopDesc::is_pseudo_string_at(int which) { - oop entry = *(obj_at_addr(which)); - if (entry->is_symbol()) + CPSlot entry = slot_at(which); + if (entry.is_metadata()) // Not yet resolved, but it will resolve to a string. return false; - else if (java_lang_String::is_instance(entry)) + else if (java_lang_String::is_instance(entry.get_oop())) return false; // actually, it might be a non-interned or non-perm string else // truly pseudo @@ -638,8 +645,8 @@ bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k, int which) { - // Names are interned, so we can compare symbolOops directly - symbolOop cp_name = klass_name_at(which); + // Names are interned, so we can compare Symbol*s directly + Symbol* cp_name = klass_name_at(which); return (cp_name == k->name()); } @@ -650,7 +657,7 @@ for (int index = 1; index < tags()->length(); index++) { // Index 0 is unused if (tag_at(index).is_unresolved_string()) { // Intern string - symbolOop sym = unresolved_string_at(index); + Symbol* sym = unresolved_string_at(index); oop entry = StringTable::intern(sym, CHECK_(-1)); string_at_put(index, entry); } @@ -658,23 +665,39 @@ return count; } +// Iterate over symbols and decrement ones which are Symbol*s. +// This is done during GC so do not need to lock constantPool unless we +// have per-thread safepoints. +// Only decrement the UTF8 symbols. Unresolved classes and strings point to +// these symbols but didn't increment the reference count. +void constantPoolOopDesc::unreference_symbols() { + for (int index = 1; index < length(); index++) { // Index 0 is unused + constantTag tag = tag_at(index); + if (tag.is_symbol()) { + symbol_at(index)->decrement_refcount(); + } + } +} // Iterate over symbols which are used as class, field, method names and // signatures (in preparation for writing to the shared archive). -void constantPoolOopDesc::shared_symbols_iterate(OopClosure* closure) { +void constantPoolOopDesc::shared_symbols_iterate(SymbolClosure* closure) { for (int index = 1; index < length(); index++) { // Index 0 is unused switch (tag_at(index).value()) { case JVM_CONSTANT_UnresolvedClass: - closure->do_oop(obj_at_addr(index)); + case JVM_CONSTANT_UnresolvedString: + case JVM_CONSTANT_Utf8: + assert(slot_at(index).is_metadata(), "must be symbol"); + closure->do_symbol(symbol_at_addr(index)); break; case JVM_CONSTANT_NameAndType: { int i = *int_at_addr(index); - closure->do_oop(obj_at_addr((unsigned)i >> 16)); - closure->do_oop(obj_at_addr((unsigned)i & 0xffff)); + closure->do_symbol(symbol_at_addr((unsigned)i >> 16)); + closure->do_symbol(symbol_at_addr((unsigned)i & 0xffff)); } break; @@ -692,12 +715,6 @@ // Do nothing! Not a symbol. break; - case JVM_CONSTANT_UnresolvedString: - case JVM_CONSTANT_Utf8: - // These constants are symbols, but unless these symbols are - // actually to be used for something, we don't want to mark them. - break; - case JVM_CONSTANT_Long: case JVM_CONSTANT_Double: // Do nothing! Not an oop. (But takes two pool entries.) @@ -744,7 +761,7 @@ break; case JVM_CONSTANT_String: - closure->do_oop(obj_at_addr(index)); + closure->do_oop(obj_at_addr_raw(index)); break; case JVM_CONSTANT_UnresolvedString: @@ -904,8 +921,8 @@ case JVM_CONSTANT_UnresolvedClass: { - symbolOop k1 = unresolved_klass_at(index1); - symbolOop k2 = cp2->unresolved_klass_at(index2); + Symbol* k1 = unresolved_klass_at(index1); + Symbol* k2 = cp2->unresolved_klass_at(index2); if (k1 == k2) { return true; } @@ -960,8 +977,8 @@ case JVM_CONSTANT_UnresolvedString: { - symbolOop s1 = unresolved_string_at(index1); - symbolOop s2 = cp2->unresolved_string_at(index2); + Symbol* s1 = unresolved_string_at(index1); + Symbol* s2 = cp2->unresolved_string_at(index2); if (s1 == s2) { return true; } @@ -969,8 +986,8 @@ case JVM_CONSTANT_Utf8: { - symbolOop s1 = symbol_at(index1); - symbolOop s2 = cp2->symbol_at(index2); + Symbol* s1 = symbol_at(index1); + Symbol* s2 = cp2->symbol_at(index2); if (s1 == s2) { return true; } @@ -1158,13 +1175,13 @@ case JVM_CONSTANT_UnresolvedClass: { - symbolOop k = from_cp->unresolved_klass_at(from_i); + Symbol* k = from_cp->unresolved_klass_at(from_i); to_cp->unresolved_klass_at_put(to_i, k); } break; case JVM_CONSTANT_UnresolvedClassInError: { - symbolOop k = from_cp->unresolved_klass_at(from_i); + Symbol* k = from_cp->unresolved_klass_at(from_i); to_cp->unresolved_klass_at_put(to_i, k); to_cp->tag_at_put(to_i, JVM_CONSTANT_UnresolvedClassInError); } break; @@ -1172,14 +1189,16 @@ case JVM_CONSTANT_UnresolvedString: { - symbolOop s = from_cp->unresolved_string_at(from_i); + Symbol* s = from_cp->unresolved_string_at(from_i); to_cp->unresolved_string_at_put(to_i, s); } break; case JVM_CONSTANT_Utf8: { - symbolOop s = from_cp->symbol_at(from_i); + Symbol* s = from_cp->symbol_at(from_i); to_cp->symbol_at_put(to_i, s); + // This constantPool has the same lifetime as the original, so don't + // increase reference counts for the copy. } break; case JVM_CONSTANT_MethodType: @@ -1453,7 +1472,7 @@ switch(tag) { case JVM_CONSTANT_Utf8: { - symbolOop sym = symbol_at(idx); + Symbol* sym = symbol_at(idx); symmap->add_entry(sym, idx); DBG(printf("adding symbol entry %s = %d\n", sym->as_utf8(), idx)); break; @@ -1461,7 +1480,7 @@ case JVM_CONSTANT_Class: case JVM_CONSTANT_UnresolvedClass: case JVM_CONSTANT_UnresolvedClassInError: { - symbolOop sym = klass_name_at(idx); + Symbol* sym = klass_name_at(idx); classmap->add_entry(sym, idx); DBG(printf("adding class entry %s = %d\n", sym->as_utf8(), idx)); break; @@ -1509,7 +1528,7 @@ break; } case JVM_CONSTANT_Utf8: { - symbolOop sym = symbol_at(idx); + Symbol* sym = symbol_at(idx); char* str = sym->as_utf8(); // Warning! It's crashing on x86 with len = sym->utf8_length() int len = (int) strlen(str); @@ -1546,7 +1565,7 @@ case JVM_CONSTANT_UnresolvedClass: case JVM_CONSTANT_UnresolvedClassInError: { *bytes = JVM_CONSTANT_Class; - symbolOop sym = klass_name_at(idx); + Symbol* sym = klass_name_at(idx); idx1 = tbl->symbol_to_value(sym); assert(idx1 != 0, "Have not found a hashtable entry"); Bytes::put_Java_u2((address) (bytes+1), idx1); @@ -1556,19 +1575,19 @@ case JVM_CONSTANT_String: { unsigned int hash; char *str = string_at_noresolve(idx); - symbolOop sym = SymbolTable::lookup_only(str, (int) strlen(str), hash); + TempNewSymbol sym = SymbolTable::lookup_only(str, (int) strlen(str), hash); if (sym == NULL) { // sym can be NULL if string refers to incorrectly encoded JVM_CONSTANT_Utf8 // this can happen with JVM TI; see CR 6839599 for more details - oop string = *(obj_at_addr(idx)); + oop string = *(obj_at_addr_raw(idx)); assert(java_lang_String::is_instance(string),"Not a String"); DBG(printf("Error #%03hd tag=%03hd\n", idx, tag)); idx1 = 0; for (int j = 0; j < tbl->table_size() && idx1 == 0; j++) { for (SymbolHashMapEntry* cur = tbl->bucket(j); cur != NULL; cur = cur->next()) { int length; - sym = cur->symbol(); - jchar* chars = sym->as_unicode(length); + Symbol* s = cur->symbol(); + jchar* chars = s->as_unicode(length); if (java_lang_String::equals(string, chars, length)) { idx1 = cur->value(); DBG(printf("Index found: %d\n",idx1)); @@ -1586,7 +1605,7 @@ } case JVM_CONSTANT_UnresolvedString: { *bytes = JVM_CONSTANT_String; - symbolOop sym = unresolved_string_at(idx); + Symbol* sym = unresolved_string_at(idx); idx1 = tbl->symbol_to_value(sym); assert(idx1 != 0, "Have not found a hashtable entry"); Bytes::put_Java_u2((address) (bytes+1), idx1); @@ -1666,7 +1685,7 @@ } /* end copy_cpool_bytes */ -void SymbolHashMap::add_entry(symbolOop sym, u2 value) { +void SymbolHashMap::add_entry(Symbol* sym, u2 value) { char *str = sym->as_utf8(); unsigned int hash = compute_hash(str, sym->utf8_length()); unsigned int index = hash % table_size(); @@ -1687,7 +1706,7 @@ assert(entry->symbol() != NULL, "SymbolHashMapEntry symbol is NULL"); } -SymbolHashMapEntry* SymbolHashMap::find_entry(symbolOop sym) { +SymbolHashMapEntry* SymbolHashMap::find_entry(Symbol* sym) { assert(sym != NULL, "SymbolHashMap::find_entry - symbol is NULL"); char *str = sym->as_utf8(); int len = sym->utf8_length(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/constantPoolOop.hpp --- a/src/share/vm/oops/constantPoolOop.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/constantPoolOop.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -27,6 +27,7 @@ #include "oops/arrayOop.hpp" #include "oops/cpCacheOop.hpp" +#include "oops/symbol.hpp" #include "oops/typeArrayOop.hpp" #include "utilities/constantTag.hpp" #ifdef TARGET_ARCH_x86 @@ -47,10 +48,32 @@ // modified when the entry is resolved. If a klass or string constant pool // entry is read without a lock, only the resolved state guarantees that // the entry in the constant pool is a klass or String object and -// not a symbolOop. +// not a Symbol*. class SymbolHashMap; +class CPSlot VALUE_OBJ_CLASS_SPEC { + intptr_t _ptr; + public: + CPSlot(intptr_t ptr): _ptr(ptr) {} + CPSlot(void* ptr): _ptr((intptr_t)ptr) {} + CPSlot(oop ptr): _ptr((intptr_t)ptr) {} + CPSlot(Symbol* ptr): _ptr((intptr_t)ptr | 1) {} + + intptr_t value() { return _ptr; } + bool is_oop() { return (_ptr & 1) == 0; } + bool is_metadata() { return (_ptr & 1) == 1; } + + oop get_oop() { + assert(is_oop(), "bad call"); + return oop(_ptr); + } + Symbol* get_symbol() { + assert(is_metadata(), "bad call"); + return (Symbol*)(_ptr & ~1); + } +}; + class constantPoolOopDesc : public oopDesc { friend class VMStructs; friend class BytecodeInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast @@ -89,11 +112,41 @@ oop* cache_addr() { return (oop*)&_cache; } oop* operands_addr() { return (oop*)&_operands; } - oop* obj_at_addr(int which) const { + CPSlot slot_at(int which) { + assert(is_within_bounds(which), "index out of bounds"); + // There's a transitional value of zero when converting from + // Symbol->0->Klass for G1 when resolving classes and strings. + // wait for the value to be non-zero (this is temporary) + volatile intptr_t adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which)); + if (adr == 0 && which != 0) { + constantTag t = tag_at(which); + if (t.is_unresolved_klass() || t.is_klass() || + t.is_unresolved_string() || t.is_string()) { + while ((adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which))) == 0); + } + } + return CPSlot(adr); + } + + void slot_at_put(int which, CPSlot s) const { + assert(is_within_bounds(which), "index out of bounds"); + *(intptr_t*)&base()[which] = s.value(); + } + oop* obj_at_addr_raw(int which) const { assert(is_within_bounds(which), "index out of bounds"); return (oop*) &base()[which]; } + void obj_at_put_without_check(int which, oop o) { + assert(is_within_bounds(which), "index out of bounds"); + oop_store_without_check((volatile oop *)obj_at_addr_raw(which), o); + } + + void obj_at_put(int which, oop o) const { + assert(is_within_bounds(which), "index out of bounds"); + oop_store((volatile oop*)obj_at_addr_raw(which), o); + } + jint* int_at_addr(int which) const { assert(is_within_bounds(which), "index out of bounds"); return (jint*) &base()[which]; @@ -141,15 +194,20 @@ // Storing constants void klass_at_put(int which, klassOop k) { - oop_store_without_check((volatile oop *)obj_at_addr(which), oop(k)); + // Overwrite the old index with a GC friendly value so + // that if G1 looks during the transition during oop_store it won't + // assert the symbol is not an oop. + *obj_at_addr_raw(which) = NULL; + assert(k != NULL, "resolved class shouldn't be null"); + obj_at_put_without_check(which, k); // The interpreter assumes when the tag is stored, the klass is resolved - // and the klassOop is a klass rather than a symbolOop, so we need + // and the klassOop is a klass rather than a Symbol*, so we need // hardware store ordering here. release_tag_at_put(which, JVM_CONSTANT_Class); if (UseConcMarkSweepGC) { // In case the earlier card-mark was consumed by a concurrent // marking thread before the tag was updated, redirty the card. - oop_store_without_check((volatile oop *)obj_at_addr(which), oop(k)); + obj_at_put_without_check(which, k); } } @@ -160,13 +218,9 @@ } // Temporary until actual use - void unresolved_klass_at_put(int which, symbolOop s) { - // Overwrite the old index with a GC friendly value so - // that if GC looks during the transition it won't try - // to treat a small integer as oop. - *obj_at_addr(which) = NULL; + void unresolved_klass_at_put(int which, Symbol* s) { release_tag_at_put(which, JVM_CONSTANT_UnresolvedClass); - oop_store_without_check(obj_at_addr(which), oop(s)); + slot_at_put(which, s); } void method_handle_index_at_put(int which, int ref_kind, int ref_index) { @@ -191,10 +245,9 @@ } // Temporary until actual use - void unresolved_string_at_put(int which, symbolOop s) { - *obj_at_addr(which) = NULL; + void unresolved_string_at_put(int which, Symbol* s) { release_tag_at_put(which, JVM_CONSTANT_UnresolvedString); - oop_store_without_check(obj_at_addr(which), oop(s)); + slot_at_put(which, s); } void int_at_put(int which, jint i) { @@ -220,28 +273,39 @@ Bytes::put_native_u8((address) double_at_addr(which), *((u8*) &d)); } - void symbol_at_put(int which, symbolOop s) { + Symbol** symbol_at_addr(int which) const { + assert(is_within_bounds(which), "index out of bounds"); + return (Symbol**) &base()[which]; + } + + void symbol_at_put(int which, Symbol* s) { + assert(s->refcount() != 0, "should have nonzero refcount"); tag_at_put(which, JVM_CONSTANT_Utf8); - oop_store_without_check(obj_at_addr(which), oop(s)); + slot_at_put(which, s); } void string_at_put(int which, oop str) { - oop_store((volatile oop*)obj_at_addr(which), str); + // Overwrite the old index with a GC friendly value so + // that if G1 looks during the transition during oop_store it won't + // assert the symbol is not an oop. + *obj_at_addr_raw(which) = NULL; + assert(str != NULL, "resolved string shouldn't be null"); + obj_at_put(which, str); release_tag_at_put(which, JVM_CONSTANT_String); if (UseConcMarkSweepGC) { // In case the earlier card-mark was consumed by a concurrent // marking thread before the tag was updated, redirty the card. - oop_store_without_check((volatile oop *)obj_at_addr(which), str); + obj_at_put_without_check(which, str); } } void object_at_put(int which, oop str) { - oop_store((volatile oop*) obj_at_addr(which), str); + obj_at_put(which, str); release_tag_at_put(which, JVM_CONSTANT_Object); if (UseConcMarkSweepGC) { // In case the earlier card-mark was consumed by a concurrent // marking thread before the tag was updated, redirty the card. - oop_store_without_check((volatile oop*) obj_at_addr(which), str); + obj_at_put_without_check(which, str); } } @@ -279,13 +343,19 @@ bool is_pointer_entry(int which) { constantTag tag = tag_at(which); return tag.is_klass() || - tag.is_unresolved_klass() || - tag.is_symbol() || - tag.is_unresolved_string() || tag.is_string() || tag.is_object(); } + // Whether the entry points to an object for ldc (resolved or not) + bool is_object_entry(int which) { + constantTag tag = tag_at(which); + return is_pointer_entry(which) || + tag.is_unresolved_klass() || + tag.is_unresolved_string() || + tag.is_symbol(); + } + // Fetching constants klassOop klass_at(int which, TRAPS) { @@ -293,25 +363,25 @@ return klass_at_impl(h_this, which, CHECK_NULL); } - symbolOop klass_name_at(int which); // Returns the name, w/o resolving. + Symbol* klass_name_at(int which); // Returns the name, w/o resolving. klassOop resolved_klass_at(int which) { // Used by Compiler guarantee(tag_at(which).is_klass(), "Corrupted constant pool"); // Must do an acquire here in case another thread resolved the klass // behind our back, lest we later load stale values thru the oop. - return klassOop((oop)OrderAccess::load_ptr_acquire(obj_at_addr(which))); + return klassOop(CPSlot(OrderAccess::load_ptr_acquire(obj_at_addr_raw(which))).get_oop()); } // This method should only be used with a cpool lock or during parsing or gc - symbolOop unresolved_klass_at(int which) { // Temporary until actual use - symbolOop s = symbolOop((oop)OrderAccess::load_ptr_acquire(obj_at_addr(which))); + Symbol* unresolved_klass_at(int which) { // Temporary until actual use + Symbol* s = CPSlot(OrderAccess::load_ptr_acquire(obj_at_addr_raw(which))).get_symbol(); // check that the klass is still unresolved. assert(tag_at(which).is_unresolved_klass(), "Corrupted constant pool"); return s; } // RedefineClasses() API support: - symbolOop klass_at_noresolve(int which) { return klass_name_at(which); } + Symbol* klass_at_noresolve(int which) { return klass_name_at(which); } jint int_at(int which) { assert(tag_at(which).is_int(), "Corrupted constant pool"); @@ -336,9 +406,9 @@ return *((jdouble*)&tmp); } - symbolOop symbol_at(int which) { + Symbol* symbol_at(int which) { assert(tag_at(which).is_utf8(), "Corrupted constant pool"); - return symbolOop(*obj_at_addr(which)); + return slot_at(which).get_symbol(); } oop string_at(int which, TRAPS) { @@ -348,7 +418,7 @@ oop object_at(int which) { assert(tag_at(which).is_object(), "Corrupted constant pool"); - return *obj_at_addr(which); + return slot_at(which).get_oop(); } // A "pseudo-string" is an non-string oop that has found is way into @@ -362,7 +432,7 @@ oop pseudo_string_at(int which) { assert(tag_at(which).is_string(), "Corrupted constant pool"); - return *obj_at_addr(which); + return slot_at(which).get_oop(); } void pseudo_string_at_put(int which, oop x) { @@ -378,12 +448,12 @@ assert(tag_at(which).is_string(), "Corrupted constant pool"); // Must do an acquire here in case another thread resolved the klass // behind our back, lest we later load stale values thru the oop. - return (oop)OrderAccess::load_ptr_acquire(obj_at_addr(which)); + return CPSlot(OrderAccess::load_ptr_acquire(obj_at_addr_raw(which))).get_oop(); } // This method should only be used with a cpool lock or during parsing or gc - symbolOop unresolved_string_at(int which) { // Temporary until actual use - symbolOop s = symbolOop((oop)OrderAccess::load_ptr_acquire(obj_at_addr(which))); + Symbol* unresolved_string_at(int which) { // Temporary until actual use + Symbol* s = CPSlot(OrderAccess::load_ptr_acquire(obj_at_addr_raw(which))).get_symbol(); // check that the string is still unresolved. assert(tag_at(which).is_unresolved_string(), "Corrupted constant pool"); return s; @@ -391,7 +461,7 @@ // Returns an UTF8 for a CONSTANT_String entry at a given index. // UTF8 char* representation was chosen to avoid conversion of - // java_lang_Strings at resolved entries into symbolOops + // java_lang_Strings at resolved entries into Symbol*s // or vice versa. // Caller is responsible for checking for pseudo-strings. char* string_at_noresolve(int which); @@ -414,11 +484,11 @@ return *int_at_addr(which); } // Derived queries: - symbolOop method_handle_name_ref_at(int which) { + Symbol* method_handle_name_ref_at(int which) { int member = method_handle_index_at(which); return impl_name_ref_at(member, true); } - symbolOop method_handle_signature_ref_at(int which) { + Symbol* method_handle_signature_ref_at(int which) { int member = method_handle_index_at(which); return impl_signature_ref_at(member, true); } @@ -426,7 +496,7 @@ int member = method_handle_index_at(which); return impl_klass_ref_index_at(member, true); } - symbolOop method_type_signature_at(int which) { + Symbol* method_type_signature_at(int which) { int sym = method_type_index_at(which); return symbol_at(sym); } @@ -534,9 +604,9 @@ // Lookup for entries consisting of (klass_index, name_and_type index) klassOop klass_ref_at(int which, TRAPS); - symbolOop klass_ref_at_noresolve(int which); - symbolOop name_ref_at(int which) { return impl_name_ref_at(which, false); } - symbolOop signature_ref_at(int which) { return impl_signature_ref_at(which, false); } + Symbol* klass_ref_at_noresolve(int which); + Symbol* name_ref_at(int which) { return impl_name_ref_at(which, false); } + Symbol* signature_ref_at(int which) { return impl_signature_ref_at(which, false); } int klass_ref_index_at(int which) { return impl_klass_ref_index_at(which, false); } int name_and_type_ref_index_at(int which) { return impl_name_and_type_ref_index_at(which, false); } @@ -605,15 +675,15 @@ // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the // future by other Java code. These take constant pool indices rather than // constant pool cache indices as do the peer methods above. - symbolOop uncached_klass_ref_at_noresolve(int which); - symbolOop uncached_name_ref_at(int which) { return impl_name_ref_at(which, true); } - symbolOop uncached_signature_ref_at(int which) { return impl_signature_ref_at(which, true); } + Symbol* uncached_klass_ref_at_noresolve(int which); + Symbol* uncached_name_ref_at(int which) { return impl_name_ref_at(which, true); } + Symbol* uncached_signature_ref_at(int which) { return impl_signature_ref_at(which, true); } int uncached_klass_ref_index_at(int which) { return impl_klass_ref_index_at(which, true); } int uncached_name_and_type_ref_index_at(int which) { return impl_name_and_type_ref_index_at(which, true); } // Sharing int pre_resolve_shared_klasses(TRAPS); - void shared_symbols_iterate(OopClosure* closure0); + void shared_symbols_iterate(SymbolClosure* closure0); void shared_tags_iterate(OopClosure* closure0); void shared_strings_iterate(OopClosure* closure0); @@ -628,8 +698,8 @@ private: - symbolOop impl_name_ref_at(int which, bool uncached); - symbolOop impl_signature_ref_at(int which, bool uncached); + Symbol* impl_name_ref_at(int which, bool uncached); + Symbol* impl_signature_ref_at(int which, bool uncached); int impl_klass_ref_index_at(int which, bool uncached); int impl_name_and_type_ref_index_at(int which, bool uncached); @@ -672,6 +742,9 @@ int orig_length() const { return _orig_length; } void set_orig_length(int orig_length) { _orig_length = orig_length; } + // Decrease ref counts of symbols that are in the constant pool + // when the holder class is unloaded + void unreference_symbols(); // JVMTI accesss - GetConstantPool, RetransformClasses, ... friend class JvmtiConstantPoolReconstituter; @@ -694,7 +767,7 @@ private: unsigned int _hash; // 32-bit hash for item SymbolHashMapEntry* _next; // Next element in the linked list for this bucket - symbolOop _symbol; // 1-st part of the mapping: symbol => value + Symbol* _symbol; // 1-st part of the mapping: symbol => value u2 _value; // 2-nd part of the mapping: symbol => value public: @@ -704,13 +777,13 @@ SymbolHashMapEntry* next() const { return _next; } void set_next(SymbolHashMapEntry* next) { _next = next; } - symbolOop symbol() const { return _symbol; } - void set_symbol(symbolOop sym) { _symbol = sym; } + Symbol* symbol() const { return _symbol; } + void set_symbol(Symbol* sym) { _symbol = sym; } u2 value() const { return _value; } void set_value(u2 value) { _value = value; } - SymbolHashMapEntry(unsigned int hash, symbolOop symbol, u2 value) + SymbolHashMapEntry(unsigned int hash, Symbol* symbol, u2 value) : _hash(hash), _symbol(symbol), _value(value), _next(NULL) {} }; // End SymbolHashMapEntry class @@ -769,10 +842,10 @@ return _buckets[i].entry(); } - void add_entry(symbolOop sym, u2 value); - SymbolHashMapEntry* find_entry(symbolOop sym); + void add_entry(Symbol* sym, u2 value); + SymbolHashMapEntry* find_entry(Symbol* sym); - u2 symbol_to_value(symbolOop sym) { + u2 symbol_to_value(Symbol* sym) { SymbolHashMapEntry *entry = find_entry(sym); return (entry == NULL) ? 0 : entry->value(); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/generateOopMap.cpp --- a/src/share/vm/oops/generateOopMap.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/generateOopMap.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -26,7 +26,7 @@ #include "interpreter/bytecodeStream.hpp" #include "oops/generateOopMap.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/relocator.hpp" @@ -123,7 +123,7 @@ set(CellTypeState::value); } public: - ComputeCallStack(symbolOop signature) : SignatureIterator(signature) {}; + ComputeCallStack(Symbol* signature) : SignatureIterator(signature) {}; // Compute methods int compute_for_parameters(bool is_static, CellTypeState *effect) { @@ -177,7 +177,7 @@ set(CellTypeState::value); } public: - ComputeEntryStack(symbolOop signature) : SignatureIterator(signature) {}; + ComputeEntryStack(Symbol* signature) : SignatureIterator(signature) {}; // Compute methods int compute_for_parameters(bool is_static, CellTypeState *effect) { @@ -660,7 +660,7 @@ _monitor_top = 0; } -int GenerateOopMap::methodsig_to_effect(symbolOop signature, bool is_static, CellTypeState* effect) { +int GenerateOopMap::methodsig_to_effect(Symbol* signature, bool is_static, CellTypeState* effect) { ComputeEntryStack ces(signature); return ces.compute_for_parameters(is_static, effect); } @@ -1265,7 +1265,7 @@ constantPoolOop cp = method()->constants(); int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx); int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx); - symbolOop signature = cp->symbol_at(signatureIdx); + Symbol* signature = cp->symbol_at(signatureIdx); os->print("%s", signature->as_C_string()); } os->cr(); @@ -1297,7 +1297,7 @@ constantPoolOop cp = method()->constants(); int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx); int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx); - symbolOop signature = cp->symbol_at(signatureIdx); + Symbol* signature = cp->symbol_at(signatureIdx); os->print("%s", signature->as_C_string()); } os->cr(); @@ -1844,7 +1844,7 @@ // Make sure bt==T_OBJECT is the same as old code (is_pointer_entry). // Note that CONSTANT_MethodHandle entries are u2 index pairs, not pointer-entries, // and they are processed by _fast_aldc and the CP cache. - assert((ldc.has_cache_index() || cp->is_pointer_entry(ldc.pool_index())) + assert((ldc.has_cache_index() || cp->is_object_entry(ldc.pool_index())) ? (bt == T_OBJECT) : true, "expected object type"); ppush1(cts); } @@ -1884,7 +1884,7 @@ constantPoolOop cp = method()->constants(); int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx); int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx); - symbolOop signature = cp->symbol_at(signatureIdx); + Symbol* signature = cp->symbol_at(signatureIdx); // Parse signature (espcially simple for fields) assert(signature->utf8_length() > 0, "field signatures cannot have zero length"); @@ -1912,7 +1912,7 @@ void GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) { // Dig up signature for field in constant pool constantPoolOop cp = _method->constants(); - symbolOop signature = cp->signature_ref_at(idx); + Symbol* signature = cp->signature_ref_at(idx); // Parse method signature CellTypeState out[4]; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/generateOopMap.hpp --- a/src/share/vm/oops/generateOopMap.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/generateOopMap.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -323,7 +323,7 @@ // Cell type methods void init_state(); void make_context_uninitialized (); - int methodsig_to_effect (symbolOop signature, bool isStatic, CellTypeState* effect); + int methodsig_to_effect (Symbol* signature, bool isStatic, CellTypeState* effect); bool merge_local_state_vectors (CellTypeState* cts, CellTypeState* bbts); bool merge_monitor_state_vectors(CellTypeState* cts, CellTypeState* bbts); void copy_state (CellTypeState *dst, CellTypeState *src); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -41,7 +41,7 @@ #include "oops/methodOop.hpp" #include "oops/objArrayKlassKlass.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" #include "runtime/fieldDescriptor.hpp" @@ -96,7 +96,7 @@ { \ char* data = NULL; \ int len = 0; \ - symbolOop name = (clss)->name(); \ + Symbol* name = (clss)->name(); \ if (name != NULL) { \ data = (char*)name->bytes(); \ len = name->utf8_length(); \ @@ -109,7 +109,7 @@ { \ char* data = NULL; \ int len = 0; \ - symbolOop name = (clss)->name(); \ + Symbol* name = (clss)->name(); \ if (name != NULL) { \ data = (char*)name->bytes(); \ len = name->utf8_length(); \ @@ -266,7 +266,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_IncompatibleClassChangeError(), + vmSymbols::java_lang_IncompatibleClassChangeError(), "class %s has interface %s as super class", this_oop->external_name(), super->external_name() @@ -500,8 +500,8 @@ THROW_OOP(e()); } else { JavaCallArguments args(e); - THROW_ARG(vmSymbolHandles::java_lang_ExceptionInInitializerError(), - vmSymbolHandles::throwable_void_signature(), + THROW_ARG(vmSymbols::java_lang_ExceptionInInitializerError(), + vmSymbols::throwable_void_signature(), &args); } } @@ -770,13 +770,13 @@ } -bool instanceKlass::find_local_field(symbolOop name, symbolOop sig, fieldDescriptor* fd) const { +bool instanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { const int n = fields()->length(); for (int i = 0; i < n; i += next_offset ) { int name_index = fields()->ushort_at(i + name_index_offset); int sig_index = fields()->ushort_at(i + signature_index_offset); - symbolOop f_name = constants()->symbol_at(name_index); - symbolOop f_sig = constants()->symbol_at(sig_index); + Symbol* f_name = constants()->symbol_at(name_index); + Symbol* f_sig = constants()->symbol_at(sig_index); if (f_name == name && f_sig == sig) { fd->initialize(as_klassOop(), i); return true; @@ -786,21 +786,23 @@ } -void instanceKlass::field_names_and_sigs_iterate(OopClosure* closure) { +void instanceKlass::shared_symbols_iterate(SymbolClosure* closure) { + Klass::shared_symbols_iterate(closure); + closure->do_symbol(&_generic_signature); + closure->do_symbol(&_source_file_name); + closure->do_symbol(&_source_debug_extension); + const int n = fields()->length(); for (int i = 0; i < n; i += next_offset ) { int name_index = fields()->ushort_at(i + name_index_offset); - symbolOop name = constants()->symbol_at(name_index); - closure->do_oop((oop*)&name); - + closure->do_symbol(constants()->symbol_at_addr(name_index)); int sig_index = fields()->ushort_at(i + signature_index_offset); - symbolOop sig = constants()->symbol_at(sig_index); - closure->do_oop((oop*)&sig); + closure->do_symbol(constants()->symbol_at_addr(sig_index)); } } -klassOop instanceKlass::find_interface_field(symbolOop name, symbolOop sig, fieldDescriptor* fd) const { +klassOop instanceKlass::find_interface_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { const int n = local_interfaces()->length(); for (int i = 0; i < n; i++) { klassOop intf1 = klassOop(local_interfaces()->obj_at(i)); @@ -819,7 +821,7 @@ } -klassOop instanceKlass::find_field(symbolOop name, symbolOop sig, fieldDescriptor* fd) const { +klassOop instanceKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { // search order according to newest JVM spec (5.4.3.2, p.167). // 1) search for field in current klass if (find_local_field(name, sig, fd)) { @@ -838,7 +840,7 @@ } -klassOop instanceKlass::find_field(symbolOop name, symbolOop sig, bool is_static, fieldDescriptor* fd) const { +klassOop instanceKlass::find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const { // search order according to newest JVM spec (5.4.3.2, p.167). // 1) search for field in current klass if (find_local_field(name, sig, fd)) { @@ -965,7 +967,7 @@ } #ifdef ASSERT -static int linear_search(objArrayOop methods, symbolOop name, symbolOop signature) { +static int linear_search(objArrayOop methods, Symbol* name, Symbol* signature) { int len = methods->length(); for (int index = 0; index < len; index++) { methodOop m = (methodOop)(methods->obj_at(index)); @@ -978,11 +980,11 @@ } #endif -methodOop instanceKlass::find_method(symbolOop name, symbolOop signature) const { +methodOop instanceKlass::find_method(Symbol* name, Symbol* signature) const { return instanceKlass::find_method(methods(), name, signature); } -methodOop instanceKlass::find_method(objArrayOop methods, symbolOop name, symbolOop signature) { +methodOop instanceKlass::find_method(objArrayOop methods, Symbol* name, Symbol* signature) { int len = methods->length(); // methods are sorted, so do binary search int l = 0; @@ -1030,7 +1032,7 @@ return NULL; } -methodOop instanceKlass::uncached_lookup_method(symbolOop name, symbolOop signature) const { +methodOop instanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { klassOop klass = as_klassOop(); while (klass != NULL) { methodOop method = instanceKlass::cast(klass)->find_method(name, signature); @@ -1041,8 +1043,8 @@ } // lookup a method in all the interfaces that this class implements -methodOop instanceKlass::lookup_method_in_all_interfaces(symbolOop name, - symbolOop signature) const { +methodOop instanceKlass::lookup_method_in_all_interfaces(Symbol* name, + Symbol* signature) const { objArrayOop all_ifs = instanceKlass::cast(as_klassOop())->transitive_interfaces(); int num_ifs = all_ifs->length(); instanceKlass *ik = NULL; @@ -1990,6 +1992,26 @@ _cached_class_file_bytes = NULL; _cached_class_file_len = 0; } + + // Decrement symbol reference counts associated with the unloaded class. + if (_name != NULL) _name->decrement_refcount(); + // unreference array name derived from this class name (arrays of an unloaded + // class can't be referenced anymore). + if (_array_name != NULL) _array_name->decrement_refcount(); + if (_source_file_name != NULL) _source_file_name->decrement_refcount(); + if (_source_debug_extension != NULL) _source_debug_extension->decrement_refcount(); + // walk constant pool and decrement symbol reference counts + _constants->unreference_symbols(); +} + +void instanceKlass::set_source_file_name(Symbol* n) { + _source_file_name = n; + if (_source_file_name != NULL) _source_file_name->increment_refcount(); +} + +void instanceKlass::set_source_debug_extension(Symbol* n) { + _source_debug_extension = n; + if (_source_debug_extension != NULL) _source_debug_extension->increment_refcount(); } const char* instanceKlass::signature_name() const { @@ -2011,7 +2033,7 @@ bool instanceKlass::is_same_class_package(klassOop class2) { klassOop class1 = as_klassOop(); oop classloader1 = instanceKlass::cast(class1)->class_loader(); - symbolOop classname1 = Klass::cast(class1)->name(); + Symbol* classname1 = Klass::cast(class1)->name(); if (Klass::cast(class2)->oop_is_objArray()) { class2 = objArrayKlass::cast(class2)->bottom_klass(); @@ -2023,16 +2045,16 @@ assert(Klass::cast(class2)->oop_is_typeArray(), "should be type array"); classloader2 = NULL; } - symbolOop classname2 = Klass::cast(class2)->name(); + Symbol* classname2 = Klass::cast(class2)->name(); return instanceKlass::is_same_class_package(classloader1, classname1, classloader2, classname2); } -bool instanceKlass::is_same_class_package(oop classloader2, symbolOop classname2) { +bool instanceKlass::is_same_class_package(oop classloader2, Symbol* classname2) { klassOop class1 = as_klassOop(); oop classloader1 = instanceKlass::cast(class1)->class_loader(); - symbolOop classname1 = Klass::cast(class1)->name(); + Symbol* classname1 = Klass::cast(class1)->name(); return instanceKlass::is_same_class_package(classloader1, classname1, classloader2, classname2); @@ -2040,8 +2062,8 @@ // return true if two classes are in the same package, classloader // and classname information is enough to determine a class's package -bool instanceKlass::is_same_class_package(oop class_loader1, symbolOop class_name1, - oop class_loader2, symbolOop class_name2) { +bool instanceKlass::is_same_class_package(oop class_loader1, Symbol* class_name1, + oop class_loader2, Symbol* class_name2) { if (class_loader1 != class_loader2) { return false; } else if (class_name1 == class_name2) { @@ -2049,14 +2071,14 @@ } else { ResourceMark rm; - // The symbolOop's are in UTF8 encoding. Since we only need to check explicitly + // The Symbol*'s are in UTF8 encoding. Since we only need to check explicitly // for ASCII characters ('/', 'L', '['), we can keep them in UTF8 encoding. // Otherwise, we just compare jbyte values between the strings. - jbyte *name1 = class_name1->base(); - jbyte *name2 = class_name2->base(); - - jbyte *last_slash1 = UTF8::strrchr(name1, class_name1->utf8_length(), '/'); - jbyte *last_slash2 = UTF8::strrchr(name2, class_name2->utf8_length(), '/'); + const jbyte *name1 = class_name1->base(); + const jbyte *name2 = class_name2->base(); + + const jbyte *last_slash1 = UTF8::strrchr(name1, class_name1->utf8_length(), '/'); + const jbyte *last_slash2 = UTF8::strrchr(name2, class_name2->utf8_length(), '/'); if ((last_slash1 == NULL) || (last_slash2 == NULL)) { // One of the two doesn't have a package. Only return true @@ -2097,7 +2119,7 @@ // Assumes name-signature match // "this" is instanceKlass of super_method which must exist // note that the instanceKlass of the method in the targetclassname has not always been created yet -bool instanceKlass::is_override(methodHandle super_method, Handle targetclassloader, symbolHandle targetclassname, TRAPS) { +bool instanceKlass::is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS) { // Private methods can not be overridden if (super_method->is_private()) { return false; @@ -2109,12 +2131,12 @@ } // Package-private methods are not inherited outside of package assert(super_method->is_package_private(), "must be package private"); - return(is_same_class_package(targetclassloader(), targetclassname())); + return(is_same_class_package(targetclassloader(), targetclassname)); } /* defined for now in jvm.cpp, for historical reasons *-- klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle self, - symbolOop& simple_name_result, TRAPS) { + Symbol*& simple_name_result, TRAPS) { ... } */ @@ -2185,7 +2207,7 @@ // only look at classes that are already loaded // since we are looking for the flags for our self. - symbolOop inner_name = ik->constants()->klass_name_at(ioff); + Symbol* inner_name = ik->constants()->klass_name_at(ioff); if ((ik->name() == inner_name)) { // This is really a member class. access = inner_class_list_h->ushort_at(i + instanceKlass::inner_class_access_flags_offset); @@ -2224,7 +2246,7 @@ // If the interface isn't implemented by the receiver class, // the VM should throw IncompatibleClassChangeError. if (cnt >= nof_interfaces) { - THROW_OOP_0(vmSymbols::java_lang_IncompatibleClassChangeError()); + THROW_0(vmSymbols::java_lang_IncompatibleClassChangeError()); } klassOop ik = ioe->interface_klass(); @@ -2234,7 +2256,7 @@ itableMethodEntry* ime = ioe->first_method_entry(as_klassOop()); methodOop m = ime[index].method(); if (m == NULL) { - THROW_OOP_0(vmSymbols::java_lang_AbstractMethodError()); + THROW_0(vmSymbols::java_lang_AbstractMethodError()); } return m; } @@ -2721,8 +2743,8 @@ if (!emcp_methods->at(i)) { // only obsolete methods are interesting methodOop old_method = (methodOop) old_methods->obj_at(i); - symbolOop m_name = old_method->name(); - symbolOop m_signature = old_method->signature(); + Symbol* m_name = old_method->name(); + Symbol* m_signature = old_method->signature(); // skip the last entry since we just added it for (int j = _previous_versions->length() - 2; j >= 0; j--) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/instanceKlass.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -189,16 +189,10 @@ klassOop _host_klass; // Class signers. objArrayOop _signers; - // Name of source file containing this klass, NULL if not specified. - symbolOop _source_file_name; - // the source debug extension for this klass, NULL if not specified. - symbolOop _source_debug_extension; // inner_classes attribute. typeArrayOop _inner_classes; // Implementors of this interface (not valid if it overflows) klassOop _implementors[implementors_limit]; - // Generic signature, or null if none. - symbolOop _generic_signature; // invokedynamic bootstrap method (a java.dyn.MethodHandle) oop _bootstrap_method; // Annotations for this class, or null if none. @@ -222,6 +216,16 @@ // End of the oop block. // + // Name of source file containing this klass, NULL if not specified. + Symbol* _source_file_name; + // the source debug extension for this klass, NULL if not specified. + Symbol* _source_debug_extension; + // Generic signature, or null if none. + Symbol* _generic_signature; + // Array name derived from this class which needs unreferencing + // if this class is unloaded. + Symbol* _array_name; + // Number of heapOopSize words used by non-static fields in this klass // (including inherited fields but after header_size()). int _nonstatic_field_size; @@ -343,12 +347,12 @@ }; // method override check - bool is_override(methodHandle super_method, Handle targetclassloader, symbolHandle targetclassname, TRAPS); + bool is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS); // package bool is_same_class_package(klassOop class2); - bool is_same_class_package(oop classloader2, symbolOop classname2); - static bool is_same_class_package(oop class_loader1, symbolOop class_name1, oop class_loader2, symbolOop class_name2); + bool is_same_class_package(oop classloader2, Symbol* classname2); + static bool is_same_class_package(oop class_loader1, Symbol* class_name1, oop class_loader2, Symbol* class_name2); // find an enclosing class (defined where original code was, in jvm.cpp!) klassOop compute_enclosing_class(bool* inner_is_member, TRAPS) { @@ -402,13 +406,13 @@ void set_reference_type(ReferenceType t) { _reference_type = t; } // find local field, returns true if found - bool find_local_field(symbolOop name, symbolOop sig, fieldDescriptor* fd) const; + bool find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; // find field in direct superinterfaces, returns the interface in which the field is defined - klassOop find_interface_field(symbolOop name, symbolOop sig, fieldDescriptor* fd) const; + klassOop find_interface_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined - klassOop find_field(symbolOop name, symbolOop sig, fieldDescriptor* fd) const; + klassOop find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; // find instance or static fields according to JVM spec 5.4.3.2, returns the klass in which the field is defined - klassOop find_field(symbolOop name, symbolOop sig, bool is_static, fieldDescriptor* fd) const; + klassOop find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const; // find a non-static or static field given its offset within the class. bool contains_field_offset(int offset) { @@ -419,15 +423,15 @@ bool find_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const; // find a local method (returns NULL if not found) - methodOop find_method(symbolOop name, symbolOop signature) const; - static methodOop find_method(objArrayOop methods, symbolOop name, symbolOop signature); + methodOop find_method(Symbol* name, Symbol* signature) const; + static methodOop find_method(objArrayOop methods, Symbol* name, Symbol* signature); // lookup operation (returns NULL if not found) - methodOop uncached_lookup_method(symbolOop name, symbolOop signature) const; + methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const; // lookup a method in all the interfaces that this class implements // (returns NULL if not found) - methodOop lookup_method_in_all_interfaces(symbolOop name, symbolOop signature) const; + methodOop lookup_method_in_all_interfaces(Symbol* name, Symbol* signature) const; // constant pool constantPoolOop constants() const { return _constants; } @@ -451,8 +455,8 @@ void set_signers(objArrayOop s) { oop_store((oop*) &_signers, oop(s)); } // source file name - symbolOop source_file_name() const { return _source_file_name; } - void set_source_file_name(symbolOop n) { oop_store_without_check((oop*) &_source_file_name, (oop) n); } + Symbol* source_file_name() const { return _source_file_name; } + void set_source_file_name(Symbol* n); // minor and major version numbers of class file u2 minor_version() const { return _minor_version; } @@ -461,8 +465,12 @@ void set_major_version(u2 major_version) { _major_version = major_version; } // source debug extension - symbolOop source_debug_extension() const { return _source_debug_extension; } - void set_source_debug_extension(symbolOop n){ oop_store_without_check((oop*) &_source_debug_extension, (oop) n); } + Symbol* source_debug_extension() const { return _source_debug_extension; } + void set_source_debug_extension(Symbol* n); + + // symbol unloading support (refcount already added) + Symbol* array_name() { return _array_name; } + void set_array_name(Symbol* name) { assert(_array_name == NULL, "name already created"); _array_name = name; } // nonstatic oop-map blocks static int nonstatic_oop_map_size(unsigned int oop_map_count) { @@ -511,8 +519,9 @@ void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; } // generics support - symbolOop generic_signature() const { return _generic_signature; } - void set_generic_signature(symbolOop sig) { oop_store_without_check((oop*)&_generic_signature, (oop)sig); } + Symbol* generic_signature() const { return _generic_signature; } + void set_generic_signature(Symbol* sig) { _generic_signature = sig; } + u2 enclosing_method_class_index() const { return _enclosing_method_class_index; } u2 enclosing_method_method_index() const { return _enclosing_method_method_index; } void set_enclosing_method_indices(u2 class_index, @@ -807,11 +816,8 @@ oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;} oop* adr_host_klass() const { return (oop*)&this->_host_klass;} oop* adr_signers() const { return (oop*)&this->_signers;} - oop* adr_source_file_name() const { return (oop*)&this->_source_file_name;} - oop* adr_source_debug_extension() const { return (oop*)&this->_source_debug_extension;} oop* adr_inner_classes() const { return (oop*)&this->_inner_classes;} oop* adr_implementors() const { return (oop*)&this->_implementors[0];} - oop* adr_generic_signature() const { return (oop*)&this->_generic_signature;} oop* adr_bootstrap_method() const { return (oop*)&this->_bootstrap_method;} oop* adr_methods_jmethod_ids() const { return (oop*)&this->_methods_jmethod_ids;} oop* adr_methods_cached_itable_indices() const { return (oop*)&this->_methods_cached_itable_indices;} @@ -843,7 +849,7 @@ public: // sharing support virtual void remove_unshareable_info(); - void field_names_and_sigs_iterate(OopClosure* closure); + virtual void shared_symbols_iterate(SymbolClosure* closure); // jvm support jint compute_modifier_flags(TRAPS) const; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/instanceKlassKlass.cpp --- a/src/share/vm/oops/instanceKlassKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/instanceKlassKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -37,7 +37,7 @@ #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "oops/typeArrayOop.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/fieldDescriptor.hpp" @@ -101,13 +101,10 @@ MarkSweep::mark_and_push(ik->adr_fields()); MarkSweep::mark_and_push(ik->adr_constants()); MarkSweep::mark_and_push(ik->adr_class_loader()); - MarkSweep::mark_and_push(ik->adr_source_file_name()); - MarkSweep::mark_and_push(ik->adr_source_debug_extension()); MarkSweep::mark_and_push(ik->adr_inner_classes()); MarkSweep::mark_and_push(ik->adr_protection_domain()); MarkSweep::mark_and_push(ik->adr_host_klass()); MarkSweep::mark_and_push(ik->adr_signers()); - MarkSweep::mark_and_push(ik->adr_generic_signature()); MarkSweep::mark_and_push(ik->adr_bootstrap_method()); MarkSweep::mark_and_push(ik->adr_class_annotations()); MarkSweep::mark_and_push(ik->adr_fields_annotations()); @@ -142,13 +139,10 @@ PSParallelCompact::mark_and_push(cm, ik->adr_fields()); PSParallelCompact::mark_and_push(cm, ik->adr_constants()); PSParallelCompact::mark_and_push(cm, ik->adr_class_loader()); - PSParallelCompact::mark_and_push(cm, ik->adr_source_file_name()); - PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension()); PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes()); PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain()); PSParallelCompact::mark_and_push(cm, ik->adr_host_klass()); PSParallelCompact::mark_and_push(cm, ik->adr_signers()); - PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature()); PSParallelCompact::mark_and_push(cm, ik->adr_bootstrap_method()); PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations()); PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations()); @@ -189,13 +183,10 @@ blk->do_oop(ik->adr_protection_domain()); blk->do_oop(ik->adr_host_klass()); blk->do_oop(ik->adr_signers()); - blk->do_oop(ik->adr_source_file_name()); - blk->do_oop(ik->adr_source_debug_extension()); blk->do_oop(ik->adr_inner_classes()); for (int i = 0; i < instanceKlass::implementors_limit; i++) { blk->do_oop(&ik->adr_implementors()[i]); } - blk->do_oop(ik->adr_generic_signature()); blk->do_oop(ik->adr_bootstrap_method()); blk->do_oop(ik->adr_class_annotations()); blk->do_oop(ik->adr_fields_annotations()); @@ -245,18 +236,12 @@ if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_signers(); if (mr.contains(adr)) blk->do_oop(adr); - adr = ik->adr_source_file_name(); - if (mr.contains(adr)) blk->do_oop(adr); - adr = ik->adr_source_debug_extension(); - if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_inner_classes(); if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_implementors(); for (int i = 0; i < instanceKlass::implementors_limit; i++) { if (mr.contains(&adr[i])) blk->do_oop(&adr[i]); } - adr = ik->adr_generic_signature(); - if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_bootstrap_method(); if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_class_annotations(); @@ -296,13 +281,10 @@ MarkSweep::adjust_pointer(ik->adr_protection_domain()); MarkSweep::adjust_pointer(ik->adr_host_klass()); MarkSweep::adjust_pointer(ik->adr_signers()); - MarkSweep::adjust_pointer(ik->adr_source_file_name()); - MarkSweep::adjust_pointer(ik->adr_source_debug_extension()); MarkSweep::adjust_pointer(ik->adr_inner_classes()); for (int i = 0; i < instanceKlass::implementors_limit; i++) { MarkSweep::adjust_pointer(&ik->adr_implementors()[i]); } - MarkSweep::adjust_pointer(ik->adr_generic_signature()); MarkSweep::adjust_pointer(ik->adr_bootstrap_method()); MarkSweep::adjust_pointer(ik->adr_class_annotations()); MarkSweep::adjust_pointer(ik->adr_fields_annotations()); @@ -452,6 +434,8 @@ ik->set_signers(NULL); ik->set_source_file_name(NULL); ik->set_source_debug_extension(NULL); + ik->set_source_debug_extension(NULL); + ik->set_array_name(NULL); ik->set_inner_classes(NULL); ik->set_static_oop_field_size(0); ik->set_nonstatic_field_size(0); @@ -667,7 +651,7 @@ #endif // Verify that klass is present in SystemDictionary if (ik->is_loaded() && !ik->is_anonymous()) { - symbolHandle h_name (thread, ik->name()); + Symbol* h_name = ik->name(); Handle h_loader (thread, ik->class_loader()); Handle h_obj(thread, obj); SystemDictionary::verify_obj_klass_present(h_obj, h_name, h_loader); @@ -793,14 +777,6 @@ guarantee(ik->constants()->is_constantPool(), "should be constant pool"); guarantee(ik->inner_classes()->is_perm(), "should be in permspace"); guarantee(ik->inner_classes()->is_typeArray(), "should be type array"); - if (ik->source_file_name() != NULL) { - guarantee(ik->source_file_name()->is_perm(), "should be in permspace"); - guarantee(ik->source_file_name()->is_symbol(), "should be symbol"); - } - if (ik->source_debug_extension() != NULL) { - guarantee(ik->source_debug_extension()->is_perm(), "should be in permspace"); - guarantee(ik->source_debug_extension()->is_symbol(), "should be symbol"); - } if (ik->protection_domain() != NULL) { guarantee(ik->protection_domain()->is_oop(), "should be oop"); } @@ -810,10 +786,6 @@ if (ik->signers() != NULL) { guarantee(ik->signers()->is_objArray(), "should be obj array"); } - if (ik->generic_signature() != NULL) { - guarantee(ik->generic_signature()->is_perm(), "should be in permspace"); - guarantee(ik->generic_signature()->is_symbol(), "should be symbol"); - } if (ik->class_annotations() != NULL) { guarantee(ik->class_annotations()->is_typeArray(), "should be type array"); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/klass.cpp --- a/src/share/vm/oops/klass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/klass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -35,6 +35,10 @@ #include "oops/oop.inline2.hpp" #include "runtime/atomic.hpp" +void Klass::set_name(Symbol* n) { + _name = n; + if (_name != NULL) _name->increment_refcount(); +} bool Klass::is_subclass_of(klassOop k) const { // Run up the super chain and check @@ -115,7 +119,7 @@ } -methodOop Klass::uncached_lookup_method(symbolOop name, symbolOop signature) const { +methodOop Klass::uncached_lookup_method(Symbol* name, Symbol* signature) const { #ifdef ASSERT tty->print_cr("Error: uncached_lookup_method called on a klass oop." " Likely error: reflection method does not correctly" @@ -454,6 +458,11 @@ } +void Klass::shared_symbols_iterate(SymbolClosure* closure) { + closure->do_symbol(&_name); +} + + klassOop Klass::array_klass_or_null(int rank) { EXCEPTION_MARK; // No exception can be thrown by array_klass_impl when called with or_null == true. diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/klass.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -212,6 +212,10 @@ // secondary supers, else is &_primary_supers[depth()]. juint _super_check_offset; + // Class name. Instance classes: java/lang/String, etc. Array classes: [I, + // [Ljava/lang/String;, etc. Set to zero for all other kinds of classes. + Symbol* _name; + public: oop* oop_block_beg() const { return adr_secondary_super_cache(); } oop* oop_block_end() const { return adr_next_sibling() + 1; } @@ -235,9 +239,6 @@ oop _java_mirror; // Superclass klassOop _super; - // Class name. Instance classes: java/lang/String, etc. Array classes: [I, - // [Ljava/lang/String;, etc. Set to zero for all other kinds of classes. - symbolOop _name; // First subclass (NULL if none); _subklass->next_sibling() is next one klassOop _subklass; // Sibling link (or NULL); links all subklasses of a klass @@ -361,7 +362,6 @@ oop* adr_secondary_super_cache() const { return (oop*)&_secondary_super_cache; } oop* adr_secondary_supers()const { return (oop*)&_secondary_supers; } oop* adr_java_mirror() const { return (oop*)&_java_mirror; } - oop* adr_name() const { return (oop*)&_name; } oop* adr_subklass() const { return (oop*)&_subklass; } oop* adr_next_sibling() const { return (oop*)&_next_sibling; } @@ -511,9 +511,9 @@ virtual void initialize(TRAPS); // lookup operation for MethodLookupCache friend class MethodLookupCache; - virtual methodOop uncached_lookup_method(symbolOop name, symbolOop signature) const; + virtual methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const; public: - methodOop lookup_method(symbolOop name, symbolOop signature) const { + methodOop lookup_method(Symbol* name, Symbol* signature) const { return uncached_lookup_method(name, signature); } @@ -537,6 +537,7 @@ public: virtual void remove_unshareable_info(); + virtual void shared_symbols_iterate(SymbolClosure* closure); protected: // computes the subtype relationship @@ -579,7 +580,6 @@ virtual bool oop_is_instanceRef() const { return false; } virtual bool oop_is_array() const { return false; } virtual bool oop_is_objArray_slow() const { return false; } - virtual bool oop_is_symbol() const { return false; } virtual bool oop_is_klass() const { return false; } virtual bool oop_is_thread() const { return false; } virtual bool oop_is_method() const { return false; } @@ -781,8 +781,8 @@ Klass *up_cast_abstract(); // klass name - symbolOop name() const { return _name; } - void set_name(symbolOop n) { oop_store_without_check((oop*) &_name, (oop) n); } + Symbol* name() const { return _name; } + void set_name(Symbol* n); friend class klassKlass; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/klassKlass.cpp --- a/src/share/vm/oops/klassKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/klassKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -37,8 +37,7 @@ #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" -#include "oops/symbolKlass.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" #include "runtime/handles.inline.hpp" #ifndef SERIALGC @@ -70,7 +69,6 @@ MarkSweep::mark_and_push(k->adr_secondary_super_cache()); MarkSweep::mark_and_push(k->adr_secondary_supers()); MarkSweep::mark_and_push(k->adr_java_mirror()); - MarkSweep::mark_and_push(k->adr_name()); // We follow the subklass and sibling links at the end of the // marking phase, since otherwise following them will prevent // class unloading (all classes are transitively linked from @@ -90,7 +88,6 @@ PSParallelCompact::mark_and_push(cm, k->adr_secondary_super_cache()); PSParallelCompact::mark_and_push(cm, k->adr_secondary_supers()); PSParallelCompact::mark_and_push(cm, k->adr_java_mirror()); - PSParallelCompact::mark_and_push(cm, k->adr_name()); // We follow the subklass and sibling links at the end of the // marking phase, since otherwise following them will prevent // class unloading (all classes are transitively linked from @@ -110,7 +107,6 @@ blk->do_oop(k->adr_secondary_super_cache()); blk->do_oop(k->adr_secondary_supers()); blk->do_oop(k->adr_java_mirror()); - blk->do_oop(k->adr_name()); // The following are in the perm gen and are treated // specially in a later phase of a perm gen collection; ... assert(oop(k)->is_perm(), "should be in perm"); @@ -144,8 +140,6 @@ if (mr.contains(adr)) blk->do_oop(adr); adr = k->adr_java_mirror(); if (mr.contains(adr)) blk->do_oop(adr); - adr = k->adr_name(); - if (mr.contains(adr)) blk->do_oop(adr); // The following are "weak links" in the perm gen and are // treated specially in a later phase of a perm gen collection. assert(oop(k)->is_perm(), "should be in perm"); @@ -174,7 +168,6 @@ MarkSweep::adjust_pointer(k->adr_secondary_super_cache()); MarkSweep::adjust_pointer(k->adr_secondary_supers()); MarkSweep::adjust_pointer(k->adr_java_mirror()); - MarkSweep::adjust_pointer(k->adr_name()); MarkSweep::adjust_pointer(k->adr_subklass()); MarkSweep::adjust_pointer(k->adr_next_sibling()); return size; @@ -256,9 +249,4 @@ guarantee(k->java_mirror()->is_perm(), "should be in permspace"); guarantee(k->java_mirror()->is_instance(), "should be instance"); } - if (k->name() != NULL) { - guarantee(Universe::heap()->is_in_permanent(k->name()), - "should be in permspace"); - guarantee(k->name()->is_symbol(), "should be symbol"); - } } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/klassVtable.cpp --- a/src/share/vm/oops/klassVtable.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/klassVtable.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -61,7 +61,7 @@ objArrayOop methods, AccessFlags class_flags, Handle classloader, - symbolHandle classname, + Symbol* classname, objArrayOop local_interfaces, TRAPS ) { @@ -210,7 +210,7 @@ // the superclass's method, but might indirectly override a super-super class's vtable entry // If none found, return a null superk, else return the superk of the method this does override instanceKlass* klassVtable::find_transitive_override(instanceKlass* initialsuper, methodHandle target_method, - int vtable_index, Handle target_loader, symbolHandle target_classname, Thread * THREAD) { + int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { instanceKlass* superk = initialsuper; while (superk != NULL && superk->super() != NULL) { instanceKlass* supersuperklass = instanceKlass::cast(superk->super()); @@ -218,9 +218,9 @@ if (vtable_index < ssVtable->length()) { methodOop super_method = ssVtable->method_at(vtable_index); #ifndef PRODUCT - symbolHandle name(THREAD,target_method()->name()); - symbolHandle signature(THREAD,target_method()->signature()); - assert(super_method->name() == name() && super_method->signature() == signature(), "vtable entry name/sig mismatch"); + Symbol* name= target_method()->name(); + Symbol* signature = target_method()->signature(); + assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); #endif if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { #ifndef PRODUCT @@ -294,14 +294,14 @@ // which can block for gc, once we are in this loop, use handles // For classfiles built with >= jdk7, we now look for transitive overrides - symbolHandle name(THREAD,target_method()->name()); - symbolHandle signature(THREAD,target_method()->signature()); + Symbol* name = target_method()->name(); + Symbol* signature = target_method()->signature(); Handle target_loader(THREAD, _klass->class_loader()); - symbolHandle target_classname(THREAD, _klass->name()); + Symbol* target_classname = _klass->name(); for(int i = 0; i < super_vtable_len; i++) { methodOop super_method = method_at(i); // Check if method name matches - if (super_method->name() == name() && super_method->signature() == signature()) { + if (super_method->name() == name && super_method->signature() == signature) { // get super_klass for method_holder for the found method instanceKlass* super_klass = instanceKlass::cast(super_method->method_holder()); @@ -406,7 +406,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, klassOop super, Handle classloader, - symbolHandle classname, + Symbol* classname, AccessFlags class_flags, TRAPS) { if ((class_flags.is_final() || target_method()->is_final()) || @@ -436,8 +436,8 @@ // search through the super class hierarchy to see if we need // a new entry ResourceMark rm; - symbolOop name = target_method()->name(); - symbolOop signature = target_method()->signature(); + Symbol* name = target_method()->name(); + Symbol* signature = target_method()->signature(); klassOop k = super; methodOop super_method = NULL; instanceKlass *holder = NULL; @@ -485,7 +485,7 @@ // Support for miranda methods // get the vtable index of a miranda method with matching "name" and "signature" -int klassVtable::index_of_miranda(symbolOop name, symbolOop signature) { +int klassVtable::index_of_miranda(Symbol* name, Symbol* signature) { // search from the bottom, might be faster for (int i = (length() - 1); i >= 0; i--) { methodOop m = table()[i].method(); @@ -516,9 +516,8 @@ // check if a method is a miranda method, given a class's methods table and it's super // the caller must make sure that the method belongs to an interface implemented by the class bool klassVtable::is_miranda(methodOop m, objArrayOop class_methods, klassOop super) { - symbolOop name = m->name(); - symbolOop signature = m->signature(); - + Symbol* name = m->name(); + Symbol* signature = m->signature(); if (instanceKlass::find_method(class_methods, name, signature) == NULL) { // did not find it in the method table of the current class if (super == NULL) { @@ -929,8 +928,8 @@ // methods needs a handle in case of gc from check_signature_loaders for(; i < nof_methods; i++) { methodOop m = (methodOop)methods()->obj_at(i); - symbolOop method_name = m->name(); - symbolOop method_signature = m->signature(); + Symbol* method_name = m->name(); + Symbol* method_signature = m->signature(); // This is same code as in Linkresolver::lookup_instance_method_in_klasses methodOop target = klass->uncached_lookup_method(method_name, method_signature); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/klassVtable.hpp --- a/src/share/vm/oops/klassVtable.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/klassVtable.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -71,7 +71,7 @@ // searching; all methods return -1 if not found int index_of(methodOop m) const { return index_of(m, _length); } - int index_of_miranda(symbolOop name, symbolOop signature); + int index_of_miranda(Symbol* name, Symbol* signature); void initialize_vtable(bool checkconstraints, TRAPS); // initialize vtable of a new klass @@ -79,7 +79,7 @@ static void compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods, klassOop super, objArrayOop methods, AccessFlags class_flags, Handle classloader, - symbolHandle classname, objArrayOop local_interfaces, + Symbol* classname, objArrayOop local_interfaces, TRAPS); // RedefineClasses() API support: @@ -125,11 +125,11 @@ int initialize_from_super(KlassHandle super); int index_of(methodOop m, int len) const; // same as index_of, but search only up to len void put_method_at(methodOop m, int index); - static bool needs_new_vtable_entry(methodHandle m, klassOop super, Handle classloader, symbolHandle classname, AccessFlags access_flags, TRAPS); + static bool needs_new_vtable_entry(methodHandle m, klassOop super, Handle classloader, Symbol* classname, AccessFlags access_flags, TRAPS); bool update_inherited_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len, bool checkconstraints, TRAPS); instanceKlass* find_transitive_override(instanceKlass* initialsuper, methodHandle target_method, int vtable_index, - Handle target_loader, symbolHandle target_classname, Thread* THREAD); + Handle target_loader, Symbol* target_classname, Thread* THREAD); // support for miranda methods bool is_miranda_entry_at(int i); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/markOop.hpp --- a/src/share/vm/oops/markOop.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/markOop.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -118,14 +118,7 @@ }; // The biased locking code currently requires that the age bits be - // contiguous to the lock bits. Class data sharing would prefer the - // hash bits to be lower down to provide more random hash codes for - // shared read-only symbolOop objects, because these objects' mark - // words are set to their own address with marked_value in the lock - // bit, and using lower bits would make their identity hash values - // more random. However, the performance decision was made in favor - // of the biased locking code. - + // contiguous to the lock bits. enum { lock_shift = 0, biased_lock_shift = lock_bits, age_shift = lock_bits + biased_lock_bits, diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/methodKlass.cpp --- a/src/share/vm/oops/methodKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/methodKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -36,7 +36,7 @@ #include "oops/methodKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" klassOop methodKlass::create_klass(TRAPS) { @@ -353,10 +353,6 @@ if (!obj->partially_loaded()) { methodOop m = methodOop(obj); guarantee(m->is_perm(), "should be in permspace"); - guarantee(m->name()->is_perm(), "should be in permspace"); - guarantee(m->name()->is_symbol(), "should be symbol"); - guarantee(m->signature()->is_perm(), "should be in permspace"); - guarantee(m->signature()->is_symbol(), "should be symbol"); guarantee(m->constants()->is_perm(), "should be in permspace"); guarantee(m->constants()->is_constantPool(), "should be constant pool"); guarantee(m->constMethod()->is_constMethod(), "should be constMethodOop"); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/methodOop.cpp --- a/src/share/vm/oops/methodOop.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/methodOop.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -38,7 +38,7 @@ #include "oops/methodDataOop.hpp" #include "oops/methodOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/methodHandleWalk.hpp" #include "prims/nativeLookup.hpp" @@ -77,7 +77,7 @@ return name_and_sig_as_C_string(Klass::cast(constants()->pool_holder()), name(), signature(), buf, size); } -char* methodOopDesc::name_and_sig_as_C_string(Klass* klass, symbolOop method_name, symbolOop signature) { +char* methodOopDesc::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature) { const char* klass_name = klass->external_name(); int klass_name_len = (int)strlen(klass_name); int method_name_len = method_name->utf8_length(); @@ -91,8 +91,8 @@ return dest; } -char* methodOopDesc::name_and_sig_as_C_string(Klass* klass, symbolOop method_name, symbolOop signature, char* buf, int size) { - symbolOop klass_name = klass->name(); +char* methodOopDesc::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size) { + Symbol* klass_name = klass->name(); klass_name->as_klass_external_name(buf, size); int len = (int)strlen(buf); @@ -221,7 +221,7 @@ } -symbolOop methodOopDesc::klass_name() const { +Symbol* methodOopDesc::klass_name() const { klassOop k = method_holder(); assert(k->is_klass(), "must be klass"); instanceKlass* ik = (instanceKlass*) k->klass_part(); @@ -333,8 +333,7 @@ void methodOopDesc::compute_size_of_parameters(Thread *thread) { - symbolHandle h_signature(thread, signature()); - ArgumentSizeComputer asc(h_signature); + ArgumentSizeComputer asc(signature()); set_size_of_parameters(asc.size() + (is_static() ? 0 : 1)); } @@ -520,7 +519,7 @@ bool methodOopDesc::is_klass_loaded_by_klass_index(int klass_index) const { if( _constants->tag_at(klass_index).is_unresolved_klass() ) { Thread *thread = Thread::current(); - symbolHandle klass_name(thread, _constants->klass_name_at(klass_index)); + Symbol* klass_name = _constants->klass_name_at(klass_index); Handle loader(thread, instanceKlass::cast(method_holder())->class_loader()); Handle prot (thread, Klass::cast(method_holder())->protection_domain()); return SystemDictionary::find(klass_name, loader, prot, thread) != NULL; @@ -852,7 +851,7 @@ // Constant pool structure for invoke methods: enum { _imcp_invoke_name = 1, // utf8: 'invokeExact' or 'invokeGeneric' - _imcp_invoke_signature, // utf8: (variable symbolOop) + _imcp_invoke_signature, // utf8: (variable Symbol*) _imcp_method_type_value, // string: (variable java/dyn/MethodType, sic) _imcp_limit }; @@ -895,8 +894,8 @@ } methodHandle methodOopDesc::make_invoke_method(KlassHandle holder, - symbolHandle name, - symbolHandle signature, + Symbol* name, + Symbol* signature, Handle method_type, TRAPS) { methodHandle empty; @@ -914,9 +913,9 @@ constantPoolOop cp_oop = oopFactory::new_constantPool(_imcp_limit, IsSafeConc, CHECK_(empty)); cp = constantPoolHandle(THREAD, cp_oop); } - cp->symbol_at_put(_imcp_invoke_name, name()); - cp->symbol_at_put(_imcp_invoke_signature, signature()); - cp->string_at_put(_imcp_method_type_value, vmSymbols::void_signature()); + cp->symbol_at_put(_imcp_invoke_name, name); + cp->symbol_at_put(_imcp_invoke_signature, signature); + cp->string_at_put(_imcp_method_type_value, Universe::the_null_string()); cp->set_pool_holder(holder()); // set up the fancy stuff: @@ -932,7 +931,7 @@ m->set_name_index(_imcp_invoke_name); m->set_signature_index(_imcp_invoke_signature); assert(is_method_handle_invoke_name(m->name()), ""); - assert(m->signature() == signature(), ""); + assert(m->signature() == signature, ""); assert(m->is_method_handle_invoke(), ""); #ifdef CC_INTERP ResultTypeFinder rtf(signature()); @@ -1047,7 +1046,7 @@ return vmSymbols::NO_SID; // regardless of name, no intrinsics here // see if the klass name is well-known: - symbolOop klass_name = instanceKlass::cast(holder)->name(); + Symbol* klass_name = instanceKlass::cast(holder)->name(); return vmSymbols::find_sid(klass_name); } @@ -1123,11 +1122,12 @@ bool sig_is_loaded = true; Handle class_loader(THREAD, instanceKlass::cast(m->method_holder())->class_loader()); Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain()); - symbolHandle signature(THREAD, m->signature()); + ResourceMark rm(THREAD); + Symbol* signature = m->signature(); for(SignatureStream ss(signature); !ss.is_done(); ss.next()) { if (ss.is_object()) { - symbolOop sym = ss.as_symbol(CHECK_(false)); - symbolHandle name (THREAD, sym); + Symbol* sym = ss.as_symbol(CHECK_(false)); + Symbol* name = sym; klassOop klass = SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); // We are loading classes eagerly. If a ClassNotFoundException or @@ -1149,11 +1149,12 @@ bool methodOopDesc::has_unloaded_classes_in_signature(methodHandle m, TRAPS) { Handle class_loader(THREAD, instanceKlass::cast(m->method_holder())->class_loader()); Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain()); - symbolHandle signature(THREAD, m->signature()); + ResourceMark rm(THREAD); + Symbol* signature = m->signature(); for(SignatureStream ss(signature); !ss.is_done(); ss.next()) { if (ss.type() == T_OBJECT) { - symbolHandle name(THREAD, ss.as_symbol_or_null()); - if (name() == NULL) return true; + Symbol* name = ss.as_symbol_or_null(); + if (name == NULL) return true; klassOop klass = SystemDictionary::find(name, class_loader, protection_domain, THREAD); if (klass == NULL) return true; } @@ -1317,7 +1318,7 @@ } public: - SignatureTypePrinter(symbolHandle signature, outputStream* st) : SignatureTypeNames(signature) { + SignatureTypePrinter(Symbol* signature, outputStream* st) : SignatureTypeNames(signature) { _st = st; _use_separator = false; } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/methodOop.hpp --- a/src/share/vm/oops/methodOop.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/methodOop.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -161,17 +161,17 @@ void set_access_flags(AccessFlags flags) { _access_flags = flags; } // name - symbolOop name() const { return _constants->symbol_at(name_index()); } + Symbol* name() const { return _constants->symbol_at(name_index()); } int name_index() const { return constMethod()->name_index(); } void set_name_index(int index) { constMethod()->set_name_index(index); } // signature - symbolOop signature() const { return _constants->symbol_at(signature_index()); } + Symbol* signature() const { return _constants->symbol_at(signature_index()); } int signature_index() const { return constMethod()->signature_index(); } void set_signature_index(int index) { constMethod()->set_signature_index(index); } // generics support - symbolOop generic_signature() const { int idx = generic_signature_index(); return ((idx != 0) ? _constants->symbol_at(idx) : (symbolOop)NULL); } + Symbol* generic_signature() const { int idx = generic_signature_index(); return ((idx != 0) ? _constants->symbol_at(idx) : (Symbol*)NULL); } int generic_signature_index() const { return constMethod()->generic_signature_index(); } void set_generic_signature_index(int index) { constMethod()->set_generic_signature_index(index); } @@ -193,8 +193,8 @@ char* name_and_sig_as_C_string(char* buf, int size); // Static routine in the situations we don't have a methodOop - static char* name_and_sig_as_C_string(Klass* klass, symbolOop method_name, symbolOop signature); - static char* name_and_sig_as_C_string(Klass* klass, symbolOop method_name, symbolOop signature, char* buf, int size); + static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature); + static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size); Bytecodes::Code java_code_at(int bci) const { return Bytecodes::java_code_at(this, bcp_from(bci)); @@ -433,7 +433,7 @@ klassOop method_holder() const { return _constants->pool_holder(); } void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments) - symbolOop klass_name() const; // returns the name of the method holder + Symbol* klass_name() const; // returns the name of the method holder BasicType result_type() const; // type of the method result int result_type_index() const; // type index of the method result bool is_returning_oop() const { BasicType r = result_type(); return (r == T_OBJECT || r == T_ARRAY); } @@ -564,15 +564,15 @@ // JSR 292 support bool is_method_handle_invoke() const { return access_flags().is_method_handle_invoke(); } static bool is_method_handle_invoke_name(vmSymbols::SID name_sid); - static bool is_method_handle_invoke_name(symbolOop name) { + static bool is_method_handle_invoke_name(Symbol* name) { return is_method_handle_invoke_name(vmSymbols::find_sid(name)); } // Tests if this method is an internal adapter frame from the // MethodHandleCompiler. bool is_method_handle_adapter() const; static methodHandle make_invoke_method(KlassHandle holder, - symbolHandle name, //invokeExact or invokeGeneric - symbolHandle signature, //anything at all + Symbol* name, //invokeExact or invokeGeneric + Symbol* signature, //anything at all Handle method_type, TRAPS); // these operate only on invoke methods: diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/objArrayKlass.cpp --- a/src/share/vm/oops/objArrayKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/objArrayKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -37,7 +37,7 @@ #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/copy.hpp" diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/objArrayKlassKlass.cpp --- a/src/share/vm/oops/objArrayKlassKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/objArrayKlassKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -110,14 +110,11 @@ } } - // Create type name for klass (except for symbol arrays, since symbolKlass - // does not have a name). This will potentially allocate an object, cause - // GC, and all other kinds of things. Hence, this must be done before we - // get a handle to the new objArrayKlass we want to construct. We cannot - // block while holding a handling to a partly initialized object. - symbolHandle name = symbolHandle(); + // Create type name for klass. + Symbol* name = NULL; + if (!element_klass->oop_is_instance() || + (name = instanceKlass::cast(element_klass())->array_name()) == NULL) { - if (!element_klass->oop_is_symbol()) { ResourceMark rm(THREAD); char *name_str = element_klass->name()->as_C_string(); int len = element_klass->name()->utf8_length(); @@ -133,7 +130,11 @@ new_str[idx++] = ';'; } new_str[idx++] = '\0'; - name = oopFactory::new_symbol_handle(new_str, CHECK_0); + name = SymbolTable::new_symbol(new_str, CHECK_0); + if (element_klass->oop_is_instance()) { + instanceKlass* ik = instanceKlass::cast(element_klass()); + ik->set_array_name(name); + } } objArrayKlass o; @@ -142,12 +143,15 @@ this_oop, CHECK_0); - // Initialize instance variables objArrayKlass* oak = objArrayKlass::cast(k()); oak->set_dimension(n); oak->set_element_klass(element_klass()); - oak->set_name(name()); + oak->set_name(name); + // decrement refcount because object arrays are not explicitly freed. The + // instanceKlass array_name() keeps the name counted while the klass is + // loaded. + name->decrement_refcount(); klassOop bk; if (element_klass->oop_is_objArray()) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/oop.hpp --- a/src/share/vm/oops/oop.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/oop.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -127,7 +127,6 @@ bool is_instanceRef() const; bool is_array() const; bool is_objArray() const; - bool is_symbol() const; bool is_klass() const; bool is_thread() const; bool is_method() const; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/oop.inline.hpp --- a/src/share/vm/oops/oop.inline.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/oop.inline.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -140,7 +140,6 @@ inline bool oopDesc::is_objArray() const { return blueprint()->oop_is_objArray(); } inline bool oopDesc::is_typeArray() const { return blueprint()->oop_is_typeArray(); } inline bool oopDesc::is_javaArray() const { return blueprint()->oop_is_javaArray(); } -inline bool oopDesc::is_symbol() const { return blueprint()->oop_is_symbol(); } inline bool oopDesc::is_klass() const { return blueprint()->oop_is_klass(); } inline bool oopDesc::is_thread() const { return blueprint()->oop_is_thread(); } inline bool oopDesc::is_method() const { return blueprint()->oop_is_method(); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/oopsHierarchy.hpp --- a/src/share/vm/oops/oopsHierarchy.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/oopsHierarchy.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -49,7 +49,6 @@ typedef class typeArrayOopDesc* typeArrayOop; typedef class constantPoolOopDesc* constantPoolOop; typedef class constantPoolCacheOopDesc* constantPoolCacheOop; -typedef class symbolOopDesc* symbolOop; typedef class klassOopDesc* klassOop; typedef class markOopDesc* markOop; typedef class compiledICHolderOopDesc* compiledICHolderOop; @@ -166,7 +165,6 @@ DEF_OOP(constantPoolCache); DEF_OOP(objArray); DEF_OOP(typeArray); -DEF_OOP(symbol); DEF_OOP(klass); DEF_OOP(compiledICHolder); @@ -190,7 +188,6 @@ class typeArrayKlass; class constantPoolKlass; class constantPoolCacheKlass; -class symbolKlass; class compiledICHolderKlass; #endif // SHARE_VM_OOPS_OOPSHIERARCHY_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/symbol.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/oops/symbol.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -0,0 +1,231 @@ +/* + * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + + +#include "precompiled.hpp" +#include "oops/oop.inline.hpp" +#include "oops/symbol.hpp" +#include "runtime/os.hpp" +#include "memory/allocation.inline.hpp" + +Symbol::Symbol(const u1* name, int length) : _refcount(0), _length(length) { + _identity_hash = os::random(); + for (int i = 0; i < _length; i++) { + byte_at_put(i, name[i]); + } +} + +void* Symbol::operator new(size_t size, int len) { + return (void *) AllocateHeap(object_size(len) * HeapWordSize, "symbol"); +} + +// ------------------------------------------------------------------ +// Symbol::equals +// +// Compares the symbol with a string of the given length. +bool Symbol::equals(const char* str, int len) const { + int l = utf8_length(); + if (l != len) return false; + while (l-- > 0) { + if (str[l] != (char) byte_at(l)) + return false; + } + assert(l == -1, "we should be at the beginning"); + return true; +} + + +// ------------------------------------------------------------------ +// Symbol::starts_with +// +// Tests if the symbol starts with the specified prefix of the given +// length. +bool Symbol::starts_with(const char* prefix, int len) const { + if (len > utf8_length()) return false; + while (len-- > 0) { + if (prefix[len] != (char) byte_at(len)) + return false; + } + assert(len == -1, "we should be at the beginning"); + return true; +} + + +// ------------------------------------------------------------------ +// Symbol::index_of +// +// Finds if the given string is a substring of this symbol's utf8 bytes. +// Return -1 on failure. Otherwise return the first index where str occurs. +int Symbol::index_of_at(int i, const char* str, int len) const { + assert(i >= 0 && i <= utf8_length(), "oob"); + if (len <= 0) return 0; + char first_char = str[0]; + address bytes = (address) ((Symbol*)this)->base(); + address limit = bytes + utf8_length() - len; // inclusive limit + address scan = bytes + i; + if (scan > limit) + return -1; + for (;;) { + scan = (address) memchr(scan, first_char, (limit + 1 - scan)); + if (scan == NULL) + return -1; // not found + assert(scan >= bytes+i && scan <= limit, "scan oob"); + if (memcmp(scan, str, len) == 0) + return (int)(scan - bytes); + } +} + + +char* Symbol::as_C_string(char* buf, int size) const { + if (size > 0) { + int len = MIN2(size - 1, utf8_length()); + for (int i = 0; i < len; i++) { + buf[i] = byte_at(i); + } + buf[len] = '\0'; + } + return buf; +} + +char* Symbol::as_C_string() const { + int len = utf8_length(); + char* str = NEW_RESOURCE_ARRAY(char, len + 1); + return as_C_string(str, len + 1); +} + +char* Symbol::as_C_string_flexible_buffer(Thread* t, + char* buf, int size) const { + char* str; + int len = utf8_length(); + int buf_len = len + 1; + if (size < buf_len) { + str = NEW_RESOURCE_ARRAY(char, buf_len); + } else { + str = buf; + } + return as_C_string(str, buf_len); +} + +void Symbol::print_symbol_on(outputStream* st) const { + st = st ? st : tty; + int length = UTF8::unicode_length((const char*)bytes(), utf8_length()); + const char *ptr = (const char *)bytes(); + jchar value; + for (int index = 0; index < length; index++) { + ptr = UTF8::next(ptr, &value); + if (value >= 32 && value < 127 || value == '\'' || value == '\\') { + st->put(value); + } else { + st->print("\\u%04x", value); + } + } +} + +jchar* Symbol::as_unicode(int& length) const { + Symbol* this_ptr = (Symbol*)this; + length = UTF8::unicode_length((char*)this_ptr->bytes(), utf8_length()); + jchar* result = NEW_RESOURCE_ARRAY(jchar, length); + if (length > 0) { + UTF8::convert_to_unicode((char*)this_ptr->bytes(), result, length); + } + return result; +} + +const char* Symbol::as_klass_external_name(char* buf, int size) const { + if (size > 0) { + char* str = as_C_string(buf, size); + int length = (int)strlen(str); + // Turn all '/'s into '.'s (also for array klasses) + for (int index = 0; index < length; index++) { + if (str[index] == '/') { + str[index] = '.'; + } + } + return str; + } else { + return buf; + } +} + +const char* Symbol::as_klass_external_name() const { + char* str = as_C_string(); + int length = (int)strlen(str); + // Turn all '/'s into '.'s (also for array klasses) + for (int index = 0; index < length; index++) { + if (str[index] == '/') { + str[index] = '.'; + } + } + return str; +} + + +void Symbol::print_on(outputStream* st) const { + if (this == NULL) { + st->print_cr("NULL"); + } else { + st->print("Symbol: '"); + print_symbol_on(st); + st->print("'"); + st->print(" count %d", refcount()); + } +} + +// The print_value functions are present in all builds, to support the +// disassembler and error reporting. +void Symbol::print_value_on(outputStream* st) const { + if (this == NULL) { + st->print("NULL"); + } else { + st->print("'"); + for (int i = 0; i < utf8_length(); i++) { + st->print("%c", byte_at(i)); + } + st->print("'"); + } +} + +void Symbol::increment_refcount() { + // Only increment the refcount if positive. If negative either + // overflow has occurred or it is a permanent symbol in a read only + // shared archive. + if (_refcount >= 0) { + Atomic::inc(&_refcount); + NOT_PRODUCT(Atomic::inc(&_total_count);) + } +} + +void Symbol::decrement_refcount() { + if (_refcount >= 0) { + Atomic::dec(&_refcount); +#ifdef ASSERT + if (_refcount < 0) { + print(); + assert(false, "reference count underflow for symbol"); + } +#endif + } +} + +NOT_PRODUCT(int Symbol::_total_count = 0;) diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/symbol.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/oops/symbol.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -0,0 +1,223 @@ +/* + * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_OOPS_SYMBOL_HPP +#define SHARE_VM_OOPS_SYMBOL_HPP + +#include "utilities/utf8.hpp" +#include "memory/allocation.hpp" + +// A Symbol is a canonicalized string. +// All Symbols reside in global SymbolTable and are reference counted. + +// Reference counting +// +// All Symbols are allocated and added to the SymbolTable. +// When a class is unloaded, the reference counts of the Symbol pointers in +// the ConstantPool and in instanceKlass (see release_C_heap_structures) are +// decremented. When the reference count for a Symbol goes to 0, the garbage +// collector can free the Symbol and remove it from the SymbolTable. +// +// 0) Symbols need to be reference counted when a pointer to the Symbol is +// saved in persistent storage. This does not include the pointer +// in the SymbolTable bucket (the _literal field in HashtableEntry) +// that points to the Symbol. All other stores of a Symbol* +// to a field of a persistent variable (e.g., the _name filed in +// FieldAccessInfo or _ptr in a CPSlot) is reference counted. +// +// 1) The lookup of a "name" in the SymbolTable either creates a Symbol F for +// "name" and returns a pointer to F or finds a pre-existing Symbol F for +// "name" and returns a pointer to it. In both cases the reference count for F +// is incremented under the assumption that a pointer to F will be created from +// the return value. Thus the increment of the reference count is on the lookup +// and not on the assignment to the new Symbol*. That is +// Symbol* G = lookup() +// ^ increment on lookup() +// and not +// Symbol* G = lookup() +// ^ increment on assignmnet +// The reference count must be decremented manually when the copy of the +// pointer G is destroyed. +// +// 2) For a local Symbol* A that is a copy of an existing Symbol* B, the +// reference counting is elided when the scope of B is greater than the scope +// of A. For example, in the code fragment +// below "klass" is passed as a parameter to the method. Symbol* "kn" +// is a copy of the name in "klass". +// +// Symbol* kn = klass->name(); +// unsigned int d_hash = dictionary()->compute_hash(kn, class_loader); +// +// The scope of "klass" is greater than the scope of "kn" so the reference +// counting for "kn" is elided. +// +// Symbol* copied from ConstantPool entries are good candidates for reference +// counting elision. The ConstantPool entries for a class C exist until C is +// unloaded. If a Symbol* is copied out of the ConstantPool into Symbol* X, +// the Symbol* in the ConstantPool will in general out live X so the reference +// counting on X can be elided. +// +// For cases where the scope of A is not greater than the scope of B, +// the reference counting is explicitly done. See ciSymbol, +// ResolutionErrorEntry and ClassVerifier for examples. +// +// 3) When a Symbol K is created for temporary use, generally for substrings of +// an existing symbol or to create a new symbol, assign it to a +// TempNewSymbol. The SymbolTable methods new_symbol(), lookup() +// and probe() all potentially return a pointer to a new Symbol. +// The allocation (or lookup) of K increments the reference count for K +// and the destructor decrements the reference count. +// +// Another example of TempNewSymbol usage is parsed_name used in +// ClassFileParser::parseClassFile() where parsed_name is used in the cleanup +// after a failed attempt to load a class. Here parsed_name is a +// TempNewSymbol (passed in as a parameter) so the reference count on its symbol +// will be decremented when it goes out of scope. + +class Symbol : public CHeapObj { + friend class VMStructs; + friend class SymbolTable; + friend class MoveSymbols; + private: + volatile int _refcount; + int _identity_hash; + unsigned short _length; // number of UTF8 characters in the symbol + jbyte _body[1]; + + enum { + // max_symbol_length is constrained by type of _length + max_symbol_length = (1 << 16) -1 + }; + + static int object_size(int length) { + size_t size = heap_word_size(sizeof(Symbol) + length); + return align_object_size(size); + } + + void byte_at_put(int index, int value) { + assert(index >=0 && index < _length, "symbol index overflow"); + _body[index] = value; + } + + Symbol(const u1* name, int length); + void* operator new(size_t size, int len); + + public: + // Low-level access (used with care, since not GC-safe) + const jbyte* base() const { return &_body[0]; } + + int object_size() { return object_size(utf8_length()); } + + // Returns the largest size symbol we can safely hold. + static int max_length() { + return max_symbol_length; + } + + int identity_hash() { + return _identity_hash; + } + + // Reference counting. See comments above this class for when to use. + int refcount() const { return _refcount; } + void increment_refcount(); + void decrement_refcount(); + + int byte_at(int index) const { + assert(index >=0 && index < _length, "symbol index overflow"); + return base()[index]; + } + + const jbyte* bytes() const { return base(); } + + int utf8_length() const { return _length; } + + // Compares the symbol with a string. + bool equals(const char* str, int len) const; + bool equals(const char* str) const { return equals(str, (int) strlen(str)); } + + // Tests if the symbol starts with the given prefix. + bool starts_with(const char* prefix, int len) const; + bool starts_with(const char* prefix) const { + return starts_with(prefix, (int) strlen(prefix)); + } + + // Tests if the symbol starts with the given prefix. + int index_of_at(int i, const char* str, int len) const; + int index_of_at(int i, const char* str) const { + return index_of_at(i, str, (int) strlen(str)); + } + + // Three-way compare for sorting; returns -1/0/1 if receiver is than arg + // note that the ordering is not alfabetical + inline int fast_compare(Symbol* other) const; + + // Returns receiver converted to null-terminated UTF-8 string; string is + // allocated in resource area, or in the char buffer provided by caller. + char* as_C_string() const; + char* as_C_string(char* buf, int size) const; + // Use buf if needed buffer length is <= size. + char* as_C_string_flexible_buffer(Thread* t, char* buf, int size) const; + + + // Returns a null terminated utf8 string in a resource array + char* as_utf8() const { return as_C_string(); } + char* as_utf8_flexible_buffer(Thread* t, char* buf, int size) const { + return as_C_string_flexible_buffer(t, buf, size); + } + + jchar* as_unicode(int& length) const; + + // Treating this symbol as a class name, returns the Java name for the class. + // String is allocated in resource area if buffer is not provided. + // See Klass::external_name() + const char* as_klass_external_name() const; + const char* as_klass_external_name(char* buf, int size) const; + + // Printing + void print_symbol_on(outputStream* st = NULL) const; + void print_on(outputStream* st) const; // First level print + void print_value_on(outputStream* st) const; // Second level print. + + // printing on default output stream + void print() { print_on(tty); } + void print_value() { print_value_on(tty); } + +#ifndef PRODUCT + // Empty constructor to create a dummy symbol object on stack + // only for getting its vtable pointer. + Symbol() { } + + static int _total_count; +#endif +}; + +// Note: this comparison is used for vtable sorting only; it doesn't matter +// what order it defines, as long as it is a total, time-invariant order +// Since Symbol*s are in C_HEAP, their relative order in memory never changes, +// so use address comparison for speed +int Symbol::fast_compare(Symbol* other) const { + return (((uintptr_t)this < (uintptr_t)other) ? -1 + : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1); +} +#endif // SHARE_VM_OOPS_SYMBOL_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/symbolKlass.cpp --- a/src/share/vm/oops/symbolKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -/* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/symbolTable.hpp" -#include "memory/gcLocker.hpp" -#include "oops/oop.inline.hpp" -#include "oops/symbolKlass.hpp" -#include "oops/symbolOop.hpp" -#include "runtime/handles.inline.hpp" - -symbolOop symbolKlass::allocate_symbol(u1* name, int len, TRAPS) { - // Don't allow symbol oops to be created which cannot fit in a symbolOop. - if (len > symbolOopDesc::max_length()) { - THROW_MSG_0(vmSymbols::java_lang_InternalError(), - "name is too long to represent"); - } - int size = symbolOopDesc::object_size(len); - symbolKlassHandle h_k(THREAD, as_klassOop()); - symbolOop sym = (symbolOop) - CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); - assert(!sym->is_parsable(), "not expecting parsability yet."); - No_Safepoint_Verifier no_safepoint; - sym->set_utf8_length(len); - for (int i = 0; i < len; i++) { - sym->byte_at_put(i, name[i]); - } - // Let the first emptySymbol be created and - // ensure only one is ever created. - assert(sym->is_parsable() || Universe::emptySymbol() == NULL, - "should be parsable here."); - return sym; -} - -bool symbolKlass::allocate_symbols(int names_count, const char** names, - int* lengths, symbolOop* sym_oops, TRAPS) { - if (UseConcMarkSweepGC || UseParallelGC) { - // Concurrent GC needs to mark all the allocated symbol oops after - // the remark phase which isn't done below (except the first symbol oop). - // So return false which will let the symbols be allocated one by one. - // The parallel collector uses an object start array to find the - // start of objects on a dirty card. The object start array is not - // updated for the start of each symbol so is not precise. During - // object array verification this causes a verification failure. - // In a product build this causes extra searching for the start of - // a symbol. As with the concurrent collector a return of false will - // cause each symbol to be allocated separately and in the case - // of the parallel collector will cause the object - // start array to be updated. - return false; - } - - assert(names_count > 0, "can't allocate 0 symbols"); - - int total_size = 0; - int i, sizes[SymbolTable::symbol_alloc_batch_size]; - for (i=0; i symbolOopDesc::max_length()) { - return false; - } - int sz = symbolOopDesc::object_size(len); - sizes[i] = sz * HeapWordSize; - total_size += sz; - } - symbolKlassHandle h_k(THREAD, as_klassOop()); - HeapWord* base = Universe::heap()->permanent_mem_allocate(total_size); - if (base == NULL) { - return false; - } - - // CAN'T take any safepoint during the initialization of the symbol oops ! - No_Safepoint_Verifier nosafepoint; - - klassOop sk = h_k(); - int pos = 0; - for (i=0; iset_mark(markOopDesc::prototype()); - s->set_klass(sk); - s->set_utf8_length(lengths[i]); - const char* name = names[i]; - for (int j=0; jbyte_at_put(j, name[j]); - } - - assert(s->is_parsable(), "should be parsable here."); - - sym_oops[i] = s; - pos += sizes[i]; - } - return true; -} - -klassOop symbolKlass::create_klass(TRAPS) { - symbolKlass o; - KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); - KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL); - // Make sure size calculation is right - assert(k()->size() == align_object_size(header_size()), "wrong size for object"); -// java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror - return k(); -} - -int symbolKlass::oop_size(oop obj) const { - assert(obj->is_symbol(),"must be a symbol"); - symbolOop s = symbolOop(obj); - int size = s->object_size(); - return size; -} - -bool symbolKlass::oop_is_parsable(oop obj) const { - assert(obj->is_symbol(),"must be a symbol"); - symbolOop s = symbolOop(obj); - return s->object_is_parsable(); -} - -void symbolKlass::oop_follow_contents(oop obj) { - assert (obj->is_symbol(), "object must be symbol"); - // Performance tweak: We skip iterating over the klass pointer since we - // know that Universe::symbolKlassObj never moves. - // Note: do not follow next link here (see SymbolTable::follow_contents) -} - -#ifndef SERIALGC -void symbolKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) { - assert (obj->is_symbol(), "object must be symbol"); - // Performance tweak: We skip iterating over the klass pointer since we - // know that Universe::symbolKlassObj never moves. - // Note: do not follow next link here (see SymbolTable::follow_contents) -} -#endif // SERIALGC - -int symbolKlass::oop_oop_iterate(oop obj, OopClosure* blk) { - assert(obj->is_symbol(), "object must be symbol"); - symbolOop s = symbolOop(obj); - // Get size before changing pointers. - // Don't call size() or oop_size() since that is a virtual call. - int size = s->object_size(); - // Performance tweak: We skip iterating over the klass pointer since we - // know that Universe::symbolKlassObj never moves. - return size; -} - - -int symbolKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { - assert(obj->is_symbol(), "object must be symbol"); - symbolOop s = symbolOop(obj); - // Get size before changing pointers. - // Don't call size() or oop_size() since that is a virtual call. - int size = s->object_size(); - // Performance tweak: We skip iterating over the klass pointer since we - // know that Universe::symbolKlassObj never moves. - return size; -} - - -int symbolKlass::oop_adjust_pointers(oop obj) { - assert(obj->is_symbol(), "should be symbol"); - symbolOop s = symbolOop(obj); - // Get size before changing pointers. - // Don't call size() or oop_size() since that is a virtual call. - int size = s->object_size(); - // Performance tweak: We skip iterating over the klass pointer since we - // know that Universe::symbolKlassObj never moves. - return size; -} - - -#ifndef SERIALGC -void symbolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { - assert(obj->is_symbol(), "should be symbol"); -} - -int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { - assert(obj->is_symbol(), "should be symbol"); - return symbolOop(obj)->object_size(); -} - -int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, - HeapWord* beg_addr, HeapWord* end_addr) { - assert(obj->is_symbol(), "should be symbol"); - return symbolOop(obj)->object_size(); -} -#endif // SERIALGC - -#ifndef PRODUCT -// Printing - -void symbolKlass::oop_print_on(oop obj, outputStream* st) { - st->print("Symbol: '"); - symbolOop(obj)->print_symbol_on(st); - st->print("'"); -} - -#endif //PRODUCT - -void symbolKlass::oop_print_value_on(oop obj, outputStream* st) { - symbolOop sym = symbolOop(obj); - st->print("'"); - for (int i = 0; i < sym->utf8_length(); i++) { - st->print("%c", sym->byte_at(i)); - } - st->print("'"); -} - -const char* symbolKlass::internal_name() const { - return "{symbol}"; -} diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/symbolKlass.hpp --- a/src/share/vm/oops/symbolKlass.hpp Thu Feb 03 17:22:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_OOPS_SYMBOLKLASS_HPP -#define SHARE_VM_OOPS_SYMBOLKLASS_HPP - -#include "oops/typeArrayKlass.hpp" - -// a symbolKlass is the klass for a symbolOop - -class symbolKlass : public Klass { - friend class VMStructs; - private: - juint _alloc_size; // allocation profiling support - public: - // Allocation - DEFINE_ALLOCATE_PERMANENT(symbolKlass); - static klassOop create_klass(TRAPS); - symbolOop allocate_symbol(u1* name, int len, TRAPS); // Assumes no characters larger than 0x7F - bool allocate_symbols(int names_count, const char** names, int* lengths, symbolOop* sym_oops, TRAPS); - - // Test operation - bool oop_is_symbol() const { return true; } - - // Casting from klassOop - static symbolKlass* cast(klassOop k) { - assert(k->klass_part()->oop_is_symbol(), "cast to symbolKlass"); - return (symbolKlass*) k->klass_part(); - } - - static int header_size() { return oopDesc::header_size() + sizeof(symbolKlass)/HeapWordSize; } - int oop_size(oop obj) const; - int klass_oop_size() const { return object_size(); } - int object_size() const { return align_object_size(header_size()); } - - // Garbage collection - void oop_follow_contents(oop obj); - int oop_adjust_pointers(oop obj); - bool oop_is_parsable(oop obj) const; - - // Parallel Scavenge and Parallel Old - PARALLEL_GC_DECLS - - // Allocation profiling support - juint alloc_size() const { return _alloc_size; } - void set_alloc_size(juint n) { _alloc_size = n; } - - // Iterators - int oop_oop_iterate(oop obj, OopClosure* blk); - int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); - - // Printing - void oop_print_value_on(oop obj, outputStream* st); -#ifndef PRODUCT - void oop_print_on(oop obj, outputStream* st); -#endif //PRODUCT - const char* internal_name() const; -}; - -#endif // SHARE_VM_OOPS_SYMBOLKLASS_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/symbolOop.cpp --- a/src/share/vm/oops/symbolOop.cpp Thu Feb 03 17:22:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" - - -// ------------------------------------------------------------------ -// symbolOopDesc::equals -// -// Compares the symbol with a string of the given length. -bool symbolOopDesc::equals(const char* str, int len) const { - int l = utf8_length(); - if (l != len) return false; - while (l-- > 0) { - if (str[l] != (char) byte_at(l)) - return false; - } - assert(l == -1, "we should be at the beginning"); - return true; -} - - -// ------------------------------------------------------------------ -// symbolOopDesc::starts_with -// -// Tests if the symbol starts with the specified prefix of the given -// length. -bool symbolOopDesc::starts_with(const char* prefix, int len) const { - if (len > utf8_length()) return false; - while (len-- > 0) { - if (prefix[len] != (char) byte_at(len)) - return false; - } - assert(len == -1, "we should be at the beginning"); - return true; -} - - -// ------------------------------------------------------------------ -// symbolOopDesc::index_of -// -// Finds if the given string is a substring of this symbol's utf8 bytes. -// Return -1 on failure. Otherwise return the first index where str occurs. -int symbolOopDesc::index_of_at(int i, const char* str, int len) const { - assert(i >= 0 && i <= utf8_length(), "oob"); - if (len <= 0) return 0; - char first_char = str[0]; - address bytes = (address) ((symbolOopDesc*)this)->base(); - address limit = bytes + utf8_length() - len; // inclusive limit - address scan = bytes + i; - if (scan > limit) - return -1; - for (;;) { - scan = (address) memchr(scan, first_char, (limit + 1 - scan)); - if (scan == NULL) - return -1; // not found - assert(scan >= bytes+i && scan <= limit, "scan oob"); - if (memcmp(scan, str, len) == 0) - return (int)(scan - bytes); - } -} - - -char* symbolOopDesc::as_C_string(char* buf, int size) const { - if (size > 0) { - int len = MIN2(size - 1, utf8_length()); - for (int i = 0; i < len; i++) { - buf[i] = byte_at(i); - } - buf[len] = '\0'; - } - return buf; -} - -char* symbolOopDesc::as_C_string() const { - int len = utf8_length(); - char* str = NEW_RESOURCE_ARRAY(char, len + 1); - return as_C_string(str, len + 1); -} - -char* symbolOopDesc::as_C_string_flexible_buffer(Thread* t, - char* buf, int size) const { - char* str; - int len = utf8_length(); - int buf_len = len + 1; - if (size < buf_len) { - str = NEW_RESOURCE_ARRAY(char, buf_len); - } else { - str = buf; - } - return as_C_string(str, buf_len); -} - -void symbolOopDesc::print_symbol_on(outputStream* st) { - st = st ? st : tty; - int length = UTF8::unicode_length((const char*)bytes(), utf8_length()); - const char *ptr = (const char *)bytes(); - jchar value; - for (int index = 0; index < length; index++) { - ptr = UTF8::next(ptr, &value); - if (value >= 32 && value < 127 || value == '\'' || value == '\\') { - st->put(value); - } else { - st->print("\\u%04x", value); - } - } -} - -jchar* symbolOopDesc::as_unicode(int& length) const { - symbolOopDesc* this_ptr = (symbolOopDesc*)this; - length = UTF8::unicode_length((char*)this_ptr->bytes(), utf8_length()); - jchar* result = NEW_RESOURCE_ARRAY(jchar, length); - if (length > 0) { - UTF8::convert_to_unicode((char*)this_ptr->bytes(), result, length); - } - return result; -} - -const char* symbolOopDesc::as_klass_external_name(char* buf, int size) const { - if (size > 0) { - char* str = as_C_string(buf, size); - int length = (int)strlen(str); - // Turn all '/'s into '.'s (also for array klasses) - for (int index = 0; index < length; index++) { - if (str[index] == '/') { - str[index] = '.'; - } - } - return str; - } else { - return buf; - } -} - -const char* symbolOopDesc::as_klass_external_name() const { - char* str = as_C_string(); - int length = (int)strlen(str); - // Turn all '/'s into '.'s (also for array klasses) - for (int index = 0; index < length; index++) { - if (str[index] == '/') { - str[index] = '.'; - } - } - return str; -} diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/symbolOop.hpp --- a/src/share/vm/oops/symbolOop.hpp Thu Feb 03 17:22:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -/* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_OOPS_SYMBOLOOP_HPP -#define SHARE_VM_OOPS_SYMBOLOOP_HPP - -#include "oops/typeArrayOop.hpp" -#include "utilities/utf8.hpp" - -// A symbolOop is a canonicalized string. -// All symbolOops reside in global symbolTable. -// See oopFactory::new_symbol for how to allocate a symbolOop - -class symbolOopDesc : public oopDesc { - friend class VMStructs; - private: - unsigned short _length; // number of UTF8 characters in the symbol - jbyte _body[1]; - - enum { - // max_symbol_length is constrained by type of _length - max_symbol_length = (1 << 16) -1 - }; - public: - - // Low-level access (used with care, since not GC-safe) - jbyte* base() { return &_body[0]; } - - - // Returns the largest size symbol we can safely hold. - static int max_length() { - return max_symbol_length; - } - - static int object_size(int length) { - int size = header_size() + (sizeof(unsigned short) + length + HeapWordSize - 1) / HeapWordSize; - return align_object_size(size); - } - - int object_size() { return object_size(utf8_length()); } - - int byte_at(int index) const { - assert(index >=0 && index < _length, "symbol index overflow"); - return ((symbolOopDesc*)this)->base()[index]; - } - - void byte_at_put(int index, int value) { - assert(index >=0 && index < _length, "symbol index overflow"); - ((symbolOopDesc*)this)->base()[index] = value; - } - - jbyte* bytes() { return base(); } - - int utf8_length() const { return _length; } - - void set_utf8_length(int len) { _length = len; } - - // Compares the symbol with a string. - bool equals(const char* str, int len) const; - bool equals(const char* str) const { return equals(str, (int) strlen(str)); } - - // Tests if the symbol starts with the given prefix. - bool starts_with(const char* prefix, int len) const; - bool starts_with(const char* prefix) const { - return starts_with(prefix, (int) strlen(prefix)); - } - - // Tests if the symbol starts with the given prefix. - int index_of_at(int i, const char* str, int len) const; - int index_of_at(int i, const char* str) const { - return index_of_at(i, str, (int) strlen(str)); - } - - // Three-way compare for sorting; returns -1/0/1 if receiver is than arg - // note that the ordering is not alfabetical - inline int fast_compare(symbolOop other) const; - - // Returns receiver converted to null-terminated UTF-8 string; string is - // allocated in resource area, or in the char buffer provided by caller. - char* as_C_string() const; - char* as_C_string(char* buf, int size) const; - // Use buf if needed buffer length is <= size. - char* as_C_string_flexible_buffer(Thread* t, char* buf, int size) const; - - - // Returns a null terminated utf8 string in a resource array - char* as_utf8() const { return as_C_string(); } - char* as_utf8_flexible_buffer(Thread* t, char* buf, int size) const { - return as_C_string_flexible_buffer(t, buf, size); - } - - jchar* as_unicode(int& length) const; - - // Treating this symbol as a class name, returns the Java name for the class. - // String is allocated in resource area if buffer is not provided. - // See Klass::external_name() - const char* as_klass_external_name() const; - const char* as_klass_external_name(char* buf, int size) const; - - bool object_is_parsable() const { - return (utf8_length() > 0 || (oop)this == Universe::emptySymbol()); - } - - // Printing - void print_symbol_on(outputStream* st = NULL); -}; - - -// Note: this comparison is used for vtable sorting only; it doesn't matter -// what order it defines, as long as it is a total, time-invariant order -// Since symbolOops are in permSpace, their relative order in memory never changes, -// so use address comparison for speed -int symbolOopDesc::fast_compare(symbolOop other) const { - return (((uintptr_t)this < (uintptr_t)other) ? -1 - : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1); -} - -#endif // SHARE_VM_OOPS_SYMBOLOOP_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/oops/typeArrayKlass.cpp --- a/src/share/vm/oops/typeArrayKlass.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/oops/typeArrayKlass.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -53,16 +53,15 @@ const char* name_str, TRAPS) { typeArrayKlass o; - symbolHandle sym(symbolOop(NULL)); - // bootstrapping: don't create sym if symbolKlass not created yet - if (Universe::symbolKlassObj() != NULL && name_str != NULL) { - sym = oopFactory::new_symbol_handle(name_str, CHECK_NULL); + Symbol* sym = NULL; + if (name_str != NULL) { + sym = SymbolTable::new_symbol(name_str, CHECK_NULL); } KlassHandle klassklass (THREAD, Universe::typeArrayKlassKlassObj()); arrayKlassHandle k = base_create_array_klass(o.vtbl_value(), header_size(), klassklass, CHECK_NULL); typeArrayKlass* ak = typeArrayKlass::cast(k()); - ak->set_name(sym()); + ak->set_name(sym); ak->set_layout_helper(array_layout_helper(type)); assert(scale == (1 << ak->log2_element_size()), "scale must check out"); assert(ak->oop_is_javaArray(), "sanity"); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/opto/runtime.cpp --- a/src/share/vm/opto/runtime.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/opto/runtime.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -477,7 +477,7 @@ const TypeFunc *OptoRuntime::uncommon_trap_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); - // symbolOop name of class to be loaded + // Symbol* name of class to be loaded fields[TypeFunc::Parms+0] = TypeInt::INT; const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); @@ -586,7 +586,7 @@ const TypeFunc *OptoRuntime::Math_D_D_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); - // symbolOop name of class to be loaded + // Symbol* name of class to be loaded fields[TypeFunc::Parms+0] = Type::DOUBLE; fields[TypeFunc::Parms+1] = Type::HALF; const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/precompiled.hpp --- a/src/share/vm/precompiled.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/precompiled.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -169,7 +169,7 @@ # include "oops/oop.inline.hpp" # include "oops/oop.inline2.hpp" # include "oops/oopsHierarchy.hpp" -# include "oops/symbolOop.hpp" +# include "oops/symbol.hpp" # include "oops/typeArrayKlass.hpp" # include "oops/typeArrayOop.hpp" # include "prims/jni.h" diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jni.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -40,7 +40,7 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" #include "oops/typeArrayOop.hpp" #include "prims/jni.h" @@ -338,16 +338,15 @@ // Since exceptions can be thrown, class initialization can take place // if name is NULL no check for class name in .class stream has to be made. - symbolHandle class_name; if (name != NULL) { const int str_len = (int)strlen(name); - if (str_len > symbolOopDesc::max_length()) { + if (str_len > Symbol::max_length()) { // It's impossible to create this class; the name cannot fit // into the constant pool. THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); } - class_name = oopFactory::new_symbol_handle(name, str_len, CHECK_NULL); } + TempNewSymbol class_name = SymbolTable::new_symbol(name, THREAD); ResourceMark rm(THREAD); ClassFileStream st((u1*) buf, bufLen, NULL); @@ -394,7 +393,7 @@ // Sanity check the name: it cannot be null or larger than the maximum size // name we can fit in the constant pool. - if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) { + if (name == NULL || (int)strlen(name) > Symbol::max_length()) { THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); } @@ -411,8 +410,8 @@ k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) { JavaValue result(T_OBJECT); JavaCalls::call_static(&result, k, - vmSymbolHandles::getFromClass_name(), - vmSymbolHandles::void_class_signature(), + vmSymbols::getFromClass_name(), + vmSymbols::void_class_signature(), thread); if (HAS_PENDING_EXCEPTION) { Handle ex(thread, thread->pending_exception()); @@ -430,7 +429,7 @@ loader = Handle(THREAD, SystemDictionary::java_system_loader()); } - symbolHandle sym = oopFactory::new_symbol_handle(name, CHECK_NULL); + TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL); result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, thread); @@ -609,7 +608,7 @@ DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret); instanceKlass* k = instanceKlass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz))); - symbolHandle name = symbolHandle(THREAD, k->name()); + Symbol* name = k->name(); Handle class_loader (THREAD, k->class_loader()); Handle protection_domain (THREAD, k->protection_domain()); THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK); @@ -663,8 +662,8 @@ ex, KlassHandle(THREAD, SystemDictionary::Throwable_klass()), - vmSymbolHandles::printStackTrace_name(), - vmSymbolHandles::void_method_signature(), + vmSymbols::printStackTrace_name(), + vmSymbols::void_method_signature(), THREAD); // If an exception is thrown in the call it gets thrown away. Not much // we can do with it. The native code that calls this, does not check @@ -838,8 +837,7 @@ virtual void get_double () = 0; virtual void get_object () = 0; - JNI_ArgumentPusher(Thread *thread, symbolOop signature) - : SignatureIterator(thread, signature) { + JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) { this->_return_type = T_ILLEGAL; _arguments = NULL; } @@ -895,12 +893,12 @@ } public: - JNI_ArgumentPusherVaArg(Thread *thread, symbolOop signature, va_list rap) - : JNI_ArgumentPusher(thread, signature) { + JNI_ArgumentPusherVaArg(Symbol* signature, va_list rap) + : JNI_ArgumentPusher(signature) { set_ap(rap); } - JNI_ArgumentPusherVaArg(Thread *thread, jmethodID method_id, va_list rap) - : JNI_ArgumentPusher(thread, JNIHandles::resolve_jmethod_id(method_id)->signature()) { + JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap) + : JNI_ArgumentPusher(JNIHandles::resolve_jmethod_id(method_id)->signature()) { set_ap(rap); } @@ -966,12 +964,12 @@ inline void set_ap(const jvalue *rap) { _ap = rap; } public: - JNI_ArgumentPusherArray(Thread *thread, symbolOop signature, const jvalue *rap) - : JNI_ArgumentPusher(thread, signature) { + JNI_ArgumentPusherArray(Symbol* signature, const jvalue *rap) + : JNI_ArgumentPusher(signature) { set_ap(rap); } - JNI_ArgumentPusherArray(Thread *thread, jmethodID method_id, const jvalue *rap) - : JNI_ArgumentPusher(thread, JNIHandles::resolve_jmethod_id(method_id)->signature()) { + JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap) + : JNI_ArgumentPusher(JNIHandles::resolve_jmethod_id(method_id)->signature()) { set_ap(rap); } @@ -1038,8 +1036,8 @@ KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc) if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass()); KlassHandle spec_klass (THREAD, method->method_holder()); - symbolHandle name (THREAD, method->name()); - symbolHandle signature (THREAD, method->signature()); + Symbol* name = method->name(); + Symbol* signature = method->signature(); CallInfo info; LinkResolver::resolve_interface_call(info, recv, recv_klass, spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle())); return info.selected_method(); @@ -1051,8 +1049,8 @@ KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc) if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass()); KlassHandle spec_klass (THREAD, method->method_holder()); - symbolHandle name (THREAD, method->name()); - symbolHandle signature (THREAD, method->signature()); + Symbol* name = method->name(); + Symbol* signature = method->signature(); CallInfo info; LinkResolver::resolve_virtual_call(info, recv, recv_klass, spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle())); return info.selected_method(); @@ -1073,7 +1071,7 @@ assert(method->is_static(), "method should be static"); // Fill out JavaCallArguments object - args->iterate( Fingerprinter(THREAD, method).fingerprint() ); + args->iterate( Fingerprinter(method).fingerprint() ); // Initialize result type result->set_type(args->get_ret_type()); @@ -1149,7 +1147,7 @@ args->push_receiver(h_recv); // Push jobject handle // Fill out JavaCallArguments object - args->iterate( Fingerprinter(THREAD, method).fingerprint() ); + args->iterate( Fingerprinter(method).fingerprint() ); // Initialize result type result->set_type(args->get_ret_type()); @@ -1196,7 +1194,7 @@ instanceOop i = alloc_object(clazz, CHECK_NULL); obj = JNIHandles::make_local(env, i); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherArray ap(THREAD, methodID, args); + JNI_ArgumentPusherArray ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); return obj; JNI_END @@ -1212,7 +1210,7 @@ instanceOop i = alloc_object(clazz, CHECK_NULL); obj = JNIHandles::make_local(env, i); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); + JNI_ArgumentPusherVaArg ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); return obj; JNI_END @@ -1230,7 +1228,7 @@ va_list args; va_start(args, methodID); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); + JNI_ArgumentPusherVaArg ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); va_end(args); return obj; @@ -1271,16 +1269,13 @@ // The class should have been loaded (we have an instance of the class // passed in) so the method and signature should already be in the symbol // table. If they're not there, the method doesn't exist. - symbolHandle signature = - symbolHandle(THREAD, SymbolTable::probe(sig, (int)strlen(sig))); - symbolHandle name; - if (name_str == NULL) { - name = vmSymbolHandles::object_initializer_name(); - } else { - name = symbolHandle(THREAD, - SymbolTable::probe(name_str, (int)strlen(name_str))); - } - if (name.is_null() || signature.is_null()) { + const char *name_to_probe = (name_str == NULL) + ? vmSymbols::object_initializer_name()->as_C_string() + : name_str; + TempNewSymbol name = SymbolTable::probe(name_to_probe, (int)strlen(name_to_probe)); + TempNewSymbol signature = SymbolTable::probe(sig, (int)strlen(sig)); + + if (name == NULL || signature == NULL) { THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); } @@ -1298,20 +1293,20 @@ Klass::cast(klass())->initialize(CHECK_NULL); methodOop m; - if (name() == vmSymbols::object_initializer_name() || - name() == vmSymbols::class_initializer_name()) { + if (name == vmSymbols::object_initializer_name() || + name == vmSymbols::class_initializer_name()) { // Never search superclasses for constructors if (klass->oop_is_instance()) { - m = instanceKlass::cast(klass())->find_method(name(), signature()); + m = instanceKlass::cast(klass())->find_method(name, signature); } else { m = NULL; } } else { - m = klass->lookup_method(name(), signature()); + m = klass->lookup_method(name, signature); // Look up interfaces if (m == NULL && klass->oop_is_instance()) { - m = instanceKlass::cast(klass())->lookup_method_in_all_interfaces(name(), - signature()); + m = instanceKlass::cast(klass())->lookup_method_in_all_interfaces(name, + signature); } } if (m == NULL || (m->is_static() != is_static)) { @@ -1365,7 +1360,7 @@ va_list args; \ va_start(args, methodID); \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \ + JNI_ArgumentPusherVaArg ap(methodID, args); \ jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ va_end(args); \ ret = jvalue.get_##ResultType(); \ @@ -1383,7 +1378,7 @@ (const ResultType&)ret);\ \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \ + JNI_ArgumentPusherVaArg ap(methodID, args); \ jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ ret = jvalue.get_##ResultType(); \ return ret;\ @@ -1399,7 +1394,7 @@ (const ResultType&)ret);\ \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherArray ap(THREAD, methodID, args); \ + JNI_ArgumentPusherArray ap(methodID, args); \ jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \ ret = jvalue.get_##ResultType(); \ return ret;\ @@ -1429,7 +1424,7 @@ va_list args; va_start(args, methodID); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); + JNI_ArgumentPusherVaArg ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK); va_end(args); JNI_END @@ -1441,7 +1436,7 @@ DT_VOID_RETURN_MARK(CallVoidMethodV); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); + JNI_ArgumentPusherVaArg ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK); JNI_END @@ -1452,7 +1447,7 @@ DT_VOID_RETURN_MARK(CallVoidMethodA); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherArray ap(THREAD, methodID, args); + JNI_ArgumentPusherArray ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK); JNI_END @@ -1475,7 +1470,7 @@ va_list args; \ va_start(args, methodID); \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \ + JNI_ArgumentPusherVaArg ap(methodID, args); \ jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ va_end(args); \ ret = jvalue.get_##ResultType(); \ @@ -1491,7 +1486,7 @@ (const ResultType&)ret);\ \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \ + JNI_ArgumentPusherVaArg ap(methodID, args); \ jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ ret = jvalue.get_##ResultType(); \ return ret;\ @@ -1506,7 +1501,7 @@ (const ResultType&)ret);\ \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherArray ap(THREAD, methodID, args); \ + JNI_ArgumentPusherArray ap(methodID, args); \ jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \ ret = jvalue.get_##ResultType(); \ return ret;\ @@ -1539,7 +1534,7 @@ va_list args; va_start(args, methodID); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); + JNI_ArgumentPusherVaArg ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK); va_end(args); JNI_END @@ -1553,7 +1548,7 @@ DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); + JNI_ArgumentPusherVaArg ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK); JNI_END @@ -1564,7 +1559,7 @@ env, obj, cls, methodID); DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherArray ap(THREAD, methodID, args); + JNI_ArgumentPusherArray ap(methodID, args); jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK); JNI_END @@ -1587,7 +1582,7 @@ va_list args; \ va_start(args, methodID); \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \ + JNI_ArgumentPusherVaArg ap(methodID, args); \ jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ va_end(args); \ ret = jvalue.get_##ResultType(); \ @@ -1603,7 +1598,7 @@ (const ResultType&)ret);\ \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \ + JNI_ArgumentPusherVaArg ap(methodID, args); \ jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ ret = jvalue.get_##ResultType(); \ return ret;\ @@ -1618,7 +1613,7 @@ (const ResultType&)ret);\ \ JavaValue jvalue(Tag); \ - JNI_ArgumentPusherArray ap(THREAD, methodID, args); \ + JNI_ArgumentPusherArray ap(methodID, args); \ jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ ret = jvalue.get_##ResultType(); \ return ret;\ @@ -1649,7 +1644,7 @@ va_list args; va_start(args, methodID); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); + JNI_ArgumentPusherVaArg ap(methodID, args); jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK); va_end(args); JNI_END @@ -1661,7 +1656,7 @@ DT_VOID_RETURN_MARK(CallStaticVoidMethodV); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); + JNI_ArgumentPusherVaArg ap(methodID, args); jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK); JNI_END @@ -1672,7 +1667,7 @@ DT_VOID_RETURN_MARK(CallStaticVoidMethodA); JavaValue jvalue(T_VOID); - JNI_ArgumentPusherArray ap(THREAD, methodID, args); + JNI_ArgumentPusherArray ap(methodID, args); jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK); JNI_END @@ -1694,11 +1689,9 @@ // The class should have been loaded (we have an instance of the class // passed in) so the field and signature should already be in the symbol // table. If they're not there, the field doesn't exist. - symbolHandle fieldname = - symbolHandle(THREAD, SymbolTable::probe(name, (int)strlen(name))); - symbolHandle signame = - symbolHandle(THREAD, SymbolTable::probe(sig, (int)strlen(sig))); - if (fieldname.is_null() || signame.is_null()) { + TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name)); + TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig)); + if (fieldname == NULL || signame == NULL) { THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); } KlassHandle k(THREAD, @@ -1708,7 +1701,7 @@ fieldDescriptor fd; if (!Klass::cast(k())->oop_is_instance() || - !instanceKlass::cast(k())->find_field(fieldname(), signame(), false, &fd)) { + !instanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) { THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); } @@ -1893,11 +1886,9 @@ // The class should have been loaded (we have an instance of the class // passed in) so the field and signature should already be in the symbol // table. If they're not there, the field doesn't exist. - symbolHandle fieldname = - symbolHandle(THREAD, SymbolTable::probe(name, (int)strlen(name))); - symbolHandle signame = - symbolHandle(THREAD, SymbolTable::probe(sig, (int)strlen(sig))); - if (fieldname.is_null() || signame.is_null()) { + TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name)); + TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig)); + if (fieldname == NULL || signame == NULL) { THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); } KlassHandle k(THREAD, @@ -1907,7 +1898,7 @@ fieldDescriptor fd; if (!Klass::cast(k())->oop_is_instance() || - !instanceKlass::cast(k())->find_field(fieldname(), signame(), true, &fd)) { + !instanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) { THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); } @@ -2389,7 +2380,7 @@ // to see if the native method is now wrapped with the prefixes. See the // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details. static methodOop find_prefixed_native(KlassHandle k, - symbolHandle name, symbolHandle signature, TRAPS) { + Symbol* name, Symbol* signature, TRAPS) { ResourceMark rm(THREAD); methodOop method; int name_len = name->utf8_length(); @@ -2405,11 +2396,11 @@ char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1); strcpy(trial_name_str, prefix); strcat(trial_name_str, name_str); - symbolHandle trial_name(THREAD, SymbolTable::probe(trial_name_str, trial_len)); - if (trial_name.is_null()) { + TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len); + if (trial_name == NULL) { continue; // no such symbol, so this prefix wasn't used, try the next prefix } - method = Klass::cast(k())->lookup_method(trial_name(), signature()); + method = Klass::cast(k())->lookup_method(trial_name, signature); if (method == NULL) { continue; // signature doesn't match, try the next prefix } @@ -2424,13 +2415,13 @@ return NULL; // not found } -static bool register_native(KlassHandle k, symbolHandle name, symbolHandle signature, address entry, TRAPS) { - methodOop method = Klass::cast(k())->lookup_method(name(), signature()); +static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) { + methodOop method = Klass::cast(k())->lookup_method(name, signature); if (method == NULL) { ResourceMark rm; stringStream st; st.print("Method %s name or signature does not match", - methodOopDesc::name_and_sig_as_C_string(Klass::cast(k()), name(), signature())); + methodOopDesc::name_and_sig_as_C_string(Klass::cast(k()), name, signature)); THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); } if (!method->is_native()) { @@ -2440,7 +2431,7 @@ ResourceMark rm; stringStream st; st.print("Method %s is not declared as native", - methodOopDesc::name_and_sig_as_C_string(Klass::cast(k()), name(), signature())); + methodOopDesc::name_and_sig_as_C_string(Klass::cast(k()), name, signature)); THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); } } @@ -2480,10 +2471,10 @@ // The class should have been loaded (we have an instance of the class // passed in) so the method and signature should already be in the symbol // table. If they're not there, the method doesn't exist. - symbolHandle name(THREAD, SymbolTable::probe(meth_name, meth_name_len)); - symbolHandle signature(THREAD, SymbolTable::probe(meth_sig, (int)strlen(meth_sig))); - - if (name.is_null() || signature.is_null()) { + TempNewSymbol name = SymbolTable::probe(meth_name, meth_name_len); + TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig)); + + if (name == NULL || signature == NULL) { ResourceMark rm; stringStream st; st.print("Method %s.%s%s not found", Klass::cast(h_k())->external_name(), meth_name, meth_sig); @@ -2717,7 +2708,7 @@ Handle loader; // null (bootstrap) loader Handle protection_domain; // null protection domain - symbolHandle sym = oopFactory::new_symbol_handle(name, CHECK_NULL); + TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL); jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL); if (TraceClassResolution && result != NULL) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jniCheck.cpp --- a/src/share/vm/prims/jniCheck.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jniCheck.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -27,7 +27,7 @@ #include "classfile/vmSymbols.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jni.h" #include "prims/jniCheck.hpp" #include "prims/jvm_misc.hpp" diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvm.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,9 +124,9 @@ vframeStream vfst(jthread); // scan up the stack skipping ClassLoader, AccessController and PrivilegedAction frames - symbolHandle access_controller = oopFactory::new_symbol_handle("java/security/AccessController", CHECK); + TempNewSymbol access_controller = SymbolTable::new_symbol("java/security/AccessController", CHECK); klassOop access_controller_klass = SystemDictionary::resolve_or_fail(access_controller, false, CHECK); - symbolHandle privileged_action = oopFactory::new_symbol_handle("java/security/PrivilegedAction", CHECK); + TempNewSymbol privileged_action = SymbolTable::new_symbol("java/security/PrivilegedAction", CHECK); klassOop privileged_action_klass = SystemDictionary::resolve_or_fail(privileged_action, false, CHECK); methodOop last_caller = NULL; @@ -175,7 +175,7 @@ // show method name if it's a native method trace = vfst.method()->name_and_sig_as_C_string(); } - symbolOop s = instanceKlass::cast(caller)->source_file_name(); + Symbol* s = instanceKlass::cast(caller)->source_file_name(); if (s != NULL) { source_file = s->as_C_string(); } @@ -311,8 +311,8 @@ JavaCalls::call_virtual(&r, props, KlassHandle(THREAD, SystemDictionary::Properties_klass()), - vmSymbolHandles::put_name(), - vmSymbolHandles::object_object_object_signature(), + vmSymbols::put_name(), + vmSymbols::object_object_object_signature(), key_str, value_str, THREAD); @@ -716,13 +716,13 @@ JVMWrapper2("JVM_FindClassFromBootLoader %s", name); // Java libraries should ensure that name is never null... - if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) { + if (name == NULL || (int)strlen(name) > Symbol::max_length()) { // It's impossible to create this class; the name cannot fit // into the constant pool. return NULL; } - symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL); + TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL); klassOop k = SystemDictionary::resolve_or_null(h_name, CHECK_NULL); if (k == NULL) { return NULL; @@ -740,7 +740,7 @@ JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name, throwError ? "error" : "exception"); // Java libraries should ensure that name is never null... - if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) { + if (name == NULL || (int)strlen(name) > Symbol::max_length()) { // It's impossible to create this class; the name cannot fit // into the constant pool. if (throwError) { @@ -749,7 +749,7 @@ THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name); } } - symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL); + TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL); Handle h_loader(THREAD, JNIHandles::resolve(loader)); jclass result = find_class_from_class_loader(env, h_name, init, h_loader, Handle(), throwError, THREAD); @@ -764,12 +764,12 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jclass from)) JVMWrapper2("JVM_FindClassFromClass %s", name); - if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) { + if (name == NULL || (int)strlen(name) > Symbol::max_length()) { // It's impossible to create this class; the name cannot fit // into the constant pool. THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); } - symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL); + TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL); oop from_class_oop = JNIHandles::resolve(from); klassOop from_class = (from_class_oop == NULL) ? (klassOop)NULL @@ -838,15 +838,15 @@ // Since exceptions can be thrown, class initialization can take place // if name is NULL no check for class name in .class stream has to be made. - symbolHandle class_name; + TempNewSymbol class_name = NULL; if (name != NULL) { const int str_len = (int)strlen(name); - if (str_len > symbolOopDesc::max_length()) { + if (str_len > Symbol::max_length()) { // It's impossible to create this class; the name cannot fit // into the constant pool. THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); } - class_name = oopFactory::new_symbol_handle(name, str_len, CHECK_NULL); + class_name = SymbolTable::new_symbol(name, str_len, CHECK_NULL); } ResourceMark rm(THREAD); @@ -905,12 +905,12 @@ if (str == NULL) return NULL; const int str_len = (int)strlen(str); - if (str_len > symbolOopDesc::max_length()) { + if (str_len > Symbol::max_length()) { // It's impossible to create this class; the name cannot fit // into the constant pool. return NULL; } - symbolHandle klass_name = oopFactory::new_symbol_handle(str, str_len,CHECK_NULL); + TempNewSymbol klass_name = SymbolTable::new_symbol(str, str_len, CHECK_NULL); // Security Note: // The Java level wrapper will perform the necessary security check allowing @@ -1155,8 +1155,8 @@ !pending_exception->is_a(SystemDictionary::RuntimeException_klass())) { // Throw a java.security.PrivilegedActionException(Exception e) exception JavaCallArguments args(pending_exception); - THROW_ARG_0(vmSymbolHandles::java_security_PrivilegedActionException(), - vmSymbolHandles::exception_void_signature(), + THROW_ARG_0(vmSymbols::java_security_PrivilegedActionException(), + vmSymbols::exception_void_signature(), &args); } } @@ -1452,8 +1452,8 @@ if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve(cls)); if (Klass::cast(k)->oop_is_instance()) { - symbolHandle sym = symbolHandle(THREAD, instanceKlass::cast(k)->generic_signature()); - if (sym.is_null()) return NULL; + Symbol* sym = instanceKlass::cast(k)->generic_signature(); + if (sym == NULL) return NULL; Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL); return (jstring) JNIHandles::make_local(env, str()); } @@ -1842,8 +1842,8 @@ if (k_o == NULL) return NULL; } instanceKlassHandle k(THREAD, k_o); - symbolOop name = cp->uncached_name_ref_at(index); - symbolOop sig = cp->uncached_signature_ref_at(index); + Symbol* name = cp->uncached_name_ref_at(index); + Symbol* sig = cp->uncached_signature_ref_at(index); methodHandle m (THREAD, k->find_method(name, sig)); if (m.is_null()) { THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up method in target class"); @@ -1893,8 +1893,8 @@ if (k_o == NULL) return NULL; } instanceKlassHandle k(THREAD, k_o); - symbolOop name = cp->uncached_name_ref_at(index); - symbolOop sig = cp->uncached_signature_ref_at(index); + Symbol* name = cp->uncached_name_ref_at(index); + Symbol* sig = cp->uncached_signature_ref_at(index); fieldDescriptor fd; klassOop target_klass = k->find_field(name, sig, &fd); if (target_klass == NULL) { @@ -1937,9 +1937,9 @@ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); } int klass_ref = cp->uncached_klass_ref_index_at(index); - symbolHandle klass_name (THREAD, cp->klass_name_at(klass_ref)); - symbolHandle member_name(THREAD, cp->uncached_name_ref_at(index)); - symbolHandle member_sig (THREAD, cp->uncached_signature_ref_at(index)); + Symbol* klass_name = cp->klass_name_at(klass_ref); + Symbol* member_name = cp->uncached_name_ref_at(index); + Symbol* member_sig = cp->uncached_signature_ref_at(index); objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::String_klass(), 3, CHECK_NULL); objArrayHandle dest(THREAD, dest_o); Handle str = java_lang_String::create_from_symbol(klass_name, CHECK_NULL); @@ -2028,8 +2028,7 @@ if (!tag.is_symbol()) { THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); } - symbolOop sym_o = cp->symbol_at(index); - symbolHandle sym(THREAD, sym_o); + Symbol* sym = cp->symbol_at(index); Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL); return (jstring) JNIHandles::make_local(str()); } @@ -2356,7 +2355,7 @@ klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); constantPoolOop cp = instanceKlass::cast(k)->constants(); - symbolOop classname = cp->klass_name_at(cp_index); + Symbol* classname = cp->klass_name_at(cp_index); return classname->as_utf8(); JVM_END @@ -2369,7 +2368,7 @@ switch (cp->tag_at(cp_index).value()) { case JVM_CONSTANT_Fieldref: { int class_index = cp->uncached_klass_ref_index_at(cp_index); - symbolOop classname = cp->klass_name_at(class_index); + Symbol* classname = cp->klass_name_at(class_index); return classname->as_utf8(); } default: @@ -2389,7 +2388,7 @@ case JVM_CONSTANT_Methodref: case JVM_CONSTANT_InterfaceMethodref: { int class_index = cp->uncached_klass_ref_index_at(cp_index); - symbolOop classname = cp->klass_name_at(class_index); + Symbol* classname = cp->klass_name_at(class_index); return classname->as_utf8(); } default: @@ -2410,8 +2409,8 @@ constantPoolOop cp_called = instanceKlass::cast(k_called)->constants(); switch (cp->tag_at(cp_index).value()) { case JVM_CONSTANT_Fieldref: { - symbolOop name = cp->uncached_name_ref_at(cp_index); - symbolOop signature = cp->uncached_signature_ref_at(cp_index); + Symbol* name = cp->uncached_name_ref_at(cp_index); + Symbol* signature = cp->uncached_signature_ref_at(cp_index); typeArrayOop fields = instanceKlass::cast(k_called)->fields(); int fields_count = fields->length(); for (int i = 0; i < fields_count; i += instanceKlass::next_offset) { @@ -2440,8 +2439,8 @@ switch (cp->tag_at(cp_index).value()) { case JVM_CONSTANT_Methodref: case JVM_CONSTANT_InterfaceMethodref: { - symbolOop name = cp->uncached_name_ref_at(cp_index); - symbolOop signature = cp->uncached_signature_ref_at(cp_index); + Symbol* name = cp->uncached_name_ref_at(cp_index); + Symbol* signature = cp->uncached_signature_ref_at(cp_index); objArrayOop methods = instanceKlass::cast(k_called)->methods(); int methods_count = methods->length(); for (int i = 0; i < methods_count; i++) { @@ -2629,8 +2628,8 @@ JavaCalls::call_virtual(&result, obj, KlassHandle(THREAD, SystemDictionary::Thread_klass()), - vmSymbolHandles::run_method_name(), - vmSymbolHandles::void_method_signature(), + vmSymbols::run_method_name(), + vmSymbols::void_method_signature(), THREAD); } @@ -2651,12 +2650,18 @@ // we operate. MutexLocker mu(Threads_lock); - // Check to see if we're running a thread that's already exited or was - // stopped (is_stillborn) or is still active (thread is not NULL). - if (java_lang_Thread::is_stillborn(JNIHandles::resolve_non_null(jthread)) || - java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) { - throw_illegal_thread_state = true; + // Since JDK 5 the java.lang.Thread threadStatus is used to prevent + // re-starting an already started thread, so we should usually find + // that the JavaThread is null. However for a JNI attached thread + // there is a small window between the Thread object being created + // (with its JavaThread set) and the update to its threadStatus, so we + // have to check for this + if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) { + throw_illegal_thread_state = true; } else { + // We could also check the stillborn flag to see if this thread was already stopped, but + // for historical reasons we let the thread detect that itself when it starts running + jlong size = java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); // Allocate the C++ Thread structure and create the native thread. The @@ -2704,7 +2709,7 @@ // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints // before the quasi-asynchronous exception is delivered. This is a little obtrusive, // but is thought to be reliable and simple. In the case, where the receiver is the -// save thread as the sender, no safepoint is needed. +// same thread as the sender, no safepoint is needed. JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)) JVMWrapper("JVM_StopThread"); @@ -2715,26 +2720,27 @@ oop java_thread = JNIHandles::resolve_non_null(jthread); JavaThread* receiver = java_lang_Thread::thread(java_thread); Events::log("JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", receiver, (address)java_thread, throwable); - // First check if thread already exited + // First check if thread is alive if (receiver != NULL) { // Check if exception is getting thrown at self (use oop equality, since the // target object might exit) if (java_thread == thread->threadObj()) { - // This is a change from JDK 1.1, but JDK 1.2 will also do it: - // NOTE (from JDK 1.2): this is done solely to prevent stopped - // threads from being restarted. - // Fix for 4314342, 4145910, perhaps others: it now doesn't have - // any effect on the "liveness" of a thread; see - // JVM_IsThreadAlive, below. - if (java_throwable->is_a(SystemDictionary::ThreadDeath_klass())) { - java_lang_Thread::set_stillborn(java_thread); - } THROW_OOP(java_throwable); } else { // Enques a VM_Operation to stop all threads and then deliver the exception... Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable)); } } + else { + // Either: + // - target thread has not been started before being stopped, or + // - target thread already terminated + // We could read the threadStatus to determine which case it is + // but that is overkill as it doesn't matter. We must set the + // stillborn flag for the first case, and if the thread has already + // exited setting this flag has no affect + java_lang_Thread::set_stillborn(java_thread); + } JVM_END @@ -3106,9 +3112,8 @@ Handle class_name_str = java_lang_String::internalize_classname(h_name, CHECK_0); const char* str = java_lang_String::as_utf8_string(class_name_str()); - symbolHandle class_name_sym = - symbolHandle(THREAD, SymbolTable::probe(str, (int)strlen(str))); - if (class_name_sym.is_null()) { + TempNewSymbol class_name_sym = SymbolTable::probe(str, (int)strlen(str)); + if (class_name_sym == NULL) { return -1; } @@ -3118,7 +3123,7 @@ if (!vfst.method()->is_native()) { klassOop holder = vfst.method()->method_holder(); assert(holder->is_klass(), "just checking"); - if (instanceKlass::cast(holder)->name() == class_name_sym()) { + if (instanceKlass::cast(holder)->name() == class_name_sym) { return depth; } depth++; @@ -3317,13 +3322,13 @@ const char* str = java_lang_String::as_utf8_string(string()); - if (str == NULL || (int)strlen(str) > symbolOopDesc::max_length()) { + if (str == NULL || (int)strlen(str) > Symbol::max_length()) { // It's impossible to create this class; the name cannot fit // into the constant pool. THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), str); } - symbolHandle name = oopFactory::new_symbol_handle(str, CHECK_NULL); + TempNewSymbol name = SymbolTable::new_symbol(str, CHECK_NULL); Handle curr_klass (THREAD, JNIHandles::resolve(currClass)); // Find the most recent class on the stack with a non-null classloader oop loader = NULL; @@ -3966,7 +3971,7 @@ // Shared JNI/JVM entry points ////////////////////////////////////////////////////////////// -jclass find_class_from_class_loader(JNIEnv* env, symbolHandle name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) { +jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) { // Security Note: // The Java level wrapper will perform the necessary security check allowing // us to pass the NULL as the initiating class loader. @@ -4062,14 +4067,13 @@ Handle str (THREAD, JNIHandles::resolve_non_null(name)); const char* cstr = java_lang_String::as_utf8_string(str()); - symbolHandle field_name = - symbolHandle(THREAD, SymbolTable::probe(cstr, (int)strlen(cstr))); - if (field_name.is_null()) { + TempNewSymbol field_name = SymbolTable::probe(cstr, (int)strlen(cstr)); + if (field_name == NULL) { THROW_0(vmSymbols::java_lang_NoSuchFieldException()); } oop mirror = JNIHandles::resolve_non_null(cls); - oop result = Reflection::reflect_field(mirror, field_name(), which, CHECK_NULL); + oop result = Reflection::reflect_field(mirror, field_name, which, CHECK_NULL); if (result == NULL) { THROW_0(vmSymbols::java_lang_NoSuchFieldException()); } @@ -4086,9 +4090,8 @@ Handle str (THREAD, JNIHandles::resolve_non_null(name)); const char* cstr = java_lang_String::as_utf8_string(str()); - symbolHandle method_name = - symbolHandle(THREAD, SymbolTable::probe(cstr, (int)strlen(cstr))); - if (method_name.is_null()) { + TempNewSymbol method_name = SymbolTable::probe(cstr, (int)strlen(cstr)); + if (method_name == NULL) { THROW_0(vmSymbols::java_lang_NoSuchMethodException()); } @@ -4461,16 +4464,14 @@ dest->obj_at_put(0, Klass::cast(enc_k)->java_mirror()); int encl_method_method_idx = ik_h->enclosing_method_method_index(); if (encl_method_method_idx != 0) { - symbolOop sym_o = ik_h->constants()->symbol_at( + Symbol* sym = ik_h->constants()->symbol_at( extract_low_short_from_int( ik_h->constants()->name_and_type_at(encl_method_method_idx))); - symbolHandle sym(THREAD, sym_o); Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL); dest->obj_at_put(1, str()); - sym_o = ik_h->constants()->symbol_at( + sym = ik_h->constants()->symbol_at( extract_high_short_from_int( ik_h->constants()->name_and_type_at(encl_method_method_idx))); - sym = symbolHandle(THREAD, sym_o); str = java_lang_String::create_from_symbol(sym, CHECK_NULL); dest->obj_at_put(2, str()); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvm_misc.hpp --- a/src/share/vm/prims/jvm_misc.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvm_misc.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,7 +31,7 @@ // Useful entry points shared by JNI and JVM interface. // We do not allow real JNI or JVM entry point to call each other. -jclass find_class_from_class_loader(JNIEnv* env, symbolHandle name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS); +jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS); void trace_class_resolution(klassOop to_class); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiClassFileReconstituter.cpp --- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -461,11 +461,11 @@ // JVMSpec| attribute_info attributes[attributes_count]; void JvmtiClassFileReconstituter::write_class_attributes() { u2 inner_classes_length = inner_classes_attribute_length(); - symbolHandle generic_signature(thread(), ikh()->generic_signature()); + Symbol* generic_signature = ikh()->generic_signature(); typeArrayHandle anno(thread(), ikh()->class_annotations()); int attr_count = 0; - if (generic_signature() != NULL) { + if (generic_signature != NULL) { ++attr_count; } if (ikh()->source_file_name() != NULL) { @@ -483,8 +483,8 @@ write_u2(attr_count); - if (generic_signature() != NULL) { - write_signature_attribute(symbol_to_cpool_index(generic_signature())); + if (generic_signature != NULL) { + write_signature_attribute(symbol_to_cpool_index(generic_signature)); } if (ikh()->source_file_name() != NULL) { write_source_file_attribute(); @@ -609,8 +609,7 @@ } void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) { - unsigned int hash_ignored; - symbolOop sym = SymbolTable::lookup_only(name, (int)strlen(name), hash_ignored); + TempNewSymbol sym = SymbolTable::probe(name, (int)strlen(name)); assert(sym != NULL, "attribute name symbol not found"); u2 attr_name_index = symbol_to_cpool_index(sym); assert(attr_name_index != 0, "attribute name symbol not in constant pool"); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiClassFileReconstituter.hpp --- a/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -41,11 +41,11 @@ instanceKlassHandle ikh() { return _ikh; }; constantPoolHandle cpool() { return _cpool; }; - u2 symbol_to_cpool_index(symbolOop sym) { + u2 symbol_to_cpool_index(Symbol* sym) { return _symmap->symbol_to_value(sym); } - u2 class_symbol_to_cpool_index(symbolOop sym) { + u2 class_symbol_to_cpool_index(Symbol* sym) { return _classmap->symbol_to_value(sym); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiEnv.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -541,12 +541,12 @@ JavaCalls::call_special(&res, loader, loader_ik, - vmSymbolHandles::appendToClassPathForInstrumentation_name(), - vmSymbolHandles::appendToClassPathForInstrumentation_signature(), + vmSymbols::appendToClassPathForInstrumentation_name(), + vmSymbols::appendToClassPathForInstrumentation_signature(), path, THREAD); if (HAS_PENDING_EXCEPTION) { - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); + Symbol* ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); CLEAR_PENDING_EXCEPTION; if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) { @@ -2124,7 +2124,7 @@ if (generic_ptr != NULL) { *generic_ptr = NULL; if (!isPrimitive && Klass::cast(k)->oop_is_instance()) { - symbolOop soo = instanceKlass::cast(k)->generic_signature(); + Symbol* soo = instanceKlass::cast(k)->generic_signature(); if (soo != NULL) { const char *gen_sig = soo->as_C_string(); if (gen_sig != NULL) { @@ -2176,7 +2176,7 @@ return JVMTI_ERROR_ABSENT_INFORMATION; } - symbolOop sfnOop = instanceKlass::cast(k_klass)->source_file_name(); + Symbol* sfnOop = instanceKlass::cast(k_klass)->source_file_name(); NULL_CHECK(sfnOop, JVMTI_ERROR_ABSENT_INFORMATION); { JavaThread* current_thread = JavaThread::current(); @@ -2539,7 +2539,7 @@ if (!Klass::cast(k)->oop_is_instance()) { return JVMTI_ERROR_ABSENT_INFORMATION; } - symbolOop sdeOop = instanceKlass::cast(k)->source_debug_extension(); + Symbol* sdeOop = instanceKlass::cast(k)->source_debug_extension(); NULL_CHECK(sdeOop, JVMTI_ERROR_ABSENT_INFORMATION); { @@ -2619,7 +2619,7 @@ } if (generic_ptr != NULL) { *generic_ptr = NULL; - symbolOop soop = fdesc_ptr->generic_signature(); + Symbol* soop = fdesc_ptr->generic_signature(); if (soop != NULL) { const char* gen_sig = soop->as_C_string(); if (gen_sig != NULL) { @@ -2695,7 +2695,7 @@ if (generic_ptr != NULL) { *generic_ptr = NULL; - symbolOop soop = method_oop->generic_signature(); + Symbol* soop = method_oop->generic_signature(); if (soop != NULL) { const char* gen_sig = soop->as_C_string(); if (gen_sig != NULL) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiEnvBase.cpp --- a/src/share/vm/prims/jvmtiEnvBase.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1355,7 +1355,7 @@ } // Get information about method return type - symbolHandle signature(current_thread, jvf->method()->signature()); + Symbol* signature = jvf->method()->signature(); ResultTypeFinder rtf(signature); TosState fr_tos = as_TosState(rtf.type()); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiExport.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -268,9 +268,9 @@ jclass _class_being_redefined; public: - JvmtiClassFileLoadEventMark(JavaThread *thread, symbolHandle name, + JvmtiClassFileLoadEventMark(JavaThread *thread, Symbol* name, Handle class_loader, Handle prot_domain, KlassHandle *class_being_redefined) : JvmtiThreadEventMark(thread) { - _class_name = name() != NULL? name->as_utf8() : NULL; + _class_name = name != NULL? name->as_utf8() : NULL; _jloader = (jobject)to_jobject(class_loader()); _protection_domain = (jobject)to_jobject(prot_domain()); if (class_being_redefined == NULL) { @@ -506,7 +506,7 @@ class JvmtiClassFileLoadHookPoster : public StackObj { private: - symbolHandle _h_name; + Symbol* _h_name; Handle _class_loader; Handle _h_protection_domain; unsigned char ** _data_ptr; @@ -522,7 +522,7 @@ JvmtiClassLoadKind _load_kind; public: - inline JvmtiClassFileLoadHookPoster(symbolHandle h_name, Handle class_loader, + inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader, Handle h_protection_domain, unsigned char **data_ptr, unsigned char **end_ptr, unsigned char **cached_data_ptr, @@ -597,7 +597,7 @@ // EVT_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, // ("JVMTI [%s] class file load hook event sent %s data_ptr = %d, data_len = %d", // JvmtiTrace::safe_get_thread_name(_thread), -// _h_name.is_null() ? "NULL" : _h_name->as_utf8(), +// _h_name == NULL ? "NULL" : _h_name->as_utf8(), // _curr_data, _curr_len )); JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader, _h_protection_domain, @@ -655,7 +655,7 @@ bool JvmtiExport::_should_post_class_file_load_hook = false; // this entry is for class file load hook on class load, redefine and retransform -void JvmtiExport::post_class_file_load_hook(symbolHandle h_name, +void JvmtiExport::post_class_file_load_hook(Symbol* h_name, Handle class_loader, Handle h_protection_domain, unsigned char **data_ptr, diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiExport.hpp --- a/src/share/vm/prims/jvmtiExport.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiExport.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -306,7 +306,7 @@ static bool _should_post_class_file_load_hook; inline static void set_should_post_class_file_load_hook(bool on) { _should_post_class_file_load_hook = on; } inline static bool should_post_class_file_load_hook() { return _should_post_class_file_load_hook; } - static void post_class_file_load_hook(symbolHandle h_name, Handle class_loader, + static void post_class_file_load_hook(Symbol* h_name, Handle class_loader, Handle h_protection_domain, unsigned char **data_ptr, unsigned char **end_ptr, unsigned char **cached_data_ptr, diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiImpl.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -285,8 +285,8 @@ // not saved in the PreviousVersionInfo. Thread *thread = Thread::current(); instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); - symbolOop m_name = _method->name(); - symbolOop m_signature = _method->signature(); + Symbol* m_name = _method->name(); + Symbol* m_signature = _method->signature(); { ResourceMark rm(thread); @@ -628,22 +628,22 @@ ty_sign++; len -= 2; } - symbolHandle ty_sym = oopFactory::new_symbol_handle(ty_sign, len, thread); - if (klass->name() == ty_sym()) { + TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len, thread); + if (klass->name() == ty_sym) { return true; } // Compare primary supers int super_depth = klass->super_depth(); int idx; for (idx = 0; idx < super_depth; idx++) { - if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym()) { + if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym) { return true; } } // Compare secondary supers objArrayOop sec_supers = klass->secondary_supers(); for (idx = 0; idx < sec_supers->length(); idx++) { - if (Klass::cast((klassOop) sec_supers->obj_at(idx))->name() == ty_sym()) { + if (Klass::cast((klassOop) sec_supers->obj_at(idx))->name() == ty_sym) { return true; } } @@ -690,7 +690,7 @@ _result = JVMTI_ERROR_INVALID_SLOT; return false; // Incorrect slot index } - symbolOop sign_sym = method_oop->constants()->symbol_at(signature_idx); + Symbol* sign_sym = method_oop->constants()->symbol_at(signature_idx); const char* signature = (const char *) sign_sym->as_utf8(); BasicType slot_type = char2type(signature[0]); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -235,7 +235,7 @@ case JVM_CONSTANT_String: // fall through // These were indirect CP entries, but they have been changed into - // symbolOops so these entries can be directly appended. + // Symbol*s so these entries can be directly appended. case JVM_CONSTANT_UnresolvedClass: // fall through case JVM_CONSTANT_UnresolvedString: { @@ -575,12 +575,12 @@ // name and signature jshort name_index = k_old_fields->short_at(i + instanceKlass::name_index_offset); jshort sig_index = k_old_fields->short_at(i +instanceKlass::signature_index_offset); - symbolOop name_sym1 = the_class->constants()->symbol_at(name_index); - symbolOop sig_sym1 = the_class->constants()->symbol_at(sig_index); + Symbol* name_sym1 = the_class->constants()->symbol_at(name_index); + Symbol* sig_sym1 = the_class->constants()->symbol_at(sig_index); name_index = k_new_fields->short_at(i + instanceKlass::name_index_offset); sig_index = k_new_fields->short_at(i + instanceKlass::signature_index_offset); - symbolOop name_sym2 = scratch_class->constants()->symbol_at(name_index); - symbolOop sig_sym2 = scratch_class->constants()->symbol_at(sig_index); + Symbol* name_sym2 = scratch_class->constants()->symbol_at(name_index); + Symbol* sig_sym2 = scratch_class->constants()->symbol_at(sig_index); if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) { return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; } @@ -855,7 +855,7 @@ } klassOop the_class_oop = java_lang_Class::as_klassOop(mirror); instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop); - symbolHandle the_class_sym = symbolHandle(THREAD, the_class->name()); + Symbol* the_class_sym = the_class->name(); // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark RC_TRACE_WITH_THREAD(0x00000001, THREAD, @@ -886,7 +886,7 @@ instanceKlassHandle scratch_class (THREAD, k); if (HAS_PENDING_EXCEPTION) { - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); + Symbol* ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("parse_stream exception: '%s'", ex_name->as_C_string())); @@ -912,7 +912,7 @@ if (!the_class->is_linked()) { the_class->link_class(THREAD); if (HAS_PENDING_EXCEPTION) { - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); + Symbol* ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("link_class exception: '%s'", ex_name->as_C_string())); @@ -950,7 +950,7 @@ } if (HAS_PENDING_EXCEPTION) { - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); + Symbol* ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("verify_byte_codes exception: '%s'", ex_name->as_C_string())); @@ -976,7 +976,7 @@ } if (HAS_PENDING_EXCEPTION) { - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); + Symbol* ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("verify_byte_codes post merge-CP exception: '%s'", @@ -993,7 +993,7 @@ Rewriter::rewrite(scratch_class, THREAD); if (HAS_PENDING_EXCEPTION) { - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); + Symbol* ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); CLEAR_PENDING_EXCEPTION; if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { return JVMTI_ERROR_OUT_OF_MEMORY; @@ -2857,8 +2857,8 @@ // (2) with the prefix. // where 'prefix' is the prefix at that 'depth' (first prefix, second prefix,...) methodOop search_prefix_name_space(int depth, char* name_str, size_t name_len, - symbolOop signature) { - symbolOop name_symbol = SymbolTable::probe(name_str, (int)name_len); + Symbol* signature) { + TempNewSymbol name_symbol = SymbolTable::probe(name_str, (int)name_len); if (name_symbol != NULL) { methodOop method = Klass::cast(the_class())->lookup_method(name_symbol, signature); if (method != NULL) { @@ -2897,7 +2897,7 @@ // Return the method name with old prefixes stripped away. char* method_name_without_prefixes(methodOop method) { - symbolOop name = method->name(); + Symbol* name = method->name(); char* name_str = name->as_utf8(); // Old prefixing may be defunct, strip prefixes, if any. diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiRedefineClasses.hpp --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -223,8 +223,8 @@ // JVM_CONSTANT_UnresolvedClass and JVM_CONSTANT_UnresolvedString // entries. During this conversion process, the UTF8 values that are // indirectly referenced by the JVM_CONSTANT_ClassIndex and -// JVM_CONSTANT_StringIndex entries are changed into symbolOops and the -// entries are modified to refer to the symbolOops. This optimization +// JVM_CONSTANT_StringIndex entries are changed into Symbol*s and the +// entries are modified to refer to the Symbol*s. This optimization // eliminates one level of indirection for those two CP entry types and // gets the entries ready for verification. During class file parsing // it is also possible for JVM_CONSTANT_UnresolvedString entries to be diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/jvmtiTagMap.cpp --- a/src/share/vm/prims/jvmtiTagMap.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/jvmtiTagMap.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -2605,7 +2605,7 @@ } // some objects are ignored - in the case of simple - // roots it's mostly symbolOops that we are skipping + // roots it's mostly Symbol*s that we are skipping // here. if (!ServiceUtil::visible_oop(o)) { return; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/methodComparator.cpp --- a/src/share/vm/prims/methodComparator.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/methodComparator.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" #include "prims/methodComparator.hpp" #include "runtime/handles.inline.hpp" diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/methodHandleWalk.cpp --- a/src/share/vm/prims/methodHandleWalk.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/methodHandleWalk.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -120,6 +120,7 @@ if (cur_slot == arg_slot) return T_OBJECT; } + ResourceMark rm(THREAD); for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { BasicType bt = ss.type(); cur_slot -= type2size[bt]; @@ -961,9 +962,9 @@ m = vmIntrinsics::method_for(iid); } - klassOop klass = m->method_holder(); - symbolOop name = m->name(); - symbolOop signature = m->signature(); + klassOop klass = m->method_holder(); + Symbol* name = m->name(); + Symbol* signature = m->signature(); if (tailcall) { // Actually, in order to make these methods more recognizable, @@ -1141,7 +1142,7 @@ for (int i = 1; i < _constants.length(); i++) { ConstantValue* cv = _constants.at(i); switch (cv->tag()) { - case JVM_CONSTANT_Utf8: cpool->symbol_at_put( i, cv->symbol_oop() ); break; + case JVM_CONSTANT_Utf8: cpool->symbol_at_put( i, cv->symbol() ); break; case JVM_CONSTANT_Integer: cpool->int_at_put( i, cv->get_jint() ); break; case JVM_CONSTANT_Float: cpool->float_at_put( i, cv->get_jfloat() ); break; case JVM_CONSTANT_Long: cpool->long_at_put( i, cv->get_jlong() ); break; @@ -1331,7 +1332,7 @@ virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS) { - symbolOop name, sig; + Symbol* name, sig; if (m != NULL) { name = m->name(); sig = m->signature(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/methodHandleWalk.hpp --- a/src/share/vm/prims/methodHandleWalk.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/methodHandleWalk.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -258,16 +258,20 @@ int _tag; // Constant pool tag type. JavaValue _value; Handle _handle; + Symbol* _sym; public: // Constructor for oop types. ConstantValue(int tag, Handle con) : _tag(tag), _handle(con) { - assert(tag == JVM_CONSTANT_Utf8 || - tag == JVM_CONSTANT_Class || + assert(tag == JVM_CONSTANT_Class || tag == JVM_CONSTANT_String || tag == JVM_CONSTANT_Object, "must be oop type"); } + ConstantValue(int tag, Symbol* con) : _tag(tag), _sym(con) { + assert(tag == JVM_CONSTANT_Utf8, "must be symbol type"); + } + // Constructor for oop reference types. ConstantValue(int tag, int index) : _tag(tag) { assert(JVM_CONSTANT_Fieldref <= tag && tag <= JVM_CONSTANT_NameAndType, "must be ref type"); @@ -291,7 +295,7 @@ } int tag() const { return _tag; } - symbolOop symbol_oop() const { return (symbolOop) _handle(); } + Symbol* symbol() const { return _sym; } klassOop klass_oop() const { return (klassOop) _handle(); } oop object_oop() const { return _handle(); } int index() const { return _value.get_jint(); } @@ -336,6 +340,12 @@ return _constants.append(cv); } + int cpool_symbol_put(int tag, Symbol* con) { + if (con == NULL) return 0; + ConstantValue* cv = new ConstantValue(tag, con); + return _constants.append(cv); + } + int cpool_oop_reference_put(int tag, int first_index, int second_index) { if (first_index == 0 && second_index == 0) return 0; assert(first_index != 0 && second_index != 0, "no zero indexes"); @@ -365,8 +375,8 @@ int cpool_object_put(Handle obj) { return cpool_oop_put(JVM_CONSTANT_Object, obj); } - int cpool_symbol_put(symbolOop sym) { - return cpool_oop_put(JVM_CONSTANT_Utf8, sym); + int cpool_symbol_put(Symbol* sym) { + return cpool_symbol_put(JVM_CONSTANT_Utf8, sym); } int cpool_klass_put(klassOop klass) { return cpool_oop_put(JVM_CONSTANT_Class, klass); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/methodHandles.cpp --- a/src/share/vm/prims/methodHandles.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/methodHandles.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -278,7 +278,7 @@ assert(m->is_method(), ""); if (m->is_static()) { // check that signature begins '(L' or '([' (not '(I', '()', etc.) - symbolOop sig = m->signature(); + Symbol* sig = m->signature(); BasicType recv_bt = char2type(sig->byte_at(1)); // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')' assert(sig->byte_at(0) == '(', "must be method sig"); @@ -438,6 +438,25 @@ return m; } +// convert the external string or reflective type to an internal signature +Symbol* MethodHandles::convert_to_signature(oop type_str, + bool polymorphic, + TRAPS) { + if (java_dyn_MethodType::is_instance(type_str)) { + return java_dyn_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); + } else if (java_lang_Class::is_instance(type_str)) { + return java_lang_Class::as_signature(type_str, false, CHECK_NULL); + } else if (java_lang_String::is_instance(type_str)) { + if (polymorphic) { + return java_lang_String::as_symbol(type_str, CHECK_NULL); + } else { + return java_lang_String::as_symbol_or_null(type_str); + } + } else { + THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized type", NULL); + } +} + // An unresolved member name is a mere symbolic reference. // Resolving it plants a vmtarget/vmindex in it, // which refers dirctly to JVM internals. @@ -478,39 +497,24 @@ defc->link_class(CHECK); // convert the external string name to an internal symbol - symbolHandle name(THREAD, java_lang_String::as_symbol_or_null(name_str)); - if (name.is_null()) return; // no such name + TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str); + if (name == NULL) return; // no such name name_str = NULL; // safety Handle polymorphic_method_type; bool polymorphic_signature = false; if ((flags & ALL_KINDS) == IS_METHOD && (defc() == SystemDictionary::MethodHandle_klass() && - methodOopDesc::is_method_handle_invoke_name(name()))) + methodOopDesc::is_method_handle_invoke_name(name))) polymorphic_signature = true; // convert the external string or reflective type to an internal signature - symbolHandle type; { - symbolOop type_sym = NULL; - if (java_dyn_MethodType::is_instance(type_str)) { - type_sym = java_dyn_MethodType::as_signature(type_str, polymorphic_signature, CHECK); - if (polymorphic_signature) - polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly - } else if (java_lang_Class::is_instance(type_str)) { - type_sym = java_lang_Class::as_signature(type_str, false, CHECK); - } else if (java_lang_String::is_instance(type_str)) { - if (polymorphic_signature) { - type = java_lang_String::as_symbol(type_str, CHECK); - } else { - type_sym = java_lang_String::as_symbol_or_null(type_str); - } - } else { - THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized type"); - } - if (type_sym != NULL) - type = symbolHandle(THREAD, type_sym); + TempNewSymbol type = convert_to_signature(type_str, polymorphic_signature, CHECK); + if (java_dyn_MethodType::is_instance(type_str) && polymorphic_signature) { + polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly } - if (type.is_null()) return; // no such signature exists in the VM + + if (type == NULL) return; // no such signature exists in the VM type_str = NULL; // safety // Time to do the lookup. @@ -566,7 +570,7 @@ CallInfo result; { EXCEPTION_MARK; - if (name() == vmSymbols::object_initializer_name()) { + if (name == vmSymbols::object_initializer_name()) { LinkResolver::resolve_special_call(result, defc, name, type, KlassHandle(), false, THREAD); } else { @@ -594,7 +598,7 @@ { // This is taken from LinkResolver::resolve_field, sans access checks. fieldDescriptor fd; // find_field initializes fd if found - KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name(), type(), &fd)); + KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name, type, &fd)); // check if field exists; i.e., if a klass containing the field def has been selected if (sel_klass.is_null()) return; oop vmtarget = sel_klass->as_klassOop(); @@ -725,7 +729,7 @@ } int MethodHandles::find_MemberNames(klassOop k, - symbolOop name, symbolOop sig, + Symbol* name, Symbol* sig, int mflags, klassOop caller, int skip, objArrayOop results) { DEBUG_ONLY(No_Safepoint_Verifier nsv); @@ -782,8 +786,8 @@ if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { // watch out for these guys: - symbolOop init_name = vmSymbols::object_initializer_name(); - symbolOop clinit_name = vmSymbols::class_initializer_name(); + Symbol* init_name = vmSymbols::object_initializer_name(); + Symbol* clinit_name = vmSymbols::class_initializer_name(); if (name == clinit_name) clinit_name = NULL; // hack for exposing bool negate_name_test = false; // fix name so that it captures the intention of IS_CONSTRUCTOR @@ -807,7 +811,7 @@ } for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) { methodOop m = st.method(); - symbolOop m_name = m->name(); + Symbol* m_name = m->name(); if (m_name == clinit_name) continue; if (name != NULL && ((m_name != name) ^ negate_name_test)) @@ -928,7 +932,7 @@ // Must be on the boot class path: if (ik->class_loader() != NULL) return false; // Check the name. - symbolOop name = ik->name(); + Symbol* name = ik->name(); for (int i = 0; ; i++) { const char* test_name = always_null_names[i]; if (test_name == NULL) break; @@ -1026,6 +1030,7 @@ int pmax = ptypes->length(); int mnum = 0; // method argument const char* err = NULL; + ResourceMark rm(THREAD); for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { oop ptype_oop = NULL; if (ss.at_return_type()) { @@ -1061,15 +1066,14 @@ } KlassHandle pklass_handle(THREAD, pklass); pklass = NULL; // If we fail to resolve types at this point, we will throw an error. - symbolOop name_oop = ss.as_symbol(CHECK); - symbolHandle name(THREAD, name_oop); + Symbol* name = ss.as_symbol(CHECK); instanceKlass* mk = instanceKlass::cast(m->method_holder()); Handle loader(THREAD, mk->class_loader()); Handle domain(THREAD, mk->protection_domain()); mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); pklass = pklass_handle(); if (mklass == NULL && pklass != NULL && - Klass::cast(pklass)->name() == name() && + Klass::cast(pklass)->name() == name && m->is_method_handle_invoke()) { // Assume a match. We can't really decode the signature of MH.invoke*. continue; @@ -2288,7 +2292,8 @@ tty->print("creating MethodType form "); if (WizardMode || Verbose) { // Warning: this calls Java code on the MH! // call Object.toString() - symbolOop name = vmSymbols::toString_name(), sig = vmSymbols::void_string_signature(); + Symbol* name = vmSymbols::toString_name(); + Symbol* sig = vmSymbols::void_string_signature(); JavaCallArguments args(Handle(THREAD, JNIHandles::resolve_non_null(erased_jh))); JavaValue result(T_OBJECT); JavaCalls::call_virtual(&result, SystemDictionary::Object_klass(), name, sig, @@ -2452,7 +2457,8 @@ objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh); if (results == NULL || !results->is_objArray()) return -1; - symbolOop name = NULL, sig = NULL; + TempNewSymbol name = NULL; + TempNewSymbol sig = NULL; if (name_jh != NULL) { name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh)); if (name == NULL) return 0; // a match is not possible @@ -2611,10 +2617,10 @@ if (enable_MH) { KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); if (MHI_klass.not_null()) { - symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK); - symbolHandle raiseException_sig = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); + TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK); + TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) - ->find_method(raiseException_name(), raiseException_sig()); + ->find_method(raiseException_name, raiseException_sig); if (raiseException_method != NULL && raiseException_method->is_static()) { MethodHandles::set_raise_exception_method(raiseException_method); } else { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/methodHandles.hpp --- a/src/share/vm/prims/methodHandles.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/methodHandles.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -287,7 +287,7 @@ static void init_MemberName(oop mname_oop, oop target); // compute vmtarget/vmindex from target static void init_MemberName(oop mname_oop, methodOop m, bool do_dispatch = true); static void init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset); - static int find_MemberNames(klassOop k, symbolOop name, symbolOop sig, + static int find_MemberNames(klassOop k, Symbol* name, Symbol* sig, int mflags, klassOop caller, int skip, objArrayOop results); // bit values for suppress argument to expand_MemberName: @@ -466,6 +466,8 @@ Register temp_reg, Register temp2_reg, Register temp3_reg = noreg); static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN; + + static Symbol* convert_to_signature(oop type_str, bool polymorphic, TRAPS); }; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/nativeLookup.cpp --- a/src/share/vm/prims/nativeLookup.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/nativeLookup.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -32,7 +32,7 @@ #include "oops/instanceKlass.hpp" #include "oops/methodOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvm_misc.hpp" #include "prims/nativeLookup.hpp" #include "runtime/arguments.hpp" @@ -51,7 +51,7 @@ #endif -static void mangle_name_on(outputStream* st, symbolOop name, int begin, int end) { +static void mangle_name_on(outputStream* st, Symbol* name, int begin, int end) { char* bytes = (char*)name->bytes() + begin; char* end_bytes = (char*)name->bytes() + end; while (bytes < end_bytes) { @@ -70,7 +70,7 @@ } -static void mangle_name_on(outputStream* st, symbolOop name) { +static void mangle_name_on(outputStream* st, Symbol* name) { mangle_name_on(st, name, 0, name->utf8_length()); } @@ -91,7 +91,7 @@ char* NativeLookup::long_jni_name(methodHandle method) { // Signature ignore the wrapping parenteses and the trailing return type stringStream st; - symbolOop signature = method->signature(); + Symbol* signature = method->signature(); st.print("__"); // find ')' int end; @@ -168,8 +168,8 @@ JavaValue result(T_LONG); JavaCalls::call_static(&result, klass, - vmSymbolHandles::findNative_name(), - vmSymbolHandles::classloader_string_long_signature(), + vmSymbols::findNative_name(), + vmSymbols::classloader_string_long_signature(), // Arguments loader, name_arg, @@ -249,10 +249,10 @@ if (wrapper_name != in_name) { // we have a name for a wrapping method int wrapper_name_len = (int)strlen(wrapper_name); - symbolHandle wrapper_symbol(THREAD, SymbolTable::probe(wrapper_name, wrapper_name_len)); - if (!wrapper_symbol.is_null()) { + TempNewSymbol wrapper_symbol = SymbolTable::probe(wrapper_name, wrapper_name_len); + if (wrapper_symbol != NULL) { KlassHandle kh(method->method_holder()); - methodOop wrapper_method = Klass::cast(kh())->lookup_method(wrapper_symbol(), + methodOop wrapper_method = Klass::cast(kh())->lookup_method(wrapper_symbol, method->signature()); if (wrapper_method != NULL && !wrapper_method->is_native()) { // we found a wrapper method, use its native entry @@ -301,9 +301,9 @@ address NativeLookup::base_library_lookup(const char* class_name, const char* method_name, const char* signature) { EXCEPTION_MARK; bool in_base_library = true; // SharedRuntime inits some math methods. - symbolHandle c_name = oopFactory::new_symbol_handle(class_name, CATCH); - symbolHandle m_name = oopFactory::new_symbol_handle(method_name, CATCH); - symbolHandle s_name = oopFactory::new_symbol_handle(signature, CATCH); + TempNewSymbol c_name = SymbolTable::new_symbol(class_name, CATCH); + TempNewSymbol m_name = SymbolTable::new_symbol(method_name, CATCH); + TempNewSymbol s_name = SymbolTable::new_symbol(signature, CATCH); // Find the class klassOop k = SystemDictionary::resolve_or_fail(c_name, true, CATCH); @@ -311,7 +311,7 @@ // Find method and invoke standard lookup methodHandle method (THREAD, - klass->uncached_lookup_method(m_name(), s_name())); + klass->uncached_lookup_method(m_name, s_name)); address result = lookup(method, in_base_library, CATCH); assert(in_base_library, "must be in basic library"); guarantee(result != NULL, "must be non NULL"); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/prims/unsafe.cpp --- a/src/share/vm/prims/unsafe.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/prims/unsafe.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -991,7 +991,7 @@ instanceKlassHandle anon_klass; { - symbolHandle no_class_name; + Symbol* no_class_name = NULL; klassOop anonk = SystemDictionary::parse_stream(no_class_name, host_loader, host_domain, &st, host_klass, cp_patches, diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/arguments.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -1941,10 +1941,16 @@ status = false; } +#ifndef SERIALGC if (UseG1GC) { status = status && verify_percentage(InitiatingHeapOccupancyPercent, "InitiatingHeapOccupancyPercent"); + status = status && verify_min_value(G1RefProcDrainInterval, 1, + "G1RefProcDrainInterval"); + status = status && verify_min_value((intx)G1ConcMarkStepDurationMillis, 1, + "G1ConcMarkStepDurationMillis"); } +#endif status = status && verify_interval(RefDiscoveryPolicy, ReferenceProcessor::DiscoveryPolicyMin, @@ -3029,15 +3035,6 @@ } ScavengeRootsInCode = 1; } -#ifdef COMPILER2 - if (EnableInvokeDynamic && DoEscapeAnalysis) { - // TODO: We need to find rules for invokedynamic and EA. For now, - // simply disable EA by default. - if (FLAG_IS_DEFAULT(DoEscapeAnalysis)) { - DoEscapeAnalysis = false; - } - } -#endif if (PrintGCDetails) { // Turn on -verbose:gc options as well diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/deoptimization.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -396,7 +396,7 @@ HandleMark hm; methodHandle method(thread, array->element(0)->method()); Bytecode_invoke invoke = Bytecode_invoke_check(method, array->element(0)->bci()); - return_type = invoke.is_valid() ? invoke.result_type(thread) : T_ILLEGAL; + return_type = invoke.is_valid() ? invoke.result_type() : T_ILLEGAL; } // Compute information for handling adapters and adjusting the frame size of the caller. @@ -601,7 +601,7 @@ cur_code == Bytecodes::_invokestatic || cur_code == Bytecodes::_invokeinterface) { Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci()); - symbolHandle signature(thread, invoke.signature()); + Symbol* signature = invoke.signature(); ArgumentSizeComputer asc(signature); cur_invoke_parameter_size = asc.size(); if (cur_code != Bytecodes::_invokestatic) { @@ -1156,7 +1156,7 @@ if (!constant_pool->tag_at(index).is_symbol()) return; Handle class_loader (THREAD, instanceKlass::cast(constant_pool->pool_holder())->class_loader()); - symbolHandle symbol (THREAD, constant_pool->symbol_at(index)); + Symbol* symbol = constant_pool->symbol_at(index); // class name? if (symbol->byte_at(0) != '(') { @@ -1166,10 +1166,10 @@ } // then it must be a signature! + ResourceMark rm(THREAD); for (SignatureStream ss(symbol); !ss.is_done(); ss.next()) { if (ss.is_object()) { - symbolOop s = ss.as_symbol(CHECK); - symbolHandle class_name (THREAD, s); + Symbol* class_name = ss.as_symbol(CHECK); Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK); } @@ -1246,19 +1246,17 @@ format_trap_request(buf, sizeof(buf), trap_request)); nm->log_identity(xtty); } - symbolHandle class_name; + Symbol* class_name = NULL; bool unresolved = false; if (unloaded_class_index >= 0) { constantPoolHandle constants (THREAD, trap_method->constants()); if (constants->tag_at(unloaded_class_index).is_unresolved_klass()) { - class_name = symbolHandle(THREAD, - constants->klass_name_at(unloaded_class_index)); + class_name = constants->klass_name_at(unloaded_class_index); unresolved = true; if (xtty != NULL) xtty->print(" unresolved='1'"); } else if (constants->tag_at(unloaded_class_index).is_symbol()) { - class_name = symbolHandle(THREAD, - constants->symbol_at(unloaded_class_index)); + class_name = constants->symbol_at(unloaded_class_index); } if (xtty != NULL) xtty->name(class_name); @@ -1294,7 +1292,7 @@ trap_reason_name(reason), trap_action_name(action), unloaded_class_index); - if (class_name.not_null()) { + if (class_name != NULL) { tty->print(unresolved ? " unresolved class: " : " symbol: "); class_name->print_symbol_on(tty); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/fieldDescriptor.hpp --- a/src/share/vm/runtime/fieldDescriptor.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/fieldDescriptor.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -28,7 +28,7 @@ #include "oops/constantPoolOop.hpp" #include "oops/klassOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/fieldType.hpp" #include "utilities/accessFlags.hpp" #include "utilities/constantTag.hpp" @@ -49,15 +49,15 @@ constantPoolHandle _cp; public: - symbolOop name() const { return _cp->symbol_at(_name_index); } - symbolOop signature() const { return _cp->symbol_at(_signature_index); } + Symbol* name() const { return _cp->symbol_at(_name_index); } + Symbol* signature() const { return _cp->symbol_at(_signature_index); } klassOop field_holder() const { return _cp->pool_holder(); } constantPoolOop constants() const { return _cp(); } AccessFlags access_flags() const { return _access_flags; } oop loader() const; // Offset (in words) of field from start of instanceOop / klassOop int offset() const { return _offset; } - symbolOop generic_signature() const { return (_generic_signature_index > 0 ? _cp->symbol_at(_generic_signature_index) : (symbolOop)NULL); } + Symbol* generic_signature() const { return (_generic_signature_index > 0 ? _cp->symbol_at(_generic_signature_index) : (Symbol*)NULL); } int index() const { return _index; } typeArrayOop annotations() const; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/fieldType.cpp --- a/src/share/vm/runtime/fieldType.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/fieldType.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -30,7 +30,7 @@ #include "runtime/fieldType.hpp" #include "runtime/signature.hpp" -void FieldType::skip_optional_size(symbolOop signature, int* index) { +void FieldType::skip_optional_size(Symbol* signature, int* index) { jchar c = signature->byte_at(*index); while (c >= '0' && c <= '9') { *index = *index + 1; @@ -38,12 +38,12 @@ } } -BasicType FieldType::basic_type(symbolOop signature) { +BasicType FieldType::basic_type(Symbol* signature) { return char2type(signature->byte_at(0)); } // Check if it is a valid array signature -bool FieldType::is_valid_array_signature(symbolOop sig) { +bool FieldType::is_valid_array_signature(Symbol* sig) { assert(sig->utf8_length() > 1, "this should already have been checked"); assert(sig->byte_at(0) == '[', "this should already have been checked"); // The first character is already checked @@ -73,7 +73,7 @@ } -BasicType FieldType::get_array_info(symbolOop signature, jint* dimension, symbolOop* object_key, TRAPS) { +BasicType FieldType::get_array_info(Symbol* signature, FieldArrayInfo& fd, TRAPS) { assert(basic_type(signature) == T_ARRAY, "must be array"); int index = 1; int dim = 1; @@ -84,14 +84,15 @@ skip_optional_size(signature, &index); } ResourceMark rm; - symbolOop element = oopFactory::new_symbol(signature->as_C_string() + index, CHECK_(T_BYTE)); - BasicType element_type = FieldType::basic_type(element); + char *element = signature->as_C_string() + index; + BasicType element_type = char2type(element[0]); if (element_type == T_OBJECT) { - char* object_type = element->as_C_string(); - object_type[element->utf8_length() - 1] = '\0'; - *object_key = oopFactory::new_symbol(object_type + 1, CHECK_(T_BYTE)); + int len = (int)strlen(element); + assert(element[len-1] == ';', "last char should be a semicolon"); + element[len-1] = '\0'; // chop off semicolon + fd._object_key = SymbolTable::new_symbol(element + 1, CHECK_(T_BYTE)); } // Pass dimension back to caller - *dimension = dim; + fd._dimension = dim; return element_type; } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/fieldType.hpp --- a/src/share/vm/runtime/fieldType.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/fieldType.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -26,26 +26,42 @@ #define SHARE_VM_RUNTIME_FIELDTYPE_HPP #include "memory/allocation.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" // Note: FieldType should be based on the SignatureIterator (or vice versa). // In any case, this structure should be re-thought at some point. // A FieldType is used to determine the type of a field from a signature string. +// Information returned by get_array_info, which is scoped to decrement +// reference count if a Symbol is created in the case of T_OBJECT +class FieldArrayInfo : public StackObj { + friend class FieldType; // field type can set these fields. + int _dimension; + Symbol* _object_key; + public: + int dimension() { return _dimension; } + Symbol* object_key() { return _object_key; } + // basic constructor + FieldArrayInfo() : _dimension(0), _object_key(NULL) {} + // destructor decrements object key's refcount if created + ~FieldArrayInfo() { if (_object_key != NULL) _object_key->decrement_refcount(); } +}; + + class FieldType: public AllStatic { private: - static void skip_optional_size(symbolOop signature, int* index); - static bool is_valid_array_signature(symbolOop signature); + static void skip_optional_size(Symbol* signature, int* index); + static bool is_valid_array_signature(Symbol* signature); public: // Return basic type - static BasicType basic_type(symbolOop signature); + static BasicType basic_type(Symbol* signature); // Testing - static bool is_array(symbolOop signature) { return signature->utf8_length() > 1 && signature->byte_at(0) == '[' && is_valid_array_signature(signature); } + static bool is_array(Symbol* signature) { return signature->utf8_length() > 1 && signature->byte_at(0) == '[' && is_valid_array_signature(signature); } - static bool is_obj(symbolOop signature) { + static bool is_obj(Symbol* signature) { int sig_length = signature->utf8_length(); // Must start with 'L' and end with ';' return (sig_length >= 2 && @@ -54,7 +70,7 @@ } // Parse field and extract array information. Works for T_ARRAY only. - static BasicType get_array_info(symbolOop signature, jint* dimension, symbolOop *object_key, TRAPS); + static BasicType get_array_info(Symbol* signature, FieldArrayInfo& ai, TRAPS); }; #endif // SHARE_VM_RUNTIME_FIELDTYPE_HPP diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/fprofiler.cpp --- a/src/share/vm/runtime/fprofiler.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/fprofiler.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,7 +31,7 @@ #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/deoptimization.hpp" #include "runtime/fprofiler.hpp" #include "runtime/mutexLocker.hpp" @@ -318,7 +318,7 @@ int limit; int i; methodOop m = method(); - symbolOop k = m->klass_name(); + Symbol* k = m->klass_name(); // Print the class name with dots instead of slashes limit = k->utf8_length(); for (i = 0 ; i < limit ; i += 1) { @@ -331,7 +331,7 @@ if (limit > 0) { st->print("."); } - symbolOop n = m->name(); + Symbol* n = m->name(); limit = n->utf8_length(); for (i = 0 ; i < limit ; i += 1) { char c = (char) n->byte_at(i); @@ -339,7 +339,7 @@ } if( Verbose ) { // Disambiguate overloaded methods - symbolOop sig = m->signature(); + Symbol* sig = m->signature(); sig->print_symbol_on(st); } } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/frame.cpp --- a/src/share/vm/runtime/frame.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/frame.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -792,7 +792,7 @@ } public: - InterpretedArgumentOopFinder(symbolHandle signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureInfo(signature), _has_receiver(has_receiver) { + InterpretedArgumentOopFinder(Symbol* signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureInfo(signature), _has_receiver(has_receiver) { // compute size of arguments int args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); assert(!fr->is_interpreted_frame() || @@ -846,7 +846,7 @@ } public: - EntryFrameOopFinder(frame* frame, symbolHandle signature, bool is_static) : SignatureInfo(signature) { + EntryFrameOopFinder(frame* frame, Symbol* signature, bool is_static) : SignatureInfo(signature) { _f = NULL; // will be set later _fr = frame; _is_static = is_static; @@ -861,7 +861,7 @@ }; -oop* frame::interpreter_callee_receiver_addr(symbolHandle signature) { +oop* frame::interpreter_callee_receiver_addr(Symbol* signature) { ArgumentSizeComputer asc(signature); int size = asc.size(); return (oop *)interpreter_frame_tos_at(size); @@ -922,7 +922,7 @@ int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); - symbolHandle signature; + Symbol* signature = NULL; bool has_receiver = false; // Process a callee's arguments if we are at a call site @@ -932,7 +932,7 @@ if (!m->is_native()) { Bytecode_invoke call = Bytecode_invoke_check(m, bci); if (call.is_valid()) { - signature = symbolHandle(thread, call.signature()); + signature = call.signature(); has_receiver = call.has_receiver(); if (map->include_argument_oops() && interpreter_frame_expression_stack_size() > 0) { @@ -965,7 +965,7 @@ } -void frame::oops_interpreted_arguments_do(symbolHandle signature, bool has_receiver, OopClosure* f) { +void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) { InterpretedArgumentOopFinder finder(signature, has_receiver, this, f); finder.oops_do(); } @@ -1014,7 +1014,7 @@ } public: - CompiledArgumentOopFinder(symbolHandle signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map) + CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map) : SignatureInfo(signature) { // initialize CompiledArgumentOopFinder @@ -1026,7 +1026,7 @@ _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); int arg_size; - _regs = SharedRuntime::find_callee_arguments(signature(), has_receiver, &arg_size); + _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, &arg_size); assert(arg_size == _arg_size, "wrong arg size"); } @@ -1039,7 +1039,7 @@ } }; -void frame::oops_compiled_arguments_do(symbolHandle signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) { +void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) { ResourceMark rm; CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map); finder.oops_do(); @@ -1099,8 +1099,7 @@ // must collect argument oops, as nobody else is doing it Thread *thread = Thread::current(); methodHandle m (thread, entry_frame_call_wrapper()->callee_method()); - symbolHandle signature (thread, m->signature()); - EntryFrameOopFinder finder(this, signature, m->is_static()); + EntryFrameOopFinder finder(this, m->signature(), m->is_static()); finder.arguments_do(f); } // Traverse the Handle Block saved in the entry frame diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/frame.hpp --- a/src/share/vm/runtime/frame.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/frame.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -261,10 +261,10 @@ // Find receiver for an invoke when arguments are just pushed on stack (i.e., callee stack-frame is // not setup) - oop interpreter_callee_receiver(symbolHandle signature) { return *interpreter_callee_receiver_addr(signature); } + oop interpreter_callee_receiver(Symbol* signature) { return *interpreter_callee_receiver_addr(signature); } - oop* interpreter_callee_receiver_addr(symbolHandle signature); + oop* interpreter_callee_receiver_addr(Symbol* signature); // expression stack (may go up or down, direction == 1 or -1) @@ -386,11 +386,11 @@ oop* oopmapreg_to_location(VMReg reg, const RegisterMap* regmap) const; // Oops-do's - void oops_compiled_arguments_do(symbolHandle signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f); + void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f); void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true); private: - void oops_interpreted_arguments_do(symbolHandle signature, bool has_receiver, OopClosure* f); + void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f); // Iteration of oops void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/globals.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -607,6 +607,9 @@ notproduct(bool, ZombieALot, false, \ "creates zombies (non-entrant) at exit from the runt. system") \ \ + product(bool, UnlinkSymbolsALot, false, \ + "unlink unreferenced symbols from the symbol table at safepoints")\ + \ notproduct(bool, WalkStackALot, false, \ "trace stack (no print) at every exit from the runtime system") \ \ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/handles.hpp --- a/src/share/vm/runtime/handles.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/handles.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -196,7 +196,6 @@ DEF_HANDLE(constantPoolCache, is_constantPoolCache) DEF_HANDLE(objArray , is_objArray ) DEF_HANDLE(typeArray , is_typeArray ) -DEF_HANDLE(symbol , is_symbol ) //------------------------------------------------------------------------------------------------------------------------ // Specific KlassHandles for different Klass types @@ -233,7 +232,6 @@ DEF_KLASS_HANDLE(arrayKlass , oop_is_array ) DEF_KLASS_HANDLE(typeArrayKlass , oop_is_typeArray_slow) DEF_KLASS_HANDLE(objArrayKlass , oop_is_objArray_slow ) -DEF_KLASS_HANDLE(symbolKlass , oop_is_symbol ) DEF_KLASS_HANDLE(constantPoolKlass , oop_is_constantPool ) DEF_KLASS_HANDLE(constantPoolCacheKlass, oop_is_constantPool ) diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/interfaceSupport.cpp --- a/src/share/vm/runtime/interfaceSupport.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/interfaceSupport.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -198,6 +198,11 @@ } } +void InterfaceSupport::unlinkSymbols() { + VM_UnlinkSymbols op; + VMThread::execute(&op); +} + void InterfaceSupport::deoptimizeAll() { if (is_init_completed() ) { if (DeoptimizeALot && deoptimizeAllCounter > DeoptimizeALotInterval) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/interfaceSupport.hpp --- a/src/share/vm/runtime/interfaceSupport.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/interfaceSupport.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -97,6 +97,7 @@ # endif static void zombieAll(); + static void unlinkSymbols(); static void deoptimizeAll(); static void stress_derived_pointers(); static void verify_stack(); @@ -375,6 +376,9 @@ if (ZombieALot) { InterfaceSupport::zombieAll(); } + if (UnlinkSymbolsALot) { + InterfaceSupport::unlinkSymbols(); + } // do verification AFTER potential deoptimization if (VerifyStack) { InterfaceSupport::verify_stack(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/java.cpp --- a/src/share/vm/runtime/java.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/java.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -41,7 +41,7 @@ #include "oops/methodOop.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/aprofiler.hpp" #include "runtime/arguments.hpp" @@ -615,7 +615,7 @@ vm_abort(false); } -void vm_exit_during_initialization(symbolHandle ex, const char* message) { +void vm_exit_during_initialization(Symbol* ex, const char* message) { ResourceMark rm; vm_notify_during_shutdown(ex->as_C_string(), message); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/java.hpp --- a/src/share/vm/runtime/java.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/java.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -49,7 +49,7 @@ // VM exit if error occurs during initialization of VM extern void vm_exit_during_initialization(Handle exception); -extern void vm_exit_during_initialization(symbolHandle exception_name, const char* message); +extern void vm_exit_during_initialization(Symbol* exception_name, const char* message); extern void vm_exit_during_initialization(const char* error, const char* message = NULL); extern void vm_shutdown_during_initialization(const char* error, const char* message = NULL); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/javaCalls.cpp --- a/src/share/vm/runtime/javaCalls.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/javaCalls.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -200,7 +200,7 @@ // ============ Virtual calls ============ -void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS) { +void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; Handle receiver = args->receiver(); KlassHandle recvrKlass(THREAD, receiver.is_null() ? (klassOop)NULL : receiver->klass()); @@ -215,13 +215,13 @@ } -void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, TRAPS) { +void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, TRAPS) { JavaCallArguments args(receiver); // One oop argument call_virtual(result, spec_klass, name, signature, &args, CHECK); } -void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS) { +void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) { JavaCallArguments args(receiver); // One oop argument args.push_oop(arg1); call_virtual(result, spec_klass, name, signature, &args, CHECK); @@ -229,7 +229,7 @@ -void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS) { +void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { JavaCallArguments args(receiver); // One oop argument args.push_oop(arg1); args.push_oop(arg2); @@ -239,7 +239,7 @@ // ============ Special calls ============ -void JavaCalls::call_special(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS) { +void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; LinkResolver::resolve_special_call(callinfo, klass, name, signature, KlassHandle(), false, CHECK); methodHandle method = callinfo.selected_method(); @@ -250,20 +250,20 @@ } -void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) { +void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { JavaCallArguments args(receiver); // One oop argument call_special(result, klass, name, signature, &args, CHECK); } -void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS) { +void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) { JavaCallArguments args(receiver); // One oop argument args.push_oop(arg1); call_special(result, klass, name, signature, &args, CHECK); } -void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS) { +void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { JavaCallArguments args(receiver); // One oop argument args.push_oop(arg1); args.push_oop(arg2); @@ -273,7 +273,7 @@ // ============ Static calls ============ -void JavaCalls::call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS) { +void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK); methodHandle method = callinfo.selected_method(); @@ -284,19 +284,19 @@ } -void JavaCalls::call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) { +void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { JavaCallArguments args; // No argument call_static(result, klass, name, signature, &args, CHECK); } -void JavaCalls::call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS) { +void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) { JavaCallArguments args(arg1); // One oop argument call_static(result, klass, name, signature, &args, CHECK); } -void JavaCalls::call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS) { +void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { JavaCallArguments args; // One oop argument args.push_oop(arg1); args.push_oop(arg2); @@ -459,7 +459,7 @@ public: bool _is_return; - SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { + SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { _is_oop = is_oop; _is_return = false; _return_type = return_type; @@ -550,7 +550,7 @@ if (return_type == T_ARRAY) return_type = T_OBJECT; // Check that oop information is correct - symbolHandle signature (thread, method->signature()); + Symbol* signature = method->signature(); SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); sc.iterate_parameters(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/javaCalls.hpp --- a/src/share/vm/runtime/javaCalls.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/javaCalls.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -189,29 +189,29 @@ // call_special // ------------ // The receiver must be first oop in argument list - static void call_special(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS); + static void call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS); - static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS); // No args - static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS); - static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS); + static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); // No args + static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS); + static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS); // virtual call // ------------ // The receiver must be first oop in argument list - static void call_virtual(JavaValue* result, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS); + static void call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS); - static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, TRAPS); // No args - static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS); - static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS); + static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, TRAPS); // No args + static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS); + static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS); // Static call // ----------- - static void call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS); + static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS); - static void call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS); - static void call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS); - static void call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS); + static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); + static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS); + static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS); // Low-level interface static void call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/objectMonitor.cpp --- a/src/share/vm/runtime/objectMonitor.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/objectMonitor.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -79,7 +79,7 @@ char* bytes = NULL; \ int len = 0; \ jlong jtid = SharedRuntime::get_java_tid(thread); \ - symbolOop klassname = ((oop)(klassOop))->klass()->klass_part()->name(); \ + Symbol* klassname = ((oop)(klassOop))->klass()->klass_part()->name(); \ if (klassname != NULL) { \ bytes = (char*)klassname->bytes(); \ len = klassname->utf8_length(); \ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/os.cpp --- a/src/share/vm/runtime/os.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/os.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -255,7 +255,7 @@ default: { // Dispatch the signal to java HandleMark hm(THREAD); - klassOop k = SystemDictionary::resolve_or_null(vmSymbolHandles::sun_misc_Signal(), THREAD); + klassOop k = SystemDictionary::resolve_or_null(vmSymbols::sun_misc_Signal(), THREAD); KlassHandle klass (THREAD, k); if (klass.not_null()) { JavaValue result(T_VOID); @@ -264,8 +264,8 @@ JavaCalls::call_static( &result, klass, - vmSymbolHandles::dispatch_name(), - vmSymbolHandles::int_void_signature(), + vmSymbols::dispatch_name(), + vmSymbols::int_void_signature(), &args, THREAD ); @@ -298,7 +298,7 @@ if (!ReduceSignalUsage) { // Setup JavaThread for processing signals EXCEPTION_MARK; - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(), true, CHECK); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); @@ -310,8 +310,8 @@ JavaValue result(T_VOID); JavaCalls::call_special(&result, thread_oop, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), thread_group, string, CHECK); @@ -320,8 +320,8 @@ JavaCalls::call_special(&result, thread_group, group, - vmSymbolHandles::add_method_name(), - vmSymbolHandles::thread_void_signature(), + vmSymbols::add_method_name(), + vmSymbols::thread_void_signature(), thread_oop, // ARG 1 CHECK); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/reflection.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -64,7 +64,7 @@ // this frame is a likely suspect caller = vfst.method()->method_holder(); line_number = vfst.method()->line_number_from_bci(vfst.bci()); - symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); + Symbol* s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); if (s != NULL) { source_file = s->as_C_string(); } @@ -622,7 +622,7 @@ ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, - vmSymbolHandles::java_lang_IncompatibleClassChangeError(), + vmSymbols::java_lang_IncompatibleClassChangeError(), "%s and %s disagree on InnerClasses attribute", outer->external_name(), inner->external_name() @@ -638,11 +638,11 @@ return java_lang_Class::primitive_mirror(ss->type()); case T_OBJECT: case T_ARRAY: - symbolOop name = ss->as_symbol(CHECK_NULL); + Symbol* name = ss->as_symbol(CHECK_NULL); oop loader = instanceKlass::cast(method->method_holder())->class_loader(); oop protection_domain = instanceKlass::cast(method->method_holder())->protection_domain(); klassOop k = SystemDictionary::resolve_or_fail( - symbolHandle(THREAD, name), + name, Handle(THREAD, loader), Handle(THREAD, protection_domain), true, CHECK_NULL); @@ -660,7 +660,8 @@ objArrayHandle mirrors (THREAD, m); int index = 0; // Collect parameter types - symbolHandle signature (THREAD, method->signature()); + ResourceMark rm(THREAD); + Symbol* signature = method->signature(); SignatureStream ss(signature); while (!ss.at_return_type()) { oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); @@ -681,9 +682,9 @@ } -Handle Reflection::new_type(symbolHandle signature, KlassHandle k, TRAPS) { +Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) { // Basic types - BasicType type = vmSymbols::signature_type(signature()); + BasicType type = vmSymbols::signature_type(signature); if (type != T_OBJECT) { return Handle(THREAD, Universe::java_mirror(type)); } @@ -714,7 +715,7 @@ instanceKlassHandle holder (THREAD, method->method_holder()); int slot = method->method_idnum(); - symbolHandle signature (THREAD, method->signature()); + Symbol* signature = method->signature(); int parameter_count = ArgumentCount(signature).size(); oop return_type_oop = NULL; objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL); @@ -726,16 +727,16 @@ if (exception_types.is_null()) return NULL; - symbolHandle method_name(THREAD, method->name()); + Symbol* method_name = method->name(); Handle name; if (intern_name) { // intern_name is only true with UseNewReflection - oop name_oop = StringTable::intern(method_name(), CHECK_NULL); + oop name_oop = StringTable::intern(method_name, CHECK_NULL); name = Handle(THREAD, name_oop); } else { name = java_lang_String::create_from_symbol(method_name, CHECK_NULL); } - if (name.is_null()) return NULL; + if (name == NULL) return NULL; int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; @@ -751,7 +752,7 @@ java_lang_reflect_Method::set_override(mh(), false); if (java_lang_reflect_Method::has_signature_field() && method->generic_signature() != NULL) { - symbolHandle gs(THREAD, method->generic_signature()); + Symbol* gs = method->generic_signature(); Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); java_lang_reflect_Method::set_signature(mh(), sig()); } @@ -774,7 +775,7 @@ instanceKlassHandle holder (THREAD, method->method_holder()); int slot = method->method_idnum(); - symbolHandle signature (THREAD, method->signature()); + Symbol* signature = method->signature(); int parameter_count = ArgumentCount(signature).size(); objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL); if (parameter_types.is_null()) return NULL; @@ -794,7 +795,7 @@ java_lang_reflect_Constructor::set_override(ch(), false); if (java_lang_reflect_Constructor::has_signature_field() && method->generic_signature() != NULL) { - symbolHandle gs(THREAD, method->generic_signature()); + Symbol* gs = method->generic_signature(); Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); java_lang_reflect_Constructor::set_signature(ch(), sig()); } @@ -809,16 +810,16 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { - symbolHandle field_name(THREAD, fd->name()); + Symbol* field_name = fd->name(); Handle name; if (intern_name) { // intern_name is only true with UseNewReflection - oop name_oop = StringTable::intern(field_name(), CHECK_NULL); + oop name_oop = StringTable::intern(field_name, CHECK_NULL); name = Handle(THREAD, name_oop); } else { name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); } - symbolHandle signature (THREAD, fd->signature()); + Symbol* signature = fd->signature(); KlassHandle holder (THREAD, fd->field_holder()); Handle type = new_type(signature, holder, CHECK_NULL); Handle rh = java_lang_reflect_Field::create(CHECK_NULL); @@ -832,7 +833,7 @@ java_lang_reflect_Field::set_override(rh(), false); if (java_lang_reflect_Field::has_signature_field() && fd->generic_signature() != NULL) { - symbolHandle gs(THREAD, fd->generic_signature()); + Symbol* gs = fd->generic_signature(); Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); java_lang_reflect_Field::set_signature(rh(), sig()); } @@ -858,8 +859,8 @@ assert(!method.is_null() , "method should not be null"); CallInfo info; - symbolHandle signature (THREAD, method->signature()); - symbolHandle name (THREAD, method->name()); + Symbol* signature = method->signature(); + Symbol* name = method->name(); LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass, name, signature, KlassHandle(), false, true, @@ -912,8 +913,8 @@ oop resolution_exception = PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION; JavaCallArguments args(Handle(THREAD, resolution_exception)); - THROW_ARG_0(vmSymbolHandles::java_lang_reflect_InvocationTargetException(), - vmSymbolHandles::throwable_void_signature(), + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), &args); } } else { @@ -941,8 +942,8 @@ method->name(), method->signature())); JavaCallArguments args(h_origexception); - THROW_ARG_0(vmSymbolHandles::java_lang_reflect_InvocationTargetException(), - vmSymbolHandles::throwable_void_signature(), + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), &args); } else { ResourceMark rm(THREAD); @@ -1043,8 +1044,8 @@ oop target_exception = PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION; JavaCallArguments args(Handle(THREAD, target_exception)); - THROW_ARG_0(vmSymbolHandles::java_lang_reflect_InvocationTargetException(), - vmSymbolHandles::throwable_void_signature(), + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), &args); } else { if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) @@ -1097,9 +1098,9 @@ oop Reflection::new_field(FieldStream* st, TRAPS) { - symbolHandle field_name(THREAD, st->name()); + Symbol* field_name = st->name(); Handle name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); - symbolHandle signature(THREAD, st->signature()); + Symbol* signature = st->signature(); Handle type = new_type(signature, st->klass(), CHECK_NULL); Handle rh = java_lang_reflect_Field::create(CHECK_NULL); oop result = rh(); @@ -1242,7 +1243,7 @@ case T_ARRAY: { Handle obj(THREAD, (oop) value->l); if (obj.not_null()) { - symbolHandle signature(THREAD, fd->signature()); + Symbol* signature = fd->signature(); Handle loader (THREAD, fd->loader()); Handle protect (THREAD, Klass::cast(fd->field_holder())->protection_domain()); klassOop k = SystemDictionary::resolve_or_fail(signature, loader, protect, true, CHECK); // may block @@ -1259,7 +1260,7 @@ } -oop Reflection::reflect_field(oop mirror, symbolOop field_name, jint which, TRAPS) { +oop Reflection::reflect_field(oop mirror, Symbol* field_name, jint which, TRAPS) { // Exclude primitive types and array types if (java_lang_Class::is_primitive(mirror)) return NULL; if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) return NULL; @@ -1287,7 +1288,7 @@ // Exclude primitive types and array types if (java_lang_Class::is_primitive(mirror) || Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) { - symbolHandle name = vmSymbolHandles::java_lang_reflect_Field(); + Symbol* name = vmSymbols::java_lang_reflect_Field(); klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL); return oopFactory::new_objArray(klass, 0, CHECK_NULL); // Return empty array } @@ -1308,7 +1309,7 @@ } // Allocate result - symbolHandle name = vmSymbolHandles::java_lang_reflect_Field(); + Symbol* name = vmSymbols::java_lang_reflect_Field(); klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL); objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL); objArrayHandle result (THREAD, r); @@ -1327,7 +1328,7 @@ } -oop Reflection::reflect_method(oop mirror, symbolHandle method_name, objArrayHandle types, jint which, TRAPS) { +oop Reflection::reflect_method(oop mirror, Symbol* method_name, objArrayHandle types, jint which, TRAPS) { if (java_lang_Class::is_primitive(mirror)) return NULL; klassOop klass = java_lang_Class::as_klassOop(mirror); if (Klass::cast(klass)->oop_is_array() && which == MEMBER_DECLARED) return NULL; @@ -1351,8 +1352,8 @@ for (MethodStream st(h_k, false, false); !st.eos(); st.next()) { methodHandle m(THREAD, st.method()); // For interfaces include static initializers since classic does that! - if (method_name() == m->name() && (include_clinit || (m->is_public() && !m->is_static() && !m->is_initializer()))) { - symbolHandle signature(THREAD, m->signature()); + if (method_name == m->name() && (include_clinit || (m->is_public() && !m->is_static() && !m->is_initializer()))) { + Symbol* signature = m->signature(); bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL); if (parameter_match) { return new_method(m, false, false, THREAD); @@ -1364,8 +1365,8 @@ { for (MethodStream st(h_k, false, false); !st.eos(); st.next()) { methodHandle m(THREAD, st.method()); - if (method_name() == m->name() && m->is_public() && m->is_static() && !m->is_initializer()) { - symbolHandle signature(THREAD, m->signature()); + if (method_name == m->name() && m->is_public() && m->is_static() && !m->is_initializer()) { + Symbol* signature = m->signature(); bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL); if (parameter_match) { return new_method(m, false, false, THREAD); @@ -1379,8 +1380,8 @@ { for (MethodStream st(h_k, true, true); !st.eos(); st.next()) { methodHandle m(THREAD, st.method()); - if (method_name() == m->name() && !m->is_initializer()) { - symbolHandle signature(THREAD, m->signature()); + if (method_name == m->name() && !m->is_initializer()) { + Symbol* signature = m->signature(); bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL); if (parameter_match) { return new_method(m, false, false, THREAD); @@ -1531,7 +1532,7 @@ for (MethodStream st(h_k, true, true); !st.eos(); st.next()) { methodHandle m(THREAD, st.method()); if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) { - symbolHandle signature(THREAD, m->signature()); + Symbol* signature = m->signature(); bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL); if (parameter_match) { return new_constructor(m, THREAD); @@ -1569,7 +1570,7 @@ } // Allocate result - symbolHandle name = vmSymbolHandles::java_lang_reflect_Constructor(); + Symbol* name = vmSymbols::java_lang_reflect_Constructor(); klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL); objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL); objArrayHandle h_result (THREAD, r); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/reflection.hpp --- a/src/share/vm/runtime/reflection.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/reflection.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -55,7 +55,7 @@ static objArrayHandle get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS); static objArrayHandle get_exception_types(methodHandle method, TRAPS); // Creating new java.lang.reflect.xxx wrappers - static Handle new_type(symbolHandle signature, KlassHandle k, TRAPS); + static Handle new_type(Symbol* signature, KlassHandle k, TRAPS); public: // Constants defined by java reflection api classes @@ -157,11 +157,11 @@ static void field_set(jvalue* value, fieldDescriptor* fd, Handle receiver, BasicType value_type, TRAPS); // Reflective lookup of fields. Returns java.lang.reflect.Field instances. - static oop reflect_field(oop mirror, symbolOop field_name, jint which, TRAPS); + static oop reflect_field(oop mirror, Symbol* field_name, jint which, TRAPS); static objArrayOop reflect_fields(oop mirror, jint which, TRAPS); // Reflective lookup of methods. Returns java.lang.reflect.Method instances. - static oop reflect_method(oop mirror, symbolHandle method_name, objArrayHandle types, jint which, TRAPS); + static oop reflect_method(oop mirror, Symbol* method_name, objArrayHandle types, jint which, TRAPS); static objArrayOop reflect_methods(oop mirror, jint which, TRAPS); // Reflective lookup of constructors. Returns java.lang.reflect.Constructor instances. diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/reflectionUtils.hpp --- a/src/share/vm/runtime/reflectionUtils.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/reflectionUtils.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -100,7 +100,7 @@ // Usage: // // for (FieldStream st(k, false, false); !st.eos(); st.next()) { -// symbolOop field_name = st.name(); +// Symbol* field_name = st.name(); // ... // } @@ -126,11 +126,11 @@ flags.set_flags(fields()->ushort_at(index() + instanceKlass::access_flags_offset)); return flags; } - symbolOop name() const { + Symbol* name() const { int name_index = fields()->ushort_at(index() + instanceKlass::name_index_offset); return constants()->symbol_at(name_index); } - symbolOop signature() const { + Symbol* signature() const { int signature_index = fields()->ushort_at(index() + instanceKlass::signature_index_offset); return constants()->symbol_at(signature_index); @@ -197,7 +197,7 @@ // Usage: // // for (FilteredFieldStream st(k, false, false); !st.eos(); st.next()) { -// symbolOop field_name = st.name(); +// Symbol* field_name = st.name(); // ... // } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/rframe.cpp --- a/src/share/vm/runtime/rframe.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/rframe.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "interpreter/interpreter.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/frame.inline.hpp" #include "runtime/rframe.hpp" #include "runtime/vframe.hpp" diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/safepoint.cpp --- a/src/share/vm/runtime/safepoint.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/safepoint.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -34,7 +34,7 @@ #include "memory/resourceArea.hpp" #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -527,7 +527,7 @@ } -oop SharedRuntime::retrieve_receiver( symbolHandle sig, frame caller ) { +oop SharedRuntime::retrieve_receiver( Symbol* sig, frame caller ) { assert(caller.is_interpreted_frame(), ""); int args_size = ArgumentSizeComputer(sig).size() + 1; assert(args_size <= caller.interpreter_frame_expression_stack_size(), "receiver must be on interpreter stack"); @@ -547,7 +547,7 @@ Exceptions::_throw(thread, __FILE__, __LINE__, h_exception); } -void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, symbolOop name, const char *message) { +void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, Symbol* name, const char *message) { Handle h_exception = Exceptions::new_exception(thread, name, message); throw_and_post_jvmti_exception(thread, h_exception); } @@ -880,7 +880,7 @@ assert(DTraceAllocProbes, "wrong call"); Klass* klass = o->blueprint(); int size = o->size(); - symbolOop name = klass->name(); + Symbol* name = klass->name(); HS_DTRACE_PROBE4(hotspot, object__alloc, get_java_tid(thread), name->bytes(), name->utf8_length(), size * HeapWordSize); return 0; @@ -889,9 +889,9 @@ JRT_LEAF(int, SharedRuntime::dtrace_method_entry( JavaThread* thread, methodOopDesc* method)) assert(DTraceMethodProbes, "wrong call"); - symbolOop kname = method->klass_name(); - symbolOop name = method->name(); - symbolOop sig = method->signature(); + Symbol* kname = method->klass_name(); + Symbol* name = method->name(); + Symbol* sig = method->signature(); HS_DTRACE_PROBE7(hotspot, method__entry, get_java_tid(thread), kname->bytes(), kname->utf8_length(), name->bytes(), name->utf8_length(), @@ -902,9 +902,9 @@ JRT_LEAF(int, SharedRuntime::dtrace_method_exit( JavaThread* thread, methodOopDesc* method)) assert(DTraceMethodProbes, "wrong call"); - symbolOop kname = method->klass_name(); - symbolOop name = method->name(); - symbolOop sig = method->signature(); + Symbol* kname = method->klass_name(); + Symbol* name = method->name(); + Symbol* sig = method->signature(); HS_DTRACE_PROBE7(hotspot, method__return, get_java_tid(thread), kname->bytes(), kname->utf8_length(), name->bytes(), name->utf8_length(), @@ -2637,7 +2637,7 @@ return regs.first(); } -VMRegPair *SharedRuntime::find_callee_arguments(symbolOop sig, bool has_receiver, int* arg_size) { +VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, int* arg_size) { // This method is returning a data structure allocating as a // ResourceObject, so do not put any ResourceMarks in here. char *s = sig->as_C_string(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/sharedRuntime.hpp --- a/src/share/vm/runtime/sharedRuntime.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/sharedRuntime.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -223,7 +223,7 @@ // Helper routine for full-speed JVMTI exception throwing support static void throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception); - static void throw_and_post_jvmti_exception(JavaThread *thread, symbolOop name, const char *message = NULL); + static void throw_and_post_jvmti_exception(JavaThread *thread, Symbol* name, const char *message = NULL); // RedefineClasses() tracing support for obsolete method entry static int rc_trace_method_entry(JavaThread* thread, methodOopDesc* m); @@ -237,7 +237,7 @@ // Used to back off a spin lock that is under heavy contention static void yield_all(JavaThread* thread, int attempts = 0); - static oop retrieve_receiver( symbolHandle sig, frame caller ); + static oop retrieve_receiver( Symbol* sig, frame caller ); static void register_finalizer(JavaThread* thread, oopDesc* obj); @@ -417,7 +417,7 @@ // Convert a sig into a calling convention register layout // and find interesting things about it. - static VMRegPair* find_callee_arguments(symbolOop sig, bool has_receiver, int *arg_size); + static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, int *arg_size); static VMReg name_for_receiver(); // "Top of Stack" slots that may be unused by the calling convention but must diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/signature.cpp --- a/src/share/vm/runtime/signature.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/signature.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -28,7 +28,7 @@ #include "memory/oopFactory.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" #include "runtime/signature.hpp" @@ -44,25 +44,11 @@ // ClassName = string. -SignatureIterator::SignatureIterator(symbolHandle signature) { - assert(signature->is_symbol(), "not a symbol"); +SignatureIterator::SignatureIterator(Symbol* signature) { _signature = signature; _parameter_index = 0; } -// Overloaded version called without handle -SignatureIterator::SignatureIterator(symbolOop signature) { - symbolHandle sh(Thread::current(), signature); - _signature = sh; - _parameter_index = 0; -} - -SignatureIterator::SignatureIterator(Thread *thread, symbolOop signature) { - symbolHandle sh(thread, signature); - _signature = sh; - _parameter_index = 0; -} - void SignatureIterator::expect(char c) { if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); _index++; @@ -70,7 +56,7 @@ void SignatureIterator::skip_optional_size() { - symbolOop sig = _signature(); + Symbol* sig = _signature; char c = sig->byte_at(_index); while ('0' <= c && c <= '9') c = sig->byte_at(++_index); } @@ -104,7 +90,7 @@ _index++; size = T_VOID_size; ; break; case 'L': { int begin = ++_index; - symbolOop sig = _signature(); + Symbol* sig = _signature; while (sig->byte_at(_index++) != ';') ; do_object(begin, _index); } @@ -114,7 +100,7 @@ case '[': { int begin = ++_index; skip_optional_size(); - symbolOop sig = _signature(); + Symbol* sig = _signature; while (sig->byte_at(_index) == '[') { _index++; skip_optional_size(); @@ -237,7 +223,7 @@ // Ignore parameters _index = 0; expect('('); - symbolOop sig = _signature(); + Symbol* sig = _signature; while (sig->byte_at(_index) != ')') _index++; expect(')'); // Parse return type @@ -264,9 +250,22 @@ // Implementation of SignatureStream +SignatureStream::SignatureStream(Symbol* signature, bool is_method) : + _signature(signature), _at_return_type(false) { + _begin = _end = (is_method ? 1 : 0); // skip first '(' in method signatures + _names = new GrowableArray(10); + next(); +} + +SignatureStream::~SignatureStream() { + // decrement refcount for names created during signature parsing + for (int i = 0; i < _names->length(); i++) { + _names->at(i)->decrement_refcount(); + } +} bool SignatureStream::is_done() const { - return _end > _signature()->utf8_length(); + return _end > _signature->utf8_length(); } @@ -274,13 +273,13 @@ switch (t) { case 'L': { _type = T_OBJECT; - symbolOop sig = _signature(); + Symbol* sig = _signature; while (sig->byte_at(_end++) != ';'); break; } case '[': { _type = T_ARRAY; - symbolOop sig = _signature(); + Symbol* sig = _signature; char c = sig->byte_at(_end); while ('0' <= c && c <= '9') c = sig->byte_at(_end++); while (sig->byte_at(_end) == '[') { @@ -319,25 +318,28 @@ return _type == T_ARRAY; } -symbolOop SignatureStream::as_symbol(TRAPS) { +Symbol* SignatureStream::as_symbol(TRAPS) { // Create a symbol from for string _begin _end int begin = _begin; int end = _end; - if ( _signature()->byte_at(_begin) == 'L' - && _signature()->byte_at(_end-1) == ';') { + if ( _signature->byte_at(_begin) == 'L' + && _signature->byte_at(_end-1) == ';') { begin++; end--; } - symbolOop result = oopFactory::new_symbol(_signature, begin, end, CHECK_NULL); - return result; + // Save names for cleaning up reference count at the end of + // SignatureStream scope. + Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL); + _names->push(name); // save new symbol for decrementing later + return name; } klassOop SignatureStream::as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS) { if (!is_object()) return NULL; - symbolOop name = as_symbol(CHECK_NULL); + Symbol* name = as_symbol(CHECK_NULL); if (failure_mode == ReturnNull) { return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); } else { @@ -355,28 +357,28 @@ return Klass::cast(klass)->java_mirror(); } -symbolOop SignatureStream::as_symbol_or_null() { +Symbol* SignatureStream::as_symbol_or_null() { // Create a symbol from for string _begin _end ResourceMark rm; int begin = _begin; int end = _end; - if ( _signature()->byte_at(_begin) == 'L' - && _signature()->byte_at(_end-1) == ';') { + if ( _signature->byte_at(_begin) == 'L' + && _signature->byte_at(_end-1) == ';') { begin++; end--; } char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); for (int index = begin; index < end; index++) { - buffer[index - begin] = _signature()->byte_at(index); + buffer[index - begin] = _signature->byte_at(index); } - symbolOop result = SymbolTable::probe(buffer, end - begin); + Symbol* result = SymbolTable::probe(buffer, end - begin); return result; } -bool SignatureVerifier::is_valid_signature(symbolHandle sig) { +bool SignatureVerifier::is_valid_signature(Symbol* sig) { const char* signature = (const char*)sig->bytes(); ssize_t len = sig->utf8_length(); if (signature == NULL || signature[0] == '\0' || len < 1) { @@ -388,7 +390,7 @@ } } -bool SignatureVerifier::is_valid_method_signature(symbolHandle sig) { +bool SignatureVerifier::is_valid_method_signature(Symbol* sig) { const char* method_sig = (const char*)sig->bytes(); ssize_t len = sig->utf8_length(); ssize_t index = 0; @@ -411,7 +413,7 @@ return false; } -bool SignatureVerifier::is_valid_type_signature(symbolHandle sig) { +bool SignatureVerifier::is_valid_type_signature(Symbol* sig) { const char* type_sig = (const char*)sig->bytes(); ssize_t len = sig->utf8_length(); return (type_sig != NULL && len >= 1 && diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/signature.hpp --- a/src/share/vm/runtime/signature.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/signature.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -47,7 +47,7 @@ class SignatureIterator: public ResourceObj { protected: - symbolHandle _signature; // the signature to iterate over + Symbol* _signature; // the signature to iterate over int _index; // the current character index (only valid during iteration) int _parameter_index; // the current parameter index (0 outside iteration phase) BasicType _return_type; @@ -87,9 +87,7 @@ }; // Constructors - SignatureIterator(symbolOop signature); - SignatureIterator(Thread *thread, symbolOop signature); - SignatureIterator(symbolHandle signature); + SignatureIterator(Symbol* signature); // Iteration void dispatch_field(); // dispatches once for field signatures @@ -138,7 +136,7 @@ void do_array (int begin, int end) { type_name("jobject" ); } public: - SignatureTypeNames(symbolHandle signature) : SignatureIterator(signature) {} + SignatureTypeNames(Symbol* signature) : SignatureIterator(signature) {} }; @@ -166,7 +164,7 @@ void do_array (int begin, int end) { set(T_ARRAY_size , T_ARRAY ); } public: - SignatureInfo(symbolHandle signature) : SignatureIterator(signature) { + SignatureInfo(Symbol* signature) : SignatureIterator(signature) { _has_iterated = _has_iterated_return = false; _size = 0; _return_type = T_ILLEGAL; @@ -181,7 +179,7 @@ private: void set(int size, BasicType type) { _size += size; } public: - ArgumentSizeComputer(symbolHandle signature) : SignatureInfo(signature) {} + ArgumentSizeComputer(Symbol* signature) : SignatureInfo(signature) {} int size() { lazy_iterate_parameters(); return _size; } }; @@ -191,7 +189,7 @@ private: void set(int size, BasicType type) { _size ++; } public: - ArgumentCount(symbolHandle signature) : SignatureInfo(signature) {} + ArgumentCount(Symbol* signature) : SignatureInfo(signature) {} int size() { lazy_iterate_parameters(); return _size; } }; @@ -205,7 +203,7 @@ public: BasicType type() { lazy_iterate_return(); return _return_type; } - ResultTypeFinder(symbolHandle signature) : SignatureInfo(signature) {} + ResultTypeFinder(Symbol* signature) : SignatureInfo(signature) {} }; @@ -238,11 +236,6 @@ _fingerprint = 0; } - Fingerprinter(Thread *thread, methodHandle method) : SignatureIterator(thread, method->signature()) { - mh = method; - _fingerprint = 0; - } - uint64_t fingerprint() { // See if we fingerprinted this method already if (mh->constMethod()->fingerprint() != CONST64(0)) { @@ -356,18 +349,19 @@ class SignatureStream : public StackObj { private: - symbolHandle _signature; + Symbol* _signature; int _begin; int _end; BasicType _type; bool _at_return_type; + GrowableArray* _names; // symbols created while parsing signature public: bool at_return_type() const { return _at_return_type; } bool is_done() const; void next_non_primitive(int t); void next() { - symbolOop sig = _signature(); + Symbol* sig = _signature; int len = sig->utf8_length(); if (_end >= len) { _end = len + 1; @@ -392,32 +386,28 @@ _end++; } - SignatureStream(symbolHandle signature, - bool is_method = true) : - _signature(signature), _at_return_type(false) { - _begin = _end = (is_method ? 1 : 0); // skip first '(' in method signatures - next(); - } + SignatureStream(Symbol* signature, bool is_method = true); + ~SignatureStream(); bool is_object() const; // True if this argument is an object bool is_array() const; // True if this argument is an array BasicType type() const { return _type; } - symbolOop as_symbol(TRAPS); + Symbol* as_symbol(TRAPS); enum FailureMode { ReturnNull, CNFException, NCDFError }; klassOop as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); // return same as_symbol except allocation of new symbols is avoided. - symbolOop as_symbol_or_null(); + Symbol* as_symbol_or_null(); }; class SignatureVerifier : public StackObj { public: // Returns true if the symbol is valid method or type signature - static bool is_valid_signature(symbolHandle sig); + static bool is_valid_signature(Symbol* sig); - static bool is_valid_method_signature(symbolHandle sig); - static bool is_valid_type_signature(symbolHandle sig); + static bool is_valid_method_signature(Symbol* sig); + static bool is_valid_type_signature(Symbol* sig); private: static ssize_t is_valid_type(const char*, ssize_t); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/statSampler.cpp --- a/src/share/vm/runtime/statSampler.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/statSampler.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -196,8 +196,8 @@ // public static String getProperty(String key, String def); JavaCalls::call_static(&result, KlassHandle(THREAD, SystemDictionary::System_klass()), - vmSymbolHandles::getProperty_name(), - vmSymbolHandles::string_string_signature(), + vmSymbols::getProperty_name(), + vmSymbols::string_string_signature(), key_str, CHECK_NULL); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/synchronizer.cpp --- a/src/share/vm/runtime/synchronizer.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/synchronizer.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -82,7 +82,7 @@ char* bytes = NULL; \ int len = 0; \ jlong jtid = SharedRuntime::get_java_tid(thread); \ - symbolOop klassname = ((oop)(klassOop))->klass()->klass_part()->name(); \ + Symbol* klassname = ((oop)(klassOop))->klass()->klass_part()->name(); \ if (klassname != NULL) { \ bytes = (char*)klassname->bytes(); \ len = klassname->utf8_length(); \ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/thread.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -37,7 +37,7 @@ #include "oops/instanceKlass.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" @@ -891,7 +891,7 @@ return os::create_main_thread((JavaThread*)this); } -static void initialize_class(symbolHandle class_name, TRAPS) { +static void initialize_class(Symbol* class_name, TRAPS) { klassOop klass = SystemDictionary::resolve_or_fail(class_name, true, CHECK); instanceKlass::cast(klass)->initialize(CHECK); } @@ -899,7 +899,7 @@ // Creates the initial ThreadGroup static Handle create_initial_thread_group(TRAPS) { - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_ThreadGroup(), true, CHECK_NH); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ThreadGroup(), true, CHECK_NH); instanceKlassHandle klass (THREAD, k); Handle system_instance = klass->allocate_instance_handle(CHECK_NH); @@ -908,8 +908,8 @@ JavaCalls::call_special(&result, system_instance, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::void_method_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::void_method_signature(), CHECK_NH); } Universe::set_system_thread_group(system_instance()); @@ -921,8 +921,8 @@ JavaCalls::call_special(&result, main_instance, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), system_instance, string, CHECK_NH); @@ -932,7 +932,7 @@ // Creates the initial Thread static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) { - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(), true, CHECK_NULL); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); @@ -945,8 +945,8 @@ JavaValue result(T_VOID); JavaCalls::call_special(&result, thread_oop, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), thread_group, string, CHECK_NULL); @@ -954,12 +954,12 @@ } static void call_initializeSystemClass(TRAPS) { - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_System(), true, CHECK); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); instanceKlassHandle klass (THREAD, k); JavaValue result(T_VOID); - JavaCalls::call_static(&result, klass, vmSymbolHandles::initializeSystemClass_name(), - vmSymbolHandles::void_method_signature(), CHECK); + JavaCalls::call_static(&result, klass, vmSymbols::initializeSystemClass_name(), + vmSymbols::void_method_signature(), CHECK); } #ifdef KERNEL @@ -973,8 +973,8 @@ } JavaValue result(T_VOID); - JavaCalls::call_static(&result, klass, vmSymbolHandles::setBootClassLoaderHook_name(), - vmSymbolHandles::void_method_signature(), CHECK); + JavaCalls::call_static(&result, klass, vmSymbols::setBootClassLoaderHook_name(), + vmSymbols::void_method_signature(), CHECK); } #endif // KERNEL @@ -985,8 +985,8 @@ instanceKlassHandle klass (THREAD, k); if (klass.not_null()) { JavaValue result(T_VOID); - JavaCalls::call_static(&result, klass, vmSymbolHandles::run_method_name(), - vmSymbolHandles::void_method_signature(), + JavaCalls::call_static(&result, klass, vmSymbols::run_method_name(), + vmSymbols::void_method_signature(), CHECK); } } @@ -997,7 +997,7 @@ const char *vm_info = VM_Version::vm_info_string(); // java.lang.System class - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_System(), true, CHECK); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); instanceKlassHandle klass (THREAD, k); // setProperty arguments @@ -1010,8 +1010,8 @@ // public static String setProperty(String key, String value); JavaCalls::call_static(&r, klass, - vmSymbolHandles::setProperty_name(), - vmSymbolHandles::string_string_string_signature(), + vmSymbols::setProperty_name(), + vmSymbols::string_string_string_signature(), key_str, value_str, CHECK); @@ -1022,7 +1022,7 @@ assert(thread_group.not_null(), "thread group should be specified"); assert(threadObj() == NULL, "should only create Java thread object once"); - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(), true, CHECK); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); @@ -1037,8 +1037,8 @@ JavaCalls::call_special(&result, thread_oop, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), thread_group, // Argument 1 name, // Argument 2 THREAD); @@ -1048,8 +1048,8 @@ JavaCalls::call_special(&result, thread_oop, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_runnable_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_runnable_void_signature(), thread_group, // Argument 1 Handle(), // Argument 2 THREAD); @@ -1070,8 +1070,8 @@ JavaCalls::call_special(&result, thread_group, group, - vmSymbolHandles::add_method_name(), - vmSymbolHandles::thread_void_signature(), + vmSymbols::add_method_name(), + vmSymbols::thread_void_signature(), threadObj, // Arg 1 THREAD); @@ -1510,11 +1510,11 @@ assert(JavaThread::current() == this, "sanity check"); assert(this->threadObj() != NULL, "just checking"); - // Execute thread entry point. If this thread is being asked to restart, - // or has been stopped before starting, do not reexecute entry point. + // Execute thread entry point unless this thread has a pending exception + // or has been stopped before starting. // Note: Due to JVM_StopThread we can have pending exceptions already! - if (!this->has_pending_exception() && !java_lang_Thread::is_stillborn(this->threadObj())) { - // enter the thread's entry point only if we have no pending exceptions + if (!this->has_pending_exception() && + !java_lang_Thread::is_stillborn(this->threadObj())) { HandleMark hm(this); this->entry_point()(this, this); } @@ -1533,13 +1533,10 @@ ObjectLocker lock(threadObj, thread); // Ignore pending exception (ThreadDeath), since we are exiting anyway thread->clear_pending_exception(); - // It is of profound importance that we set the stillborn bit and reset the thread object, - // before we do the notify. Since, changing these two variable will make JVM_IsAlive return - // false. So in case another thread is doing a join on this thread , it will detect that the thread - // is dead when it gets notified. - java_lang_Thread::set_stillborn(threadObj()); // Thread is exiting. So set thread_status field in java.lang.Thread class to TERMINATED. java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED); + // Clear the native thread instance - this makes isAlive return false and allows the join() + // to complete once we've done the notify_all below java_lang_Thread::set_thread(threadObj(), NULL); lock.notify_all(thread); // Ignore pending exception (ThreadDeath), since we are exiting anyway @@ -1590,8 +1587,8 @@ CallInfo callinfo; KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass()); LinkResolver::resolve_virtual_call(callinfo, threadObj, recvrKlass, thread_klass, - vmSymbolHandles::dispatchUncaughtException_name(), - vmSymbolHandles::throwable_void_signature(), + vmSymbols::dispatchUncaughtException_name(), + vmSymbols::throwable_void_signature(), KlassHandle(), false, false, THREAD); CLEAR_PENDING_EXCEPTION; methodHandle method = callinfo.selected_method(); @@ -1599,8 +1596,8 @@ JavaValue result(T_VOID); JavaCalls::call_virtual(&result, threadObj, thread_klass, - vmSymbolHandles::dispatchUncaughtException_name(), - vmSymbolHandles::throwable_void_signature(), + vmSymbols::dispatchUncaughtException_name(), + vmSymbols::throwable_void_signature(), uncaught_exception, THREAD); } else { @@ -1608,8 +1605,8 @@ JavaValue result(T_VOID); JavaCalls::call_virtual(&result, group, thread_group, - vmSymbolHandles::uncaughtException_name(), - vmSymbolHandles::thread_throwable_void_signature(), + vmSymbols::uncaughtException_name(), + vmSymbols::thread_throwable_void_signature(), threadObj, // Arg 1 uncaught_exception, // Arg 2 THREAD); @@ -1628,8 +1625,8 @@ KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass()); JavaCalls::call_virtual(&result, threadObj, thread_klass, - vmSymbolHandles::exit_method_name(), - vmSymbolHandles::void_method_signature(), + vmSymbols::exit_method_name(), + vmSymbols::void_method_signature(), THREAD); CLEAR_PENDING_EXCEPTION; } @@ -1996,11 +1993,6 @@ // (the compiler thread should not be a Java thread -- fix in 1.4.2) if (is_Compiler_thread()) return; - // This is a change from JDK 1.1, but JDK 1.2 will also do it: - if (java_throwable->is_a(SystemDictionary::ThreadDeath_klass())) { - java_lang_Thread::set_stillborn(threadObj()); - } - { // Actually throw the Throwable against the target Thread - however // only if there is no thread death exception installed already. @@ -3161,7 +3153,7 @@ } if (InitializeJavaLangString) { - initialize_class(vmSymbolHandles::java_lang_String(), CHECK_0); + initialize_class(vmSymbols::java_lang_String(), CHECK_0); } else { warning("java.lang.String not initialized"); } @@ -3171,10 +3163,10 @@ // Forcibly initialize java/util/HashMap and mutate the private // static final "frontCacheEnabled" field before we start creating instances #ifdef ASSERT - klassOop tmp_k = SystemDictionary::find(vmSymbolHandles::java_util_HashMap(), Handle(), Handle(), CHECK_0); + klassOop tmp_k = SystemDictionary::find(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0); assert(tmp_k == NULL, "java/util/HashMap should not be loaded yet"); #endif - klassOop k_o = SystemDictionary::resolve_or_null(vmSymbolHandles::java_util_HashMap(), Handle(), Handle(), CHECK_0); + klassOop k_o = SystemDictionary::resolve_or_null(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0); KlassHandle k = KlassHandle(THREAD, k_o); guarantee(k.not_null(), "Must find java/util/HashMap"); instanceKlassHandle ik = instanceKlassHandle(THREAD, k()); @@ -3189,7 +3181,7 @@ if (UseStringCache) { // Forcibly initialize java/lang/StringValue and mutate the private // static final "stringCacheEnabled" field before we start creating instances - klassOop k_o = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_StringValue(), Handle(), Handle(), CHECK_0); + klassOop k_o = SystemDictionary::resolve_or_null(vmSymbols::java_lang_StringValue(), Handle(), Handle(), CHECK_0); // Possible that StringValue isn't present: if so, silently don't break if (k_o != NULL) { KlassHandle k = KlassHandle(THREAD, k_o); @@ -3206,11 +3198,11 @@ // Initialize java_lang.System (needed before creating the thread) if (InitializeJavaLangSystem) { - initialize_class(vmSymbolHandles::java_lang_System(), CHECK_0); - initialize_class(vmSymbolHandles::java_lang_ThreadGroup(), CHECK_0); + initialize_class(vmSymbols::java_lang_System(), CHECK_0); + initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0); Handle thread_group = create_initial_thread_group(CHECK_0); Universe::set_main_thread_group(thread_group()); - initialize_class(vmSymbolHandles::java_lang_Thread(), CHECK_0); + initialize_class(vmSymbols::java_lang_Thread(), CHECK_0); oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0); main_thread->set_threadObj(thread_object); // Set thread status to running since main thread has @@ -3219,10 +3211,10 @@ java_lang_Thread::RUNNABLE); // The VM preresolve methods to these classes. Make sure that get initialized - initialize_class(vmSymbolHandles::java_lang_reflect_Method(), CHECK_0); - initialize_class(vmSymbolHandles::java_lang_ref_Finalizer(), CHECK_0); + initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0); + initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0); // The VM creates & returns objects of this class. Make sure it's initialized. - initialize_class(vmSymbolHandles::java_lang_Class(), CHECK_0); + initialize_class(vmSymbols::java_lang_Class(), CHECK_0); call_initializeSystemClass(CHECK_0); } else { warning("java.lang.System not initialized"); @@ -3230,13 +3222,13 @@ // an instance of OutOfMemory exception has been allocated earlier if (InitializeJavaLangExceptionsErrors) { - initialize_class(vmSymbolHandles::java_lang_OutOfMemoryError(), CHECK_0); - initialize_class(vmSymbolHandles::java_lang_NullPointerException(), CHECK_0); - initialize_class(vmSymbolHandles::java_lang_ClassCastException(), CHECK_0); - initialize_class(vmSymbolHandles::java_lang_ArrayStoreException(), CHECK_0); - initialize_class(vmSymbolHandles::java_lang_ArithmeticException(), CHECK_0); - initialize_class(vmSymbolHandles::java_lang_StackOverflowError(), CHECK_0); - initialize_class(vmSymbolHandles::java_lang_IllegalMonitorStateException(), CHECK_0); + initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0); + initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0); + initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0); + initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0); } else { warning("java.lang.OutOfMemoryError has not been initialized"); warning("java.lang.NullPointerException has not been initialized"); @@ -3262,7 +3254,7 @@ // Future Fix : the best fix is to grant everyone permissions to read "java.compiler" and // read and write"java.vm.info" in the default policy file. See bugid 4211383 // Once that is done, we should remove this hack. - initialize_class(vmSymbolHandles::java_lang_Compiler(), CHECK_0); + initialize_class(vmSymbols::java_lang_Compiler(), CHECK_0); // More hackery - the static initializer of java.lang.Compiler adds the string "nojit" to // the java.vm.info property if no jit gets loaded through java.lang.Compiler (the hotspot @@ -3588,7 +3580,7 @@ EXCEPTION_MARK; klassOop k = - SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_Shutdown(), + SystemDictionary::resolve_or_null(vmSymbols::java_lang_Shutdown(), THREAD); if (k != NULL) { // SystemDictionary::resolve_or_null will return null if there was @@ -3602,8 +3594,8 @@ JavaValue result(T_VOID); JavaCalls::call_static(&result, shutdown_klass, - vmSymbolHandles::shutdown_method_name(), - vmSymbolHandles::void_method_signature(), + vmSymbols::shutdown_method_name(), + vmSymbols::void_method_signature(), THREAD); } CLEAR_PENDING_EXCEPTION; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/vframe.cpp --- a/src/share/vm/runtime/vframe.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/vframe.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -552,7 +552,7 @@ tty->print("%s.%s", Klass::cast(k)->internal_name(), m->name()->as_C_string()); if (!m->is_native()) { - symbolOop source_name = instanceKlass::cast(k)->source_file_name(); + Symbol* source_name = instanceKlass::cast(k)->source_file_name(); int line_number = m->line_number_from_bci(bci()); if (source_name != NULL && (line_number != -1)) { tty->print("(%s:%d)", source_name->as_C_string(), line_number); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/vmStructs.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -83,8 +83,7 @@ #include "oops/objArrayKlassKlass.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "oops/symbolKlass.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" #include "oops/typeArrayKlassKlass.hpp" #include "oops/typeArrayOop.hpp" @@ -246,8 +245,8 @@ nonstatic_field(instanceKlass, _class_loader, oop) \ nonstatic_field(instanceKlass, _protection_domain, oop) \ nonstatic_field(instanceKlass, _signers, objArrayOop) \ - nonstatic_field(instanceKlass, _source_file_name, symbolOop) \ - nonstatic_field(instanceKlass, _source_debug_extension, symbolOop) \ + nonstatic_field(instanceKlass, _source_file_name, Symbol*) \ + nonstatic_field(instanceKlass, _source_debug_extension, Symbol*) \ nonstatic_field(instanceKlass, _inner_classes, typeArrayOop) \ nonstatic_field(instanceKlass, _nonstatic_field_size, int) \ nonstatic_field(instanceKlass, _static_field_size, int) \ @@ -265,7 +264,7 @@ nonstatic_field(instanceKlass, _jni_ids, JNIid*) \ nonstatic_field(instanceKlass, _osr_nmethods_head, nmethod*) \ nonstatic_field(instanceKlass, _breakpoints, BreakpointInfo*) \ - nonstatic_field(instanceKlass, _generic_signature, symbolOop) \ + nonstatic_field(instanceKlass, _generic_signature, Symbol*) \ nonstatic_field(instanceKlass, _methods_jmethod_ids, jmethodID*) \ nonstatic_field(instanceKlass, _methods_cached_itable_indices, int*) \ volatile_nonstatic_field(instanceKlass, _idnum_allocated_count, u2) \ @@ -282,7 +281,7 @@ nonstatic_field(Klass, _modifier_flags, jint) \ nonstatic_field(Klass, _super, klassOop) \ nonstatic_field(Klass, _layout_helper, jint) \ - nonstatic_field(Klass, _name, symbolOop) \ + nonstatic_field(Klass, _name, Symbol*) \ nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _subklass, klassOop) \ nonstatic_field(Klass, _next_sibling, klassOop) \ @@ -326,9 +325,10 @@ nonstatic_field(constMethodOopDesc, _generic_signature_index, u2) \ nonstatic_field(objArrayKlass, _element_klass, klassOop) \ nonstatic_field(objArrayKlass, _bottom_klass, klassOop) \ - nonstatic_field(symbolKlass, _alloc_size, juint) \ - nonstatic_field(symbolOopDesc, _length, unsigned short) \ - unchecked_nonstatic_field(symbolOopDesc, _body, sizeof(jbyte)) /* NOTE: no type */ \ + volatile_nonstatic_field(Symbol, _refcount, int) \ + nonstatic_field(Symbol, _identity_hash, int) \ + nonstatic_field(Symbol, _length, unsigned short) \ + unchecked_nonstatic_field(Symbol, _body, sizeof(jbyte)) /* NOTE: no type */ \ nonstatic_field(typeArrayKlass, _max_length, int) \ \ /***********************/ \ @@ -375,7 +375,6 @@ static_field(Universe, _longArrayKlassObj, klassOop) \ static_field(Universe, _singleArrayKlassObj, klassOop) \ static_field(Universe, _doubleArrayKlassObj, klassOop) \ - static_field(Universe, _symbolKlassObj, klassOop) \ static_field(Universe, _methodKlassObj, klassOop) \ static_field(Universe, _constMethodKlassObj, klassOop) \ static_field(Universe, _methodDataKlassObj, klassOop) \ @@ -648,7 +647,7 @@ \ nonstatic_field(BasicHashtableEntry, _next, BasicHashtableEntry*) \ nonstatic_field(BasicHashtableEntry, _hash, unsigned int) \ - nonstatic_field(HashtableEntry, _literal, oop) \ + nonstatic_field(HashtableEntry, _literal, intptr_t) \ \ /*************/ \ /* Hashtable */ \ @@ -683,7 +682,7 @@ /* LoaderConstraintEntry */ \ /*************************/ \ \ - nonstatic_field(LoaderConstraintEntry, _name, symbolOop) \ + nonstatic_field(LoaderConstraintEntry, _name, Symbol*) \ nonstatic_field(LoaderConstraintEntry, _num_loaders, int) \ nonstatic_field(LoaderConstraintEntry, _max_loaders, int) \ nonstatic_field(LoaderConstraintEntry, _loaders, oop*) \ @@ -1088,11 +1087,11 @@ declare_type(objArrayKlassKlass, arrayKlassKlass) \ declare_type(objArrayOopDesc, arrayOopDesc) \ declare_type(constMethodOopDesc, oopDesc) \ - declare_type(symbolKlass, Klass) \ - declare_type(symbolOopDesc, oopDesc) \ declare_type(typeArrayKlass, arrayKlass) \ declare_type(typeArrayKlassKlass, arrayKlassKlass) \ declare_type(typeArrayOopDesc, arrayOopDesc) \ + declare_toplevel_type(Symbol) \ + declare_toplevel_type(Symbol*) \ \ /********/ \ /* Oops */ \ @@ -1109,7 +1108,6 @@ declare_oop_type(narrowOop) \ declare_oop_type(wideKlassOop) \ declare_oop_type(constMethodOop) \ - declare_oop_type(symbolOop) \ declare_oop_type(typeArrayOop) \ \ /*************************************/ \ @@ -1207,33 +1205,21 @@ /*********************************/ \ \ declare_toplevel_type(BasicHashtable) \ - declare_type(Hashtable, BasicHashtable) \ - declare_type(SymbolTable, Hashtable) \ - declare_type(StringTable, Hashtable) \ - declare_type(LoaderConstraintTable, Hashtable) \ - declare_type(TwoOopHashtable, Hashtable) \ - declare_type(Dictionary, TwoOopHashtable) \ - declare_type(PlaceholderTable, TwoOopHashtable) \ - declare_toplevel_type(Hashtable*) \ - declare_toplevel_type(SymbolTable*) \ - declare_toplevel_type(StringTable*) \ - declare_toplevel_type(LoaderConstraintTable*) \ - declare_toplevel_type(TwoOopHashtable*) \ - declare_toplevel_type(Dictionary*) \ - declare_toplevel_type(PlaceholderTable*) \ + declare_type(Hashtable, BasicHashtable) \ + declare_type(SymbolTable, Hashtable) \ + declare_type(StringTable, Hashtable) \ + declare_type(LoaderConstraintTable, Hashtable) \ + declare_type(TwoOopHashtable, Hashtable) \ + declare_type(Dictionary, TwoOopHashtable) \ + declare_type(PlaceholderTable, TwoOopHashtable) \ declare_toplevel_type(BasicHashtableEntry) \ - declare_toplevel_type(BasicHashtableEntry*) \ - declare_type(HashtableEntry, BasicHashtableEntry) \ - declare_type(DictionaryEntry, HashtableEntry) \ - declare_type(PlaceholderEntry, HashtableEntry) \ - declare_type(LoaderConstraintEntry, HashtableEntry) \ - declare_toplevel_type(HashtableEntry*) \ - declare_toplevel_type(DictionaryEntry*) \ + declare_type(HashtableEntry, BasicHashtableEntry) \ + declare_type(DictionaryEntry, HashtableEntry) \ + declare_type(PlaceholderEntry, HashtableEntry) \ + declare_type(LoaderConstraintEntry, HashtableEntry) \ declare_toplevel_type(HashtableBucket) \ - declare_toplevel_type(HashtableBucket*) \ declare_toplevel_type(SystemDictionary) \ declare_toplevel_type(ProtectionDomainEntry) \ - declare_toplevel_type(ProtectionDomainEntry*) \ \ /***********************************************************/ \ /* Thread hierarchy (needed for run-time type information) */ \ @@ -1667,10 +1653,10 @@ declare_constant(instanceKlass::initialization_error) \ \ /*********************************/ \ - /* symbolOop - symbol max length */ \ + /* Symbol* - symbol max length */ \ /*********************************/ \ \ - declare_constant(symbolOopDesc::max_symbol_length) \ + declare_constant(Symbol::max_symbol_length) \ \ /*************************************************/ \ /* constantPoolOop layout enum for InvokeDynamic */ \ @@ -2431,17 +2417,69 @@ } #ifdef ASSERT +static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool isRecurse) { + { + VMTypeEntry* types = origtypes; + while (types->typeName != NULL) { + if (!strcmp(typeName, types->typeName)) { + return 1; + } + ++types; + } + } + size_t len = strlen(typeName); + if (typeName[len-1] == '*') { + char * s = new char[len]; + strncpy(s, typeName, len - 1); + s[len-1] = '\0'; + // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName); + if (recursiveFindType(origtypes, s, true) == 1) { + delete s; + return 1; + } + delete s; + } + if (strstr(typeName, "GrowableArray<") == typeName) { + const char * start = typeName + strlen("GrowableArray<"); + const char * end = strrchr(typeName, '>'); + int len = end - start + 1; + char * s = new char[len]; + strncpy(s, start, len - 1); + s[len-1] = '\0'; + // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName); + if (recursiveFindType(origtypes, s, true) == 1) { + delete s; + return 1; + } + delete s; + } + if (strstr(typeName, "const ") == typeName) { + const char * s = typeName + strlen("const "); + // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName); + if (recursiveFindType(origtypes, s, true) == 1) { + return 1; + } + } + if (strstr(typeName, " const") == typeName + len - 6) { + char * s = strdup(typeName); + s[len - 6] = '\0'; + // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName); + if (recursiveFindType(origtypes, s, true) == 1) { + return 1; + } + } + if (!isRecurse) { + tty->print_cr("type \"%s\" not found", typeName); + } + return 2; +} + + int VMStructs::findType(const char* typeName) { VMTypeEntry* types = gHotSpotVMTypes; - while (types->typeName != NULL) { - if (!strcmp(typeName, types->typeName)) { - return 1; - } - ++types; - } - return 0; + return recursiveFindType(types, typeName, false); } #endif diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/vmStructs.hpp --- a/src/share/vm/runtime/vmStructs.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/vmStructs.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -68,7 +68,7 @@ typedef struct { const char* typeName; // The type name containing the given field (example: "Klass") const char* fieldName; // The field name within the type (example: "_name") - const char* typeString; // Quoted name of the type of this field (example: "symbolOopDesc*"; + const char* typeString; // Quoted name of the type of this field (example: "Symbol*"; // parsed in Java to ensure type correctness int32_t isStatic; // Indicates whether following field is an offset or an address uint64_t offset; // Offset of field within structure; only used for nonstatic fields diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/vm_operations.cpp --- a/src/share/vm/runtime/vm_operations.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/vm_operations.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -23,11 +23,13 @@ */ #include "precompiled.hpp" +#include "classfile/symbolTable.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compilerOracle.hpp" #include "gc_implementation/shared/isGCActiveMark.hpp" #include "memory/resourceArea.hpp" +#include "oops/symbol.hpp" #include "runtime/arguments.hpp" #include "runtime/deoptimization.hpp" #include "runtime/interfaceSupport.hpp" @@ -170,6 +172,12 @@ #endif // !PRODUCT +void VM_UnlinkSymbols::doit() { + JavaThread *thread = (JavaThread *)calling_thread(); + assert(thread->is_Java_thread(), "must be a Java thread"); + SymbolTable::unlink(); +} + void VM_HandleFullCodeCache::doit() { NMethodSweeper::speculative_disconnect_nmethods(_is_full); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/runtime/vm_operations.hpp --- a/src/share/vm/runtime/vm_operations.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/runtime/vm_operations.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -50,6 +50,7 @@ template(DeoptimizeFrame) \ template(DeoptimizeAll) \ template(ZombieAll) \ + template(UnlinkSymbols) \ template(HandleFullCodeCache) \ template(Verify) \ template(PrintJNI) \ @@ -288,6 +289,14 @@ }; #endif // PRODUCT +class VM_UnlinkSymbols: public VM_Operation { + public: + VM_UnlinkSymbols() {} + VMOp_Type type() const { return VMOp_UnlinkSymbols; } + void doit(); + bool allow_nested_vm_operations() const { return true; } +}; + class VM_Verify: public VM_Operation { private: KlassHandle _dependee; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/attachListener.cpp --- a/src/share/vm/services/attachListener.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/attachListener.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -43,7 +43,7 @@ // Invokes sun.misc.VMSupport.serializePropertiesToByteArray to serialize // the system properties into a byte array. -static klassOop load_and_initialize_klass(symbolHandle sh, TRAPS) { +static klassOop load_and_initialize_klass(Symbol* sh, TRAPS) { klassOop k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL); instanceKlassHandle ik (THREAD, k); if (ik->should_be_initialized()) { @@ -52,12 +52,12 @@ return ik(); } -static jint get_properties(AttachOperation* op, outputStream* out, symbolHandle serializePropertiesMethod) { +static jint get_properties(AttachOperation* op, outputStream* out, Symbol* serializePropertiesMethod) { Thread* THREAD = Thread::current(); HandleMark hm; // load sun.misc.VMSupport - symbolHandle klass = vmSymbolHandles::sun_misc_VMSupport(); + Symbol* klass = vmSymbols::sun_misc_VMSupport(); klassOop k = load_and_initialize_klass(klass, THREAD); if (HAS_PENDING_EXCEPTION) { java_lang_Throwable::print(PENDING_EXCEPTION, out); @@ -71,7 +71,7 @@ JavaCallArguments args; - symbolHandle signature = vmSymbolHandles::serializePropertiesToByteArray_signature(); + Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature(); JavaCalls::call_static(&result, ik, serializePropertiesMethod, @@ -99,12 +99,12 @@ // Implementation of "properties" command. static jint get_system_properties(AttachOperation* op, outputStream* out) { - return get_properties(op, out, vmSymbolHandles::serializePropertiesToByteArray_name()); + return get_properties(op, out, vmSymbols::serializePropertiesToByteArray_name()); } // Implementation of "agent_properties" command. static jint get_agent_properties(AttachOperation* op, outputStream* out) { - return get_properties(op, out, vmSymbolHandles::serializeAgentPropertiesToByteArray_name()); + return get_properties(op, out, vmSymbols::serializeAgentPropertiesToByteArray_name()); } // Implementation of "datadump" command. @@ -430,7 +430,7 @@ // Starts the Attach Listener thread void AttachListener::init() { EXCEPTION_MARK; - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(), true, CHECK); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); @@ -442,8 +442,8 @@ JavaValue result(T_VOID); JavaCalls::call_special(&result, thread_oop, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), thread_group, string, CHECK); @@ -452,8 +452,8 @@ JavaCalls::call_special(&result, thread_group, group, - vmSymbolHandles::add_method_name(), - vmSymbolHandles::thread_void_signature(), + vmSymbols::add_method_name(), + vmSymbols::thread_void_signature(), thread_oop, // ARG 1 CHECK); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/classLoadingService.cpp --- a/src/share/vm/services/classLoadingService.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/classLoadingService.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -43,7 +43,7 @@ { \ char* data = NULL; \ int len = 0; \ - symbolOop name = (clss)->name(); \ + Symbol* name = (clss)->name(); \ if (name != NULL) { \ data = (char*)name->bytes(); \ len = name->utf8_length(); \ diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/heapDumper.cpp --- a/src/share/vm/services/heapDumper.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/heapDumper.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -425,6 +425,7 @@ void write_u4(u4 x); void write_u8(u8 x); void write_objectID(oop o); + void write_symbolID(Symbol* o); void write_classID(Klass* k); void write_id(u4 x); }; @@ -568,6 +569,15 @@ #endif } +void DumpWriter::write_symbolID(Symbol* s) { + address a = (address)((uintptr_t)s); +#ifdef _LP64 + write_u8((u8)a); +#else + write_u4((u4)a); +#endif +} + void DumpWriter::write_id(u4 x) { #ifdef _LP64 write_u8((u8) x); @@ -592,7 +602,7 @@ static void write_header(DumpWriter* writer, hprofTag tag, u4 len); // returns hprof tag for the given type signature - static hprofTag sig2tag(symbolOop sig); + static hprofTag sig2tag(Symbol* sig); // returns hprof tag for the given basic type static hprofTag type2tag(BasicType type); @@ -636,7 +646,7 @@ } // returns hprof tag for the given type signature -hprofTag DumperSupport::sig2tag(symbolOop sig) { +hprofTag DumperSupport::sig2tag(Symbol* sig) { switch (sig->byte_at(0)) { case JVM_SIGNATURE_CLASS : return HPROF_NORMAL_OBJECT; case JVM_SIGNATURE_ARRAY : return HPROF_NORMAL_OBJECT; @@ -775,7 +785,7 @@ for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) { if (!fld.access_flags().is_static()) { - symbolOop sig = fld.signature(); + Symbol* sig = fld.signature(); switch (sig->byte_at(0)) { case JVM_SIGNATURE_CLASS : case JVM_SIGNATURE_ARRAY : size += oopSize; break; @@ -815,9 +825,9 @@ // pass 2 - dump the field descriptors and raw values for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) { if (fld.access_flags().is_static()) { - symbolOop sig = fld.signature(); + Symbol* sig = fld.signature(); - writer->write_objectID(fld.name()); // name + writer->write_symbolID(fld.name()); // name writer->write_u1(sig2tag(sig)); // type // value @@ -836,7 +846,7 @@ for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) { if (!fld.access_flags().is_static()) { - symbolOop sig = fld.signature(); + Symbol* sig = fld.signature(); address addr = (address)o + fld.offset(); dump_field_value(writer, sig->byte_at(0), addr); @@ -860,9 +870,9 @@ // pass 2 - dump the field descriptors for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) { if (!fld.access_flags().is_static()) { - symbolOop sig = fld.signature(); + Symbol* sig = fld.signature(); - writer->write_objectID(fld.name()); // name + writer->write_symbolID(fld.name()); // name writer->write_u1(sig2tag(sig)); // type } } @@ -1115,42 +1125,40 @@ write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4)); writer->write_id(frame_serial_num); // frame serial number - writer->write_objectID(m->name()); // method's name - writer->write_objectID(m->signature()); // method's signature + writer->write_symbolID(m->name()); // method's name + writer->write_symbolID(m->signature()); // method's signature assert(Klass::cast(m->method_holder())->oop_is_instance(), "not instanceKlass"); - writer->write_objectID(instanceKlass::cast(m->method_holder())->source_file_name()); // source file name + writer->write_symbolID(instanceKlass::cast(m->method_holder())->source_file_name()); // source file name writer->write_u4(class_serial_num); // class serial number writer->write_u4((u4) line_number); // line number } + // Support class used to generate HPROF_UTF8 records from the entries in the // SymbolTable. -class SymbolTableDumper : public OopClosure { +class SymbolTableDumper : public SymbolClosure { private: DumpWriter* _writer; DumpWriter* writer() const { return _writer; } public: SymbolTableDumper(DumpWriter* writer) { _writer = writer; } - void do_oop(oop* obj_p); - void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); } + void do_symbol(Symbol** p); }; -void SymbolTableDumper::do_oop(oop* obj_p) { +void SymbolTableDumper::do_symbol(Symbol** p) { ResourceMark rm; - symbolOop sym = (symbolOop)*obj_p; - + Symbol* sym = load_symbol(p); int len = sym->utf8_length(); if (len > 0) { char* s = sym->as_utf8(); DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len); - writer()->write_objectID(sym); + writer()->write_symbolID(sym); writer()->write_raw(s, len); } } - // Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records class JNILocalsDumper : public OopClosure { @@ -1548,8 +1556,8 @@ writer()->write_u4(STACK_TRACE_ID); // class name ID - symbolOop name = klass->name(); - writer()->write_objectID(name); + Symbol* name = klass->name(); + writer()->write_symbolID(name); // write a LOAD_CLASS record for the array type (if it exists) k = klass->array_klass_or_null(); @@ -1727,7 +1735,7 @@ // HPROF_UTF8 records SymbolTableDumper sym_dumper(writer()); - SymbolTable::oops_do(&sym_dumper); + SymbolTable::symbols_do(&sym_dumper); // write HPROF_LOAD_CLASS records SystemDictionary::classes_do(&do_load_class); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/lowMemoryDetector.cpp --- a/src/share/vm/services/lowMemoryDetector.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/lowMemoryDetector.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -52,8 +52,8 @@ JavaValue result(T_VOID); JavaCalls::call_special(&result, thread_oop, klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), thread_group, string, CHECK); @@ -377,8 +377,8 @@ JavaCalls::call_virtual(&result, sensorKlass, - vmSymbolHandles::trigger_name(), - vmSymbolHandles::trigger_method_signature(), + vmSymbols::trigger_name(), + vmSymbols::trigger_method_signature(), &args, CHECK); } @@ -403,8 +403,8 @@ args.push_int((int) count); JavaCalls::call_virtual(&result, sensorKlass, - vmSymbolHandles::clear_name(), - vmSymbolHandles::int_void_signature(), + vmSymbols::clear_name(), + vmSymbols::int_void_signature(), &args, CHECK); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/management.cpp --- a/src/share/vm/services/management.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/management.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -122,7 +122,7 @@ // Load and initialize the sun.management.Agent class // invoke startAgent method to start the management server Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::sun_management_Agent(), + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, @@ -132,8 +132,8 @@ JavaValue result(T_VOID); JavaCalls::call_static(&result, ik, - vmSymbolHandles::startAgent_name(), - vmSymbolHandles::void_method_signature(), + vmSymbols::startAgent_name(), + vmSymbols::void_method_signature(), CHECK); } } @@ -142,7 +142,7 @@ memcpy(support, &_optional_support, sizeof(jmmOptionalSupport)); } -klassOop Management::load_and_initialize_klass(symbolHandle sh, TRAPS) { +klassOop Management::load_and_initialize_klass(Symbol* sh, TRAPS) { klassOop k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL); instanceKlassHandle ik (THREAD, k); if (ik->should_be_initialized()) { @@ -182,49 +182,49 @@ klassOop Management::java_lang_management_ThreadInfo_klass(TRAPS) { if (_threadInfo_klass == NULL) { - _threadInfo_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_ThreadInfo(), CHECK_NULL); + _threadInfo_klass = load_and_initialize_klass(vmSymbols::java_lang_management_ThreadInfo(), CHECK_NULL); } return _threadInfo_klass; } klassOop Management::java_lang_management_MemoryUsage_klass(TRAPS) { if (_memoryUsage_klass == NULL) { - _memoryUsage_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_MemoryUsage(), CHECK_NULL); + _memoryUsage_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryUsage(), CHECK_NULL); } return _memoryUsage_klass; } klassOop Management::java_lang_management_MemoryPoolMXBean_klass(TRAPS) { if (_memoryPoolMXBean_klass == NULL) { - _memoryPoolMXBean_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_MemoryPoolMXBean(), CHECK_NULL); + _memoryPoolMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryPoolMXBean(), CHECK_NULL); } return _memoryPoolMXBean_klass; } klassOop Management::java_lang_management_MemoryManagerMXBean_klass(TRAPS) { if (_memoryManagerMXBean_klass == NULL) { - _memoryManagerMXBean_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_MemoryManagerMXBean(), CHECK_NULL); + _memoryManagerMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryManagerMXBean(), CHECK_NULL); } return _memoryManagerMXBean_klass; } klassOop Management::java_lang_management_GarbageCollectorMXBean_klass(TRAPS) { if (_garbageCollectorMXBean_klass == NULL) { - _garbageCollectorMXBean_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_GarbageCollectorMXBean(), CHECK_NULL); + _garbageCollectorMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_GarbageCollectorMXBean(), CHECK_NULL); } return _garbageCollectorMXBean_klass; } klassOop Management::sun_management_Sensor_klass(TRAPS) { if (_sensor_klass == NULL) { - _sensor_klass = load_and_initialize_klass(vmSymbolHandles::sun_management_Sensor(), CHECK_NULL); + _sensor_klass = load_and_initialize_klass(vmSymbols::sun_management_Sensor(), CHECK_NULL); } return _sensor_klass; } klassOop Management::sun_management_ManagementFactory_klass(TRAPS) { if (_managementFactory_klass == NULL) { - _managementFactory_klass = load_and_initialize_klass(vmSymbolHandles::sun_management_ManagementFactory(), CHECK_NULL); + _managementFactory_klass = load_and_initialize_klass(vmSymbols::sun_management_ManagementFactory(), CHECK_NULL); } return _managementFactory_klass; } @@ -290,8 +290,8 @@ // Call ThreadInfo constructor with no locked monitors and synchronizers JavaCalls::call_special(&result, ik, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::java_lang_management_ThreadInfo_constructor_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::java_lang_management_ThreadInfo_constructor_signature(), &args, CHECK_NULL); @@ -325,8 +325,8 @@ // Call ThreadInfo constructor with locked monitors and synchronizers JavaCalls::call_special(&result, ik, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::java_lang_management_ThreadInfo_with_locks_constructor_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::java_lang_management_ThreadInfo_with_locks_constructor_signature(), &args, CHECK_NULL); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/management.hpp --- a/src/share/vm/services/management.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/management.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -50,7 +50,7 @@ static klassOop _garbageCollectorMXBean_klass; static klassOop _managementFactory_klass; - static klassOop load_and_initialize_klass(symbolHandle sh, TRAPS); + static klassOop load_and_initialize_klass(Symbol* sh, TRAPS); public: static void init(); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/memoryManager.cpp --- a/src/share/vm/services/memoryManager.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/memoryManager.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -106,15 +106,15 @@ JavaCallArguments args; args.push_oop(mgr_name); // Argument 1 - symbolHandle method_name; - symbolHandle signature; + Symbol* method_name = NULL; + Symbol* signature = NULL; if (is_gc_memory_manager()) { - method_name = vmSymbolHandles::createGarbageCollector_name(); - signature = vmSymbolHandles::createGarbageCollector_signature(); + method_name = vmSymbols::createGarbageCollector_name(); + signature = vmSymbols::createGarbageCollector_signature(); args.push_oop(Handle()); // Argument 2 (for future extension) } else { - method_name = vmSymbolHandles::createMemoryManager_name(); - signature = vmSymbolHandles::createMemoryManager_signature(); + method_name = vmSymbols::createMemoryManager_name(); + signature = vmSymbols::createMemoryManager_signature(); } JavaCalls::call_static(&result, diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/memoryPool.cpp --- a/src/share/vm/services/memoryPool.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/memoryPool.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -89,8 +89,8 @@ args.push_oop(pool_name); // Argument 1 args.push_int((int) is_heap()); // Argument 2 - symbolHandle method_name = vmSymbolHandles::createMemoryPool_name(); - symbolHandle signature = vmSymbolHandles::createMemoryPool_signature(); + Symbol* method_name = vmSymbols::createMemoryPool_name(); + Symbol* signature = vmSymbols::createMemoryPool_signature(); args.push_long(usage_threshold_value); // Argument 3 args.push_long(gc_usage_threshold_value); // Argument 4 diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/memoryService.cpp --- a/src/share/vm/services/memoryService.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/memoryService.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -619,8 +619,8 @@ JavaCalls::call_special(&result, ik, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::long_long_long_long_void_signature(), + vmSymbols::object_initializer_name(), + vmSymbols::long_long_long_long_void_signature(), &args, CHECK_NH); return obj; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/services/threadService.cpp --- a/src/share/vm/services/threadService.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/services/threadService.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -249,7 +249,7 @@ // Allocate the resulting StackTraceElement[][] object ResourceMark rm(THREAD); - klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_StackTraceElement_array(), true, CHECK_NH); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_StackTraceElement_array(), true, CHECK_NH); objArrayKlassHandle ik (THREAD, k); objArrayOop r = oopFactory::new_objArray(ik(), num_threads, CHECK_NH); objArrayHandle result_obj(THREAD, r); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/debug.cpp --- a/src/share/vm/utilities/debug.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/debug.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -263,6 +263,27 @@ #endif // PRODUCT } +void report_out_of_shared_space(SharedSpaceType shared_space) { + static const char* name[] = { + "permanent generation", + "shared read only space", + "shared read write space", + "shared miscellaneous data space" + }; + static const char* flag[] = { + "PermGen", + "SharedReadOnlySize", + "SharedReadWriteSize", + "SharedMiscDataSize" + }; + + warning("\nThe %s is not large enough\n" + "to preload requested classes. Use -XX:%s=\n" + "to increase the initial size of %s.\n", + name[shared_space], flag[shared_space], name[shared_space]); + exit(2); +} + void report_java_out_of_memory(const char* message) { static jint out_of_memory_reported = 0; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/debug.hpp --- a/src/share/vm/utilities/debug.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/debug.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -176,6 +176,16 @@ void warning(const char* format, ...); +// out of shared space reporting +enum SharedSpaceType { + SharedPermGen, + SharedReadOnly, + SharedReadWrite, + SharedMiscData +}; + +void report_out_of_shared_space(SharedSpaceType space_type); + // out of memory reporting void report_java_out_of_memory(const char* message); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/exceptions.cpp --- a/src/share/vm/utilities/exceptions.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/exceptions.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -102,10 +102,10 @@ return false; } -bool Exceptions::special_exception(Thread* thread, const char* file, int line, symbolHandle h_name, const char* message) { +bool Exceptions::special_exception(Thread* thread, const char* file, int line, Symbol* h_name, const char* message) { // bootstrapping check if (!Universe::is_fully_initialized()) { - if (h_name.is_null()) { + if (h_name == NULL) { // atleast an informative message. vm_exit_during_initialization("Exception", message); } else { @@ -161,7 +161,7 @@ } -void Exceptions::_throw_msg(Thread* thread, const char* file, int line, symbolHandle h_name, const char* message, Handle h_loader, Handle h_protection_domain) { +void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_loader, Handle h_protection_domain) { // Check for special boot-strapping/vm-thread handling if (special_exception(thread, file, line, h_name, message)) return; // Create and throw exception @@ -171,7 +171,7 @@ } // Throw an exception with a message and a cause -void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, symbolHandle h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain) { +void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain) { // Check for special boot-strapping/vm-thread handling if (special_exception(thread, file, line, h_name, message)) return; // Create and throw exception and init cause @@ -179,18 +179,9 @@ _throw(thread, file, line, h_exception, message); } -// This version creates handles and calls the other version -void Exceptions::_throw_msg(Thread* thread, const char* file, int line, - symbolOop name, const char* message) { - symbolHandle h_name(thread, name); - Handle h_loader(thread, NULL); - Handle h_protection_domain(thread, NULL); - Exceptions::_throw_msg(thread, file, line, h_name, message, h_loader, h_protection_domain); -} - // This version already has a handle for name void Exceptions::_throw_msg(Thread* thread, const char* file, int line, - symbolHandle name, const char* message) { + Symbol* name, const char* message) { Handle h_loader(thread, NULL); Handle h_protection_domain(thread, NULL); Exceptions::_throw_msg(thread, file, line, name, message, h_loader, h_protection_domain); @@ -198,13 +189,13 @@ // This version already has a handle for name void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, - symbolHandle name, const char* message, Handle cause) { + Symbol* name, const char* message, Handle cause) { Handle h_loader(thread, NULL); Handle h_protection_domain(thread, NULL); Exceptions::_throw_msg_cause(thread, file, line, name, message, cause, h_loader, h_protection_domain); } -void Exceptions::_throw_args(Thread* thread, const char* file, int line, symbolHandle h_name, symbolHandle h_signature, JavaCallArguments *args) { +void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* h_name, Symbol* h_signature, JavaCallArguments *args) { // Check for special boot-strapping/vm-thread handling if (special_exception(thread, file, line, h_name, NULL)) return; // Create and throw exception @@ -233,7 +224,7 @@ _throw_oop(THREAD, file, line, exception()); } -void Exceptions::fthrow(Thread* thread, const char* file, int line, symbolHandle h_name, const char* format, ...) { +void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) { const int max_msg_size = 1024; va_list ap; va_start(ap, format); @@ -247,8 +238,8 @@ // Creates an exception oop, calls the method with the given signature. // and returns a Handle // Initializes the cause if cause non-null -Handle Exceptions::new_exception(Thread *thread, symbolHandle h_name, - symbolHandle signature, +Handle Exceptions::new_exception(Thread *thread, Symbol* h_name, + Symbol* signature, JavaCallArguments *args, Handle h_cause, Handle h_loader, Handle h_protection_domain) { @@ -275,7 +266,7 @@ args->set_receiver(h_exception); // Call constructor JavaCalls::call_special(&result, klass, - vmSymbolHandles::object_initializer_name(), + vmSymbols::object_initializer_name(), signature, args, thread); @@ -292,8 +283,8 @@ args1.set_receiver(h_exception); args1.push_oop(h_cause); JavaCalls::call_virtual(&result1, klass, - vmSymbolHandles::initCause_name(), - vmSymbolHandles::throwable_throwable_signature(), + vmSymbols::initCause_name(), + vmSymbols::throwable_throwable_signature(), &args1, thread); } @@ -309,15 +300,15 @@ // Convenience method. Calls either the () or (String) method when // creating a new exception -Handle Exceptions::new_exception(Thread* thread, symbolHandle h_name, +Handle Exceptions::new_exception(Thread* thread, Symbol* h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain, ExceptionMsgToUtf8Mode to_utf8_safe) { JavaCallArguments args; - symbolHandle signature; + Symbol* signature = NULL; if (message == NULL) { - signature = vmSymbolHandles::void_method_signature(); + signature = vmSymbols::void_method_signature(); } else { // We want to allocate storage, but we can't do that if there's // a pending exception, so we preserve any pending exception @@ -348,7 +339,7 @@ return incoming_exception; } args.push_oop(msg); - signature = vmSymbolHandles::string_void_signature(); + signature = vmSymbols::string_void_signature(); } return new_exception(thread, h_name, signature, &args, h_cause, h_loader, h_protection_domain); } @@ -362,15 +353,14 @@ // point is to push this flag down to class java_lang_String since other // classes may need similar functionalities. Handle Exceptions::new_exception(Thread* thread, - symbolOop name, + Symbol* name, const char* message, ExceptionMsgToUtf8Mode to_utf8_safe) { - symbolHandle h_name(thread, name); Handle h_loader(thread, NULL); Handle h_prot(thread, NULL); Handle h_cause(thread, NULL); - return Exceptions::new_exception(thread, h_name, message, h_cause, h_loader, + return Exceptions::new_exception(thread, name, message, h_cause, h_loader, h_prot, to_utf8_safe); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/exceptions.hpp --- a/src/share/vm/utilities/exceptions.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/exceptions.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -50,8 +50,7 @@ class Thread; class Handle; -class symbolHandle; -class symbolOopDesc; +class Symbol; class JavaCallArguments; // The ThreadShadow class is a helper class to access the _pending_exception @@ -100,7 +99,7 @@ class Exceptions { static bool special_exception(Thread *thread, const char* file, int line, Handle exception); - static bool special_exception(Thread* thread, const char* file, int line, symbolHandle name, const char* message); + static bool special_exception(Thread* thread, const char* file, int line, Symbol* name, const char* message); public: // this enum is defined to indicate whether it is safe to // ignore the encoding scheme of the original message string. @@ -112,38 +111,36 @@ static void _throw_oop(Thread* thread, const char* file, int line, oop exception); static void _throw(Thread* thread, const char* file, int line, Handle exception, const char* msg = NULL); static void _throw_msg(Thread* thread, const char* file, int line, - symbolHandle name, const char* message, Handle loader, + Symbol* name, const char* message, Handle loader, Handle protection_domain); static void _throw_msg(Thread* thread, const char* file, int line, - symbolOop name, const char* message); - static void _throw_msg(Thread* thread, const char* file, int line, - symbolHandle name, const char* message); + Symbol* name, const char* message); static void _throw_args(Thread* thread, const char* file, int line, - symbolHandle name, symbolHandle signature, + Symbol* name, Symbol* signature, JavaCallArguments* args); static void _throw_msg_cause(Thread* thread, const char* file, - int line, symbolHandle h_name, const char* message, + int line, Symbol* h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain); static void _throw_msg_cause(Thread* thread, const char* file, int line, - symbolHandle name, const char* message, Handle cause); + Symbol* name, const char* message, Handle cause); // There is no THROW... macro for this method. Caller should remember // to do a return after calling it. - static void fthrow(Thread* thread, const char* file, int line, symbolHandle name, + static void fthrow(Thread* thread, const char* file, int line, Symbol* name, const char* format, ...); // Create and initialize a new exception - static Handle new_exception(Thread* thread, symbolHandle name, - symbolHandle signature, JavaCallArguments* args, + static Handle new_exception(Thread* thread, Symbol* name, + Symbol* signature, JavaCallArguments* args, Handle cause, Handle loader, Handle protection_domain); - static Handle new_exception(Thread* thread, symbolHandle name, + static Handle new_exception(Thread* thread, Symbol* name, const char* message, Handle cause, Handle loader, Handle protection_domain, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); - static Handle new_exception(Thread* thread, symbolOop name, + static Handle new_exception(Thread* thread, Symbol* name, const char* message, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/hashtable.cpp --- a/src/share/vm/utilities/hashtable.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/hashtable.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -31,8 +31,9 @@ #include "utilities/hashtable.hpp" #include "utilities/hashtable.inline.hpp" + HS_DTRACE_PROBE_DECL4(hs_private, hashtable__new_entry, - void*, unsigned int, oop, void*); + void*, unsigned int, void*, void*); // This is a generic hashtable, designed to be used for the symbol // and string tables. @@ -67,62 +68,17 @@ } -HashtableEntry* Hashtable::new_entry(unsigned int hashValue, oop obj) { - HashtableEntry* entry; +template HashtableEntry* Hashtable::new_entry(unsigned int hashValue, T obj) { + HashtableEntry* entry; - entry = (HashtableEntry*)BasicHashtable::new_entry(hashValue); - entry->set_literal(obj); // clears literal string field + entry = (HashtableEntry*)BasicHashtable::new_entry(hashValue); + entry->set_literal(obj); HS_DTRACE_PROBE4(hs_private, hashtable__new_entry, this, hashValue, obj, entry); return entry; } -// GC support - -void Hashtable::unlink(BoolObjectClosure* is_alive) { - // Readers of the table are unlocked, so we should only be removing - // entries at a safepoint. - assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); - for (int i = 0; i < table_size(); ++i) { - for (HashtableEntry** p = bucket_addr(i); *p != NULL; ) { - HashtableEntry* entry = *p; - if (entry->is_shared()) { - break; - } - assert(entry->literal() != NULL, "just checking"); - if (is_alive->do_object_b(entry->literal())) { - p = entry->next_addr(); - } else { - *p = entry->next(); - free_entry(entry); - } - } - } -} - - -void Hashtable::oops_do(OopClosure* f) { - for (int i = 0; i < table_size(); ++i) { - HashtableEntry** p = bucket_addr(i); - HashtableEntry* entry = bucket(i); - while (entry != NULL) { - f->do_oop(entry->literal_addr()); - - // Did the closure remove the literal from the table? - if (entry->literal() == NULL) { - assert(!entry->is_shared(), "immutable hashtable entry?"); - *p = entry->next(); - free_entry(entry); - } else { - p = entry->next_addr(); - } - entry = (HashtableEntry*)HashtableEntry::make_ptr(*p); - } - } -} - - // Reverse the order of elements in the hash buckets. void BasicHashtable::reverse() { @@ -156,11 +112,7 @@ *p != NULL; p = (*p)->next_addr()) { if (*top + entry_size() > end) { - warning("\nThe shared miscellaneous data space is not large " - "enough to \npreload requested classes. Use " - "-XX:SharedMiscDataSize= to increase \nthe initial " - "size of the miscellaneous data space.\n"); - exit(2); + report_out_of_shared_space(SharedMiscData); } *p = (BasicHashtableEntry*)memcpy(*top, *p, entry_size()); *top += entry_size(); @@ -181,15 +133,15 @@ // Reverse the order of elements in the hash buckets. -void Hashtable::reverse(void* boundary) { +template void Hashtable::reverse(void* boundary) { for (int i = 0; i < table_size(); ++i) { - HashtableEntry* high_list = NULL; - HashtableEntry* low_list = NULL; - HashtableEntry* last_low_entry = NULL; - HashtableEntry* p = bucket(i); + HashtableEntry* high_list = NULL; + HashtableEntry* low_list = NULL; + HashtableEntry* last_low_entry = NULL; + HashtableEntry* p = bucket(i); while (p != NULL) { - HashtableEntry* next = p->next(); + HashtableEntry* next = p->next(); if ((void*)p->literal() >= boundary) { p->set_next(high_list); high_list = p; @@ -223,11 +175,7 @@ *top += sizeof(intptr_t); if (*top + len > end) { - warning("\nThe shared miscellaneous data space is not large " - "enough to \npreload requested classes. Use " - "-XX:SharedMiscDataSize= to increase \nthe initial " - "size of the miscellaneous data space.\n"); - exit(2); + report_out_of_shared_space(SharedMiscData); } _buckets = (HashtableBucket*)memcpy(*top, _buckets, len); *top += len; @@ -236,11 +184,11 @@ #ifndef PRODUCT -void Hashtable::print() { +template void Hashtable::print() { ResourceMark rm; for (int i = 0; i < table_size(); i++) { - HashtableEntry* entry = bucket(i); + HashtableEntry* entry = bucket(i); while(entry != NULL) { tty->print("%d : ", i); entry->literal()->print(); @@ -277,3 +225,10 @@ } #endif + +// Explicitly instantiate these types +template class Hashtable; +template class Hashtable; +template class Hashtable; +template class Hashtable; + diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/hashtable.hpp --- a/src/share/vm/utilities/hashtable.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/hashtable.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -27,7 +27,7 @@ #include "memory/allocation.hpp" #include "oops/oop.hpp" -#include "oops/symbolOop.hpp" +#include "oops/symbol.hpp" #include "runtime/handles.hpp" // This is a generic hashtable, designed to be used for the symbol @@ -96,16 +96,16 @@ -class HashtableEntry : public BasicHashtableEntry { +template class HashtableEntry : public BasicHashtableEntry { friend class VMStructs; private: - oop _literal; // ref to item in table. + T _literal; // ref to item in table. public: // Literal - oop literal() const { return _literal; } - oop* literal_addr() { return &_literal; } - void set_literal(oop s) { _literal = s; } + T literal() const { return _literal; } + T* literal_addr() { return &_literal; } + void set_literal(T s) { _literal = s; } HashtableEntry* next() const { return (HashtableEntry*)BasicHashtableEntry::next(); @@ -159,6 +159,8 @@ // Reverse the order of elements in each of the buckets. void reverse(); + static unsigned int hash_symbol(const char* s, int len); + private: // Instance variables int _table_size; @@ -205,7 +207,7 @@ }; -class Hashtable : public BasicHashtable { +template class Hashtable : public BasicHashtable { friend class VMStructs; public: @@ -216,16 +218,9 @@ HashtableBucket* buckets, int number_of_entries) : BasicHashtable(table_size, entry_size, buckets, number_of_entries) { } - // Invoke "f->do_oop" on the locations of all oops in the table. - void oops_do(OopClosure* f); - // Debugging void print() PRODUCT_RETURN; - // GC support - // Delete pointers to otherwise-unreachable objects. - void unlink(BoolObjectClosure* cl); - // Reverse the order of elements in each of the buckets. Hashtable // entries which refer to objects at a lower address than 'boundary' // are separated from those which refer to objects at higher @@ -234,45 +229,43 @@ protected: - static unsigned int hash_symbol(const char* s, int len); - - unsigned int compute_hash(symbolHandle name) { + unsigned int compute_hash(Symbol* name) { return (unsigned int) name->identity_hash(); } - int index_for(symbolHandle name) { + int index_for(Symbol* name) { return hash_to_index(compute_hash(name)); } // Table entry management - HashtableEntry* new_entry(unsigned int hashValue, oop obj); + HashtableEntry* new_entry(unsigned int hashValue, T obj); // The following method is MT-safe and may be used with caution. - HashtableEntry* bucket(int i) { - return (HashtableEntry*)BasicHashtable::bucket(i); + HashtableEntry* bucket(int i) { + return (HashtableEntry*)BasicHashtable::bucket(i); } // The following method is not MT-safe and must be done under lock. - HashtableEntry** bucket_addr(int i) { - return (HashtableEntry**)BasicHashtable::bucket_addr(i); + HashtableEntry** bucket_addr(int i) { + return (HashtableEntry**)BasicHashtable::bucket_addr(i); } }; // Verions of hashtable where two handles are used to compute the index. -class TwoOopHashtable : public Hashtable { +template class TwoOopHashtable : public Hashtable { friend class VMStructs; protected: TwoOopHashtable(int table_size, int entry_size) - : Hashtable(table_size, entry_size) {} + : Hashtable(table_size, entry_size) {} TwoOopHashtable(int table_size, int entry_size, HashtableBucket* t, int number_of_entries) - : Hashtable(table_size, entry_size, t, number_of_entries) {} + : Hashtable(table_size, entry_size, t, number_of_entries) {} public: - unsigned int compute_hash(symbolHandle name, Handle loader) { + unsigned int compute_hash(Symbol* name, Handle loader) { // Be careful with identity_hash(), it can safepoint and if this // were one expression, the compiler could choose to unhandle each // oop before calling identity_hash() for either of them. If the first @@ -282,7 +275,7 @@ return name_hash ^ loader_hash; } - int index_for(symbolHandle name, Handle loader) { + int index_for(Symbol* name, Handle loader) { return hash_to_index(compute_hash(name, loader)); } }; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/hashtable.inline.hpp --- a/src/share/vm/utilities/hashtable.inline.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/hashtable.inline.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -41,7 +41,7 @@ // hash P(31) from Kernighan & Ritchie -inline unsigned int Hashtable::hash_symbol(const char* s, int len) { +inline unsigned int BasicHashtable::hash_symbol(const char* s, int len) { unsigned int h = 0; while (len-- > 0) { h = 31*h + (unsigned) *s; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/utf8.cpp --- a/src/share/vm/utilities/utf8.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/utf8.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -164,7 +164,7 @@ // Returns NULL if 'c' it not found. This only works as long // as 'c' is an ASCII character -jbyte* UTF8::strrchr(jbyte* base, int length, jbyte c) { +const jbyte* UTF8::strrchr(const jbyte* base, int length, jbyte c) { assert(length >= 0, "sanity check"); assert(c >= 0, "does not work for non-ASCII characters"); // Skip backwards in string until 'c' is found or end is reached @@ -172,7 +172,7 @@ return (length < 0) ? NULL : &base[length]; } -bool UTF8::equal(jbyte* base1, int length1, jbyte* base2, int length2) { +bool UTF8::equal(const jbyte* base1, int length1, const jbyte* base2, int length2) { // Length must be the same if (length1 != length2) return false; for (int i = 0; i < length1; i++) { diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/utf8.hpp --- a/src/share/vm/utilities/utf8.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/utf8.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -51,8 +51,8 @@ static char* next_character(const char* str, jint* value); // Utility methods - static jbyte* strrchr(jbyte* base, int length, jbyte c); - static bool equal(jbyte* base1, int length1, jbyte* base2, int length2); + static const jbyte* strrchr(const jbyte* base, int length, jbyte c); + static bool equal(const jbyte* base1, int length1, const jbyte* base2,int length2); static bool is_supplementary_character(const unsigned char* str); static jint get_supplementary_character(const unsigned char* str); }; diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/xmlstream.cpp --- a/src/share/vm/utilities/xmlstream.cpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/xmlstream.cpp Thu Feb 03 23:26:25 2011 -0800 @@ -422,17 +422,17 @@ klass->name()->print_symbol_on(out()); } -void xmlStream::name(symbolHandle name) { +void xmlStream::name(const Symbol* name) { assert_if_no_error(inside_attrs(), "printing attributes"); - if (name.is_null()) return; + if (name == NULL) return; print_raw(" name='"); name_text(name); print_raw("'"); } -void xmlStream::name_text(symbolHandle name) { +void xmlStream::name_text(const Symbol* name) { assert_if_no_error(inside_attrs(), "printing attributes"); - if (name.is_null()) return; + if (name == NULL) return; //name->print_short_name(text()); name->print_symbol_on(text()); } @@ -455,8 +455,6 @@ method_text(methodOop(x())); else if (x->is_klass()) klass_text(klassOop(x())); - else if (x->is_symbol()) - name_text(symbolOop(x())); else x->print_value_on(text()); } diff -r 6ecdca5709df -r ae4b185f2ed1 src/share/vm/utilities/xmlstream.hpp --- a/src/share/vm/utilities/xmlstream.hpp Thu Feb 03 17:22:06 2011 -0800 +++ b/src/share/vm/utilities/xmlstream.hpp Thu Feb 03 23:26:25 2011 -0800 @@ -139,13 +139,13 @@ void stamp(); // stamp='1.234' void method(methodHandle m); // method='k n s' ... void klass(KlassHandle k); // klass='name' - void name(symbolHandle s); // name='name' + void name(const Symbol* s); // name='name' void object(const char* attr, Handle val); // print the text alone (sans ''): void method_text(methodHandle m); void klass_text(KlassHandle k); // klass='name' - void name_text(symbolHandle s); // name='name' + void name_text(const Symbol* s); // name='name' void object_text(Handle x); /* Example uses: