This commit is contained in:
J. Duke 2017-07-05 17:34:09 +02:00
commit 9927e275b8
262 changed files with 4429 additions and 3827 deletions

View File

@ -102,3 +102,4 @@ ed6950da30cf1e8904b4bdb034d471647942271f jdk7-b123
5c4df7e992775c102f08e9f1c0a124b324641b70 jdk7-b125 5c4df7e992775c102f08e9f1c0a124b324641b70 jdk7-b125
b566d490905691787f8931f69947a92c67c6d5e4 jdk7-b126 b566d490905691787f8931f69947a92c67c6d5e4 jdk7-b126
bd70f76b0309068f157ae759c36eac8f2c6d098e jdk7-b127 bd70f76b0309068f157ae759c36eac8f2c6d098e jdk7-b127
57d702105b23fb90e40beaf00f8f8aeae5e249e7 jdk7-b128

View File

@ -921,7 +921,7 @@
<!-- ------------------------------------------------------ --> <!-- ------------------------------------------------------ -->
<h4><a name="ant">Ant</a></h4> <h4><a name="ant">Ant</a></h4>
<blockquote> <blockquote>
All OpenJDK builds require access to least Ant 1.6.5. All OpenJDK builds require access to least Ant 1.7.1.
The Ant tool is available from the The Ant tool is available from the
<a href="http://ant.apache.org" target="_blank"> <a href="http://ant.apache.org" target="_blank">
Ant download site</a>. Ant download site</a>.

View File

@ -143,4 +143,6 @@ f5603a6e50422046ebc0d2f1671d55cb8f1bf1e9 jdk7-b120
e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 jdk7-b125 e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 jdk7-b125
4c851c931d001a882cab809aaf3a55371b919244 jdk7-b126 4c851c931d001a882cab809aaf3a55371b919244 jdk7-b126
e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 hs20-b06 e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 hs20-b06
d535bf4c12355a2897e918da9f8910c0aceec4fb hs20-b07
102466e70debc4b907afbd7624e34ddb1aafee9f jdk7-b127 102466e70debc4b907afbd7624e34ddb1aafee9f jdk7-b127
9a5762f448595794d449a8e17342abd81a3fadaf jdk7-b128

View File

@ -428,6 +428,36 @@ public class CommandProcessor {
} }
} }
}, },
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) { new Command("flags", "flags [ flag ]", false) {
public void doit(Tokens t) { public void doit(Tokens t) {
int tokens = t.countTokens(); int tokens = t.countTokens();
@ -629,17 +659,6 @@ public class CommandProcessor {
} }
} }
}, },
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) { new Command("printstatics", "printstatics [ type ]", false) {
public void doit(Tokens t) { public void doit(Tokens t) {
if (t.countTokens() > 1) { if (t.countTokens() > 1) {
@ -1262,6 +1281,9 @@ public class CommandProcessor {
this.err = err; this.err = err;
for (int i = 0; i < commandList.length; i++) { for (int i = 0; i < commandList.length; i++) {
Command c = commandList[i]; Command c = commandList[i];
if (commands.get(c.name) != null) {
throw new InternalError(c.name + " has multiple definitions");
}
commands.put(c.name, c); commands.put(c.name, c);
} }
if (debugger.isAttached()) { if (debugger.isAttached()) {

View File

@ -89,6 +89,37 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
readVMLongConstants(); 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() { private void readVMTypes() {
// Get the variables we need in order to traverse the VMTypeEntry[] // Get the variables we need in order to traverse the VMTypeEntry[]
long typeEntryTypeNameOffset; long typeEntryTypeNameOffset;
@ -250,7 +281,7 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
BasicType containingType = lookupOrFail(typeName); BasicType containingType = lookupOrFail(typeName);
// The field's Type must already be in the database -- no exceptions // 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 // Create field by type
createField(containingType, fieldName, fieldType, createField(containingType, fieldName, fieldType,
@ -442,10 +473,17 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
workarounds due to incomplete information in the VMStructs workarounds due to incomplete information in the VMStructs
database. */ database. */
private BasicPointerType recursiveCreateBasicPointerType(String typeName) { 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(); String targetTypeName = typeName.substring(0, typeName.lastIndexOf('*')).trim();
Type targetType = null; Type targetType = null;
if (typeNameIsPointerType(targetTypeName)) { if (typeNameIsPointerType(targetTypeName)) {
targetType = recursiveCreateBasicPointerType(targetTypeName); targetType = lookupType(targetTypeName, false);
if (targetType == null) {
targetType = recursiveCreateBasicPointerType(targetTypeName);
}
} else { } else {
targetType = lookupType(targetTypeName, false); targetType = lookupType(targetTypeName, false);
if (targetType == null) { if (targetType == null) {
@ -466,6 +504,20 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
BasicType basicTargetType = createBasicType(targetTypeName, false, true, true); BasicType basicTargetType = createBasicType(targetTypeName, false, true, true);
basicTargetType.setSize(1); basicTargetType.setSize(1);
targetType = basicTargetType; 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 { } else {
if (DEBUG) { if (DEBUG) {
System.err.println("WARNING: missing target type \"" + targetTypeName + "\" for pointer type \"" + typeName + "\""); System.err.println("WARNING: missing target type \"" + targetTypeName + "\" for pointer type \"" + typeName + "\"");
@ -474,7 +526,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
} }
} }
} }
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) { private boolean typeNameIsPointerType(String typeName) {

View File

@ -112,7 +112,7 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
} }
// return Symbol (if unresolved) or Klass (if resolved) // return Symbol (if unresolved) or Klass (if resolved)
public Oop getKlass() { public Object getKlass() {
if (Assert.ASSERTS_ENABLED) { if (Assert.ASSERTS_ENABLED) {
Assert.that(isKlassConstant(), "not a klass literal"); Assert.that(isKlassConstant(), "not a klass literal");
} }
@ -121,11 +121,11 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
// decide based on the oop type. // decide based on the oop type.
ConstantPool cpool = method().getConstants(); ConstantPool cpool = method().getConstants();
int cpIndex = index(); int cpIndex = index();
Oop oop = cpool.getObjAt(cpIndex); ConstantPool.CPSlot oop = cpool.getSlotAt(cpIndex);
if (oop.isKlass()) { if (oop.isOop()) {
return (Klass) oop; return (Klass) oop.getOop();
} else if (oop.isSymbol()) { } else if (oop.isMetaData()) {
return (Symbol) oop; return oop.getSymbol();
} else { } else {
throw new RuntimeException("should not reach here"); throw new RuntimeException("should not reach here");
} }
@ -165,12 +165,12 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
// tag change from 'unresolved' to 'string' does not happen atomically. // tag change from 'unresolved' to 'string' does not happen atomically.
// We just look at the object at the corresponding index and // We just look at the object at the corresponding index and
// decide based on the oop type. // decide based on the oop type.
Oop obj = cpool.getObjAt(cpIndex); ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
if (obj.isSymbol()) { if (obj.isMetaData()) {
Symbol sym = (Symbol) obj; Symbol sym = obj.getSymbol();
return "<String \"" + sym.asString() + "\">"; return "<String \"" + sym.asString() + "\">";
} else if (obj.isInstance()) { } else if (obj.isOop()) {
return "<String \"" + OopUtilities.stringOopToString(obj) + "\">"; return "<String \"" + OopUtilities.stringOopToString(obj.getOop()) + "\">";
} else { } else {
throw new RuntimeException("should not reach here"); throw new RuntimeException("should not reach here");
} }
@ -178,13 +178,13 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
// tag change from 'unresolved' to 'klass' does not happen atomically. // tag change from 'unresolved' to 'klass' does not happen atomically.
// We just look at the object at the corresponding index and // We just look at the object at the corresponding index and
// decide based on the oop type. // decide based on the oop type.
Oop obj = cpool.getObjAt(cpIndex); ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
if (obj.isKlass()) { if (obj.isOop()) {
Klass k = (Klass) obj; Klass k = (Klass) obj.getOop();
return "<Class " + k.getName().asString() + "@" + k.getHandle() + ">"; return "<Class " + k.getName().asString() + "@" + k.getHandle() + ">";
} else if (obj.isSymbol()) { } else if (obj.isMetaData()) {
Symbol sym = (Symbol) obj; Symbol sym = obj.getSymbol();
return "<Class " + sym.asString() + ">"; return "<Class " + sym.asString() + ">";
} else { } else {
throw new RuntimeException("should not reach here"); throw new RuntimeException("should not reach here");
} }

View File

@ -37,11 +37,11 @@ public class BytecodeWithKlass extends BytecodeWithCPIndex {
} }
public Symbol getClassName() { public Symbol getClassName() {
Oop obj = method().getConstants().getObjAt(index()); ConstantPool.CPSlot obj = method().getConstants().getSlotAt(index());
if (obj instanceof Symbol) { if (obj.isMetaData()) {
return (Symbol)obj; return obj.getSymbol();
} else { } else {
return ((Klass)obj).getName(); return ((Klass)obj.getOop()).getName();
} }
} }

View File

@ -63,7 +63,7 @@ public class DictionaryEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
} }
public Klass klass() { public Klass klass() {
return (Klass) literal(); return (Klass)VM.getVM().getObjectHeap().newOop(literalValue().addOffsetToAsOopHandle(0));
} }
public DictionaryEntry(Address addr) { public DictionaryEntry(Address addr) {

View File

@ -42,14 +42,14 @@ public class LoaderConstraintEntry extends sun.jvm.hotspot.utilities.HashtableEn
private static synchronized void initialize(TypeDataBase db) { private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("LoaderConstraintEntry"); Type type = db.lookupType("LoaderConstraintEntry");
nameField = type.getOopField("_name"); nameField = type.getAddressField("_name");
numLoadersField = type.getCIntegerField("_num_loaders"); numLoadersField = type.getCIntegerField("_num_loaders");
maxLoadersField = type.getCIntegerField("_max_loaders"); maxLoadersField = type.getCIntegerField("_max_loaders");
loadersField = type.getAddressField("_loaders"); loadersField = type.getAddressField("_loaders");
} }
// Fields // Fields
private static sun.jvm.hotspot.types.OopField nameField; private static AddressField nameField;
private static CIntegerField numLoadersField; private static CIntegerField numLoadersField;
private static CIntegerField maxLoadersField; private static CIntegerField maxLoadersField;
private static AddressField loadersField; private static AddressField loadersField;
@ -57,7 +57,7 @@ public class LoaderConstraintEntry extends sun.jvm.hotspot.utilities.HashtableEn
// Accessors // Accessors
public Symbol name() { public Symbol name() {
return (Symbol) VM.getVM().getObjectHeap().newOop(nameField.getValue(addr)); return Symbol.create(nameField.getValue(addr));
} }
public int numLoaders() { public int numLoaders() {

View File

@ -58,7 +58,7 @@ public class PlaceholderEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
} }
public Symbol klass() { public Symbol klass() {
return (Symbol) literal(); return Symbol.create(literalValue());
} }
/* covariant return type :-( /* covariant return type :-(

View File

@ -70,11 +70,13 @@ public class StringTable extends sun.jvm.hotspot.utilities.Hashtable {
} }
public void stringsDo(StringVisitor visitor) { public void stringsDo(StringVisitor visitor) {
ObjectHeap oh = VM.getVM().getObjectHeap();
int numBuckets = tableSize(); int numBuckets = tableSize();
for (int i = 0; i < numBuckets; i++) { for (int i = 0; i < numBuckets; i++) {
for (HashtableEntry e = (HashtableEntry) bucket(i); e != null; for (HashtableEntry e = (HashtableEntry) bucket(i); e != null;
e = (HashtableEntry) e.next()) { e = (HashtableEntry) e.next()) {
visitor.visit((Instance) e.literal()); Instance s = (Instance)oh.newOop(e.literalValue().addOffsetToAsOopHandle(0));
visitor.visit(s);
} }
} }
} }

View File

@ -85,7 +85,7 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
long hashValue = hashSymbol(name); long hashValue = hashSymbol(name);
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) { for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
if (e.hash() == hashValue) { if (e.hash() == hashValue) {
Symbol sym = (Symbol) e.literal(); Symbol sym = Symbol.create(e.literalValue());
if (sym.equals(name)) { if (sym.equals(name)) {
return sym; return sym;
} }
@ -103,7 +103,7 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
for (int i = 0; i < numBuckets; i++) { for (int i = 0; i < numBuckets; i++) {
for (HashtableEntry e = (HashtableEntry) bucket(i); e != null; for (HashtableEntry e = (HashtableEntry) bucket(i); e != null;
e = (HashtableEntry) e.next()) { e = (HashtableEntry) e.next()) {
visitor.visit((Symbol) e.literal()); visitor.visit(Symbol.create(e.literalValue()));
} }
} }
} }

View File

@ -35,6 +35,38 @@ import sun.jvm.hotspot.utilities.*;
// as described in the class file // as described in the class file
public class ConstantPool extends Oop implements ClassConstants { 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 // Used for debugging this code
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
@ -110,12 +142,17 @@ public class ConstantPool extends Oop implements ClassConstants {
return new ConstantTag(getTags().getByteAt((int) index)); 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))); return getHeap().newOop(getHandle().getOopHandleAt(indexOffset(index)));
} }
public Symbol getSymbolAt(long index) { public Symbol getSymbolAt(long index) {
return (Symbol) getObjAt(index); CPSlot slot = getSlotAt(index);
return slot.getSymbol();
} }
public int getIntAt(long index){ public int getIntAt(long index){
@ -187,7 +224,7 @@ public class ConstantPool extends Oop implements ClassConstants {
// returns null, if not resolved. // returns null, if not resolved.
public Klass getKlassRefAt(int which) { public Klass getKlassRefAt(int which) {
if( ! getTagAt(which).isKlass()) return null; if( ! getTagAt(which).isKlass()) return null;
return (Klass) getObjAt(which); return (Klass) getObjAtRaw(which);
} }
// returns null, if not resolved. // returns null, if not resolved.
@ -477,7 +514,7 @@ public class ConstantPool extends Oop implements ClassConstants {
case JVM_CONSTANT_Class: { case JVM_CONSTANT_Class: {
dos.writeByte(cpConstType); dos.writeByte(cpConstType);
// Klass already resolved. ConstantPool constains klassOop. // Klass already resolved. ConstantPool constains klassOop.
Klass refKls = (Klass) getObjAt(ci); Klass refKls = (Klass) getObjAtRaw(ci);
String klassName = refKls.getName().asString(); String klassName = refKls.getName().asString();
Short s = (Short) utf8ToIndex.get(klassName); Short s = (Short) utf8ToIndex.get(klassName);
dos.writeShort(s.shortValue()); dos.writeShort(s.shortValue());
@ -498,7 +535,7 @@ public class ConstantPool extends Oop implements ClassConstants {
case JVM_CONSTANT_String: { case JVM_CONSTANT_String: {
dos.writeByte(cpConstType); dos.writeByte(cpConstType);
String str = OopUtilities.stringOopToString(getObjAt(ci)); String str = OopUtilities.stringOopToString(getObjAtRaw(ci));
Short s = (Short) utf8ToIndex.get(str); Short s = (Short) utf8ToIndex.get(str);
dos.writeShort(s.shortValue()); dos.writeShort(s.shortValue());
if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);

View File

@ -576,7 +576,7 @@ public class GenerateOopMap {
ConstantPool cp = method().getConstants(); ConstantPool cp = method().getConstants();
int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx); int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx);
int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx); 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()); tty.print("%s", signature.as_C_string());
*/ */
} }
@ -616,7 +616,7 @@ public class GenerateOopMap {
constantPoolOop cp = method().constants(); constantPoolOop cp = method().constants();
int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx); int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx);
int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx); 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()); tty.print("%s", signature.as_C_string());
*/ */
} }

View File

@ -82,8 +82,8 @@ public class InstanceKlass extends Klass {
classLoader = new OopField(type.getOopField("_class_loader"), Oop.getHeaderSize()); classLoader = new OopField(type.getOopField("_class_loader"), Oop.getHeaderSize());
protectionDomain = new OopField(type.getOopField("_protection_domain"), Oop.getHeaderSize()); protectionDomain = new OopField(type.getOopField("_protection_domain"), Oop.getHeaderSize());
signers = new OopField(type.getOopField("_signers"), Oop.getHeaderSize()); signers = new OopField(type.getOopField("_signers"), Oop.getHeaderSize());
sourceFileName = new OopField(type.getOopField("_source_file_name"), Oop.getHeaderSize()); sourceFileName = type.getAddressField("_source_file_name");
sourceDebugExtension = new OopField(type.getOopField("_source_debug_extension"), Oop.getHeaderSize()); sourceDebugExtension = type.getAddressField("_source_debug_extension");
innerClasses = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize()); innerClasses = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize());
nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize()); nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize());
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize()); staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
@ -94,7 +94,7 @@ public class InstanceKlass extends Klass {
vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize()); vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize());
itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize()); itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize());
breakpoints = type.getAddressField("_breakpoints"); 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()); majorVersion = new CIntField(type.getCIntegerField("_major_version"), Oop.getHeaderSize());
minorVersion = new CIntField(type.getCIntegerField("_minor_version"), Oop.getHeaderSize()); minorVersion = new CIntField(type.getCIntegerField("_minor_version"), Oop.getHeaderSize());
headerSize = alignObjectOffset(Oop.getHeaderSize() + type.getSize()); headerSize = alignObjectOffset(Oop.getHeaderSize() + type.getSize());
@ -135,8 +135,8 @@ public class InstanceKlass extends Klass {
private static OopField classLoader; private static OopField classLoader;
private static OopField protectionDomain; private static OopField protectionDomain;
private static OopField signers; private static OopField signers;
private static OopField sourceFileName; private static AddressField sourceFileName;
private static OopField sourceDebugExtension; private static AddressField sourceDebugExtension;
private static OopField innerClasses; private static OopField innerClasses;
private static CIntField nonstaticFieldSize; private static CIntField nonstaticFieldSize;
private static CIntField staticFieldSize; private static CIntField staticFieldSize;
@ -147,7 +147,7 @@ public class InstanceKlass extends Klass {
private static CIntField vtableLen; private static CIntField vtableLen;
private static CIntField itableLen; private static CIntField itableLen;
private static AddressField breakpoints; private static AddressField breakpoints;
private static OopField genericSignature; private static AddressField genericSignature;
private static CIntField majorVersion; private static CIntField majorVersion;
private static CIntField minorVersion; private static CIntField minorVersion;
@ -257,8 +257,8 @@ public class InstanceKlass extends Klass {
public Oop getClassLoader() { return classLoader.getValue(this); } public Oop getClassLoader() { return classLoader.getValue(this); }
public Oop getProtectionDomain() { return protectionDomain.getValue(this); } public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
public ObjArray getSigners() { return (ObjArray) signers.getValue(this); } public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
public Symbol getSourceFileName() { return (Symbol) sourceFileName.getValue(this); } public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
public Symbol getSourceDebugExtension(){ return (Symbol) sourceDebugExtension.getValue(this); } public Symbol getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); } public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); }
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); } public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
public long getStaticFieldSize() { return staticFieldSize.getValue(this); } public long getStaticFieldSize() { return staticFieldSize.getValue(this); }
@ -267,7 +267,7 @@ public class InstanceKlass extends Klass {
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
public long getVtableLen() { return vtableLen.getValue(this); } public long getVtableLen() { return vtableLen.getValue(this); }
public long getItableLen() { return itableLen.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 majorVersion() { return majorVersion.getValue(this); }
public long minorVersion() { return minorVersion.getValue(this); } public long minorVersion() { return minorVersion.getValue(this); }
@ -308,12 +308,12 @@ public class InstanceKlass extends Klass {
if (ioff != 0) { if (ioff != 0) {
// only look at classes that are already loaded // only look at classes that are already loaded
// since we are looking for the flags for our self. // since we are looking for the flags for our self.
Oop classInfo = getConstants().getObjAt(ioff); ConstantPool.CPSlot classInfo = getConstants().getSlotAt(ioff);
Symbol name = null; Symbol name = null;
if (classInfo instanceof Klass) { if (classInfo.isOop()) {
name = ((Klass) classInfo).getName(); name = ((Klass) classInfo.getOop()).getName();
} else if (classInfo instanceof Symbol) { } else if (classInfo.isMetaData()) {
name = (Symbol) classInfo; name = classInfo.getSymbol();
} else { } else {
throw new RuntimeException("should not reach here"); throw new RuntimeException("should not reach here");
} }
@ -358,12 +358,12 @@ public class InstanceKlass extends Klass {
// 'ioff' can be zero. // 'ioff' can be zero.
// refer to JVM spec. section 4.7.5. // refer to JVM spec. section 4.7.5.
if (ioff != 0) { if (ioff != 0) {
Oop iclassInfo = getConstants().getObjAt(ioff); ConstantPool.CPSlot iclassInfo = getConstants().getSlotAt(ioff);
Symbol innerName = null; Symbol innerName = null;
if (iclassInfo instanceof Klass) { if (iclassInfo.isOop()) {
innerName = ((Klass) iclassInfo).getName(); innerName = ((Klass) iclassInfo.getOop()).getName();
} else if (iclassInfo instanceof Symbol) { } else if (iclassInfo.isMetaData()) {
innerName = (Symbol) iclassInfo; innerName = iclassInfo.getSymbol();
} else { } else {
throw new RuntimeException("should not reach here"); throw new RuntimeException("should not reach here");
} }
@ -387,12 +387,12 @@ public class InstanceKlass extends Klass {
} }
} }
} else { } else {
Oop oclassInfo = getConstants().getObjAt(ooff); ConstantPool.CPSlot oclassInfo = getConstants().getSlotAt(ooff);
Symbol outerName = null; Symbol outerName = null;
if (oclassInfo instanceof Klass) { if (oclassInfo.isOop()) {
outerName = ((Klass) oclassInfo).getName(); outerName = ((Klass) oclassInfo.getOop()).getName();
} else if (oclassInfo instanceof Symbol) { } else if (oclassInfo.isMetaData()) {
outerName = (Symbol) oclassInfo; outerName = oclassInfo.getSymbol();
} else { } else {
throw new RuntimeException("should not reach here"); throw new RuntimeException("should not reach here");
} }
@ -450,7 +450,6 @@ public class InstanceKlass extends Klass {
visitor.doOop(classLoader, true); visitor.doOop(classLoader, true);
visitor.doOop(protectionDomain, true); visitor.doOop(protectionDomain, true);
visitor.doOop(signers, true); visitor.doOop(signers, true);
visitor.doOop(sourceFileName, true);
visitor.doOop(innerClasses, true); visitor.doOop(innerClasses, true);
visitor.doCInt(nonstaticFieldSize, true); visitor.doCInt(nonstaticFieldSize, true);
visitor.doCInt(staticFieldSize, true); visitor.doCInt(staticFieldSize, true);
@ -467,7 +466,7 @@ public class InstanceKlass extends Klass {
for (int index = 0; index < length; index += NEXT_OFFSET) { for (int index = 0; index < length; index += NEXT_OFFSET) {
short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET); short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET);
short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_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); AccessFlags access = new AccessFlags(accessFlags);
if (access.isStatic()) { if (access.isStatic()) {
visitField(visitor, type, index); visitField(visitor, type, index);
@ -490,7 +489,7 @@ public class InstanceKlass extends Klass {
short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET); short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET);
short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_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); AccessFlags access = new AccessFlags(accessFlags);
if (!access.isStatic()) { if (!access.isStatic()) {
visitField(visitor, type, index); visitField(visitor, type, index);
@ -787,7 +786,7 @@ public class InstanceKlass extends Klass {
private Field newField(int index) { private Field newField(int index) {
TypeArray fields = getFields(); TypeArray fields = getFields();
short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET); 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 (type.isOop()) {
if (VM.getVM().isCompressedOopsEnabled()) { if (VM.getVM().isCompressedOopsEnabled()) {
return new NarrowOopField(this, index); return new NarrowOopField(this, index);

View File

@ -53,7 +53,7 @@ public class Klass extends Oop implements ClassConstants {
javaMirror = new OopField(type.getOopField("_java_mirror"), Oop.getHeaderSize()); javaMirror = new OopField(type.getOopField("_java_mirror"), Oop.getHeaderSize());
superField = new OopField(type.getOopField("_super"), Oop.getHeaderSize()); superField = new OopField(type.getOopField("_super"), Oop.getHeaderSize());
layoutHelper = new IntField(type.getJIntField("_layout_helper"), 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()); accessFlags = new CIntField(type.getCIntegerField("_access_flags"), Oop.getHeaderSize());
subklass = new OopField(type.getOopField("_subklass"), Oop.getHeaderSize()); subklass = new OopField(type.getOopField("_subklass"), Oop.getHeaderSize());
nextSibling = new OopField(type.getOopField("_next_sibling"), Oop.getHeaderSize()); nextSibling = new OopField(type.getOopField("_next_sibling"), Oop.getHeaderSize());
@ -83,18 +83,26 @@ public class Klass extends Oop implements ClassConstants {
private static OopField javaMirror; private static OopField javaMirror;
private static OopField superField; private static OopField superField;
private static IntField layoutHelper; private static IntField layoutHelper;
private static OopField name; private static AddressField name;
private static CIntField accessFlags; private static CIntField accessFlags;
private static OopField subklass; private static OopField subklass;
private static OopField nextSibling; private static OopField nextSibling;
private static CIntField allocCount; 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 // Accessors for declared fields
public Instance getJavaMirror() { return (Instance) javaMirror.getValue(this); } public Instance getJavaMirror() { return (Instance) javaMirror.getValue(this); }
public Klass getSuper() { return (Klass) superField.getValue(this); } public Klass getSuper() { return (Klass) superField.getValue(this); }
public Klass getJavaSuper() { return null; } public Klass getJavaSuper() { return null; }
public int getLayoutHelper() { return (int) layoutHelper.getValue(this); } 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); } public long getAccessFlags() { return accessFlags.getValue(this); }
// Convenience routine // Convenience routine
public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); } public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); }
@ -162,7 +170,7 @@ public class Klass extends Oop implements ClassConstants {
visitor.doOop(javaMirror, true); visitor.doOop(javaMirror, true);
visitor.doOop(superField, true); visitor.doOop(superField, true);
visitor.doInt(layoutHelper, true); visitor.doInt(layoutHelper, true);
visitor.doOop(name, true); // visitor.doOop(name, true);
visitor.doCInt(accessFlags, true); visitor.doCInt(accessFlags, true);
visitor.doOop(subklass, true); visitor.doOop(subklass, true);
visitor.doOop(nextSibling, true); visitor.doOop(nextSibling, true);

View File

@ -196,11 +196,11 @@ public class Method extends Oop {
public Address getFromCompiledCodeEntryPoint() { return fromCompiledCodeEntryPointField.getValue(this); } public Address getFromCompiledCodeEntryPoint() { return fromCompiledCodeEntryPointField.getValue(this); }
*/ */
// Accessors // Accessors
public Symbol getName() { return (Symbol) getConstants().getObjAt(getNameIndex()); } public Symbol getName() { return getConstants().getSymbolAt(getNameIndex()); }
public Symbol getSignature() { return (Symbol) getConstants().getObjAt(getSignatureIndex()); } public Symbol getSignature() { return getConstants().getSymbolAt(getSignatureIndex()); }
public Symbol getGenericSignature() { public Symbol getGenericSignature() {
long index = getGenericSignatureIndex(); 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) // Method holder (the Klass holding this method)

View File

@ -47,7 +47,6 @@ public class ObjectHeap {
DEBUG = System.getProperty("sun.jvm.hotspot.oops.ObjectHeap.DEBUG") != null; DEBUG = System.getProperty("sun.jvm.hotspot.oops.ObjectHeap.DEBUG") != null;
} }
private OopHandle symbolKlassHandle;
private OopHandle methodKlassHandle; private OopHandle methodKlassHandle;
private OopHandle constMethodKlassHandle; private OopHandle constMethodKlassHandle;
private OopHandle methodDataKlassHandle; private OopHandle methodDataKlassHandle;
@ -68,7 +67,6 @@ public class ObjectHeap {
private OopHandle arrayKlassKlassHandle; private OopHandle arrayKlassKlassHandle;
private OopHandle compiledICHolderKlassHandle; private OopHandle compiledICHolderKlassHandle;
private SymbolKlass symbolKlassObj;
private MethodKlass methodKlassObj; private MethodKlass methodKlassObj;
private ConstMethodKlass constMethodKlassObj; private ConstMethodKlass constMethodKlassObj;
private MethodDataKlass methodDataKlassObj; private MethodDataKlass methodDataKlassObj;
@ -93,9 +91,6 @@ public class ObjectHeap {
// Lookup the roots in the object hierarchy. // Lookup the roots in the object hierarchy.
Type universeType = db.lookupType("Universe"); Type universeType = db.lookupType("Universe");
symbolKlassHandle = universeType.getOopField("_symbolKlassObj").getValue();
symbolKlassObj = new SymbolKlass(symbolKlassHandle, this);
methodKlassHandle = universeType.getOopField("_methodKlassObj").getValue(); methodKlassHandle = universeType.getOopField("_methodKlassObj").getValue();
methodKlassObj = new MethodKlass(methodKlassHandle, this); methodKlassObj = new MethodKlass(methodKlassHandle, this);
@ -199,7 +194,6 @@ public class ObjectHeap {
public long getDoubleSize() { return doubleSize; } public long getDoubleSize() { return doubleSize; }
// Accessors for well-known system classes (from Universe) // Accessors for well-known system classes (from Universe)
public SymbolKlass getSymbolKlassObj() { return symbolKlassObj; }
public MethodKlass getMethodKlassObj() { return methodKlassObj; } public MethodKlass getMethodKlassObj() { return methodKlassObj; }
public ConstMethodKlass getConstMethodKlassObj() { return constMethodKlassObj; } public ConstMethodKlass getConstMethodKlassObj() { return constMethodKlassObj; }
public MethodDataKlass getMethodDataKlassObj() { return methodDataKlassObj; } public MethodDataKlass getMethodDataKlassObj() { return methodDataKlassObj; }
@ -337,7 +331,6 @@ public class ObjectHeap {
// First check if handle is one of the root objects // First check if handle is one of the root objects
if (handle.equals(methodKlassHandle)) return getMethodKlassObj(); if (handle.equals(methodKlassHandle)) return getMethodKlassObj();
if (handle.equals(constMethodKlassHandle)) return getConstMethodKlassObj(); if (handle.equals(constMethodKlassHandle)) return getConstMethodKlassObj();
if (handle.equals(symbolKlassHandle)) return getSymbolKlassObj();
if (handle.equals(constantPoolKlassHandle)) return getConstantPoolKlassObj(); if (handle.equals(constantPoolKlassHandle)) return getConstantPoolKlassObj();
if (handle.equals(constantPoolCacheKlassHandle)) return getConstantPoolCacheKlassObj(); if (handle.equals(constantPoolCacheKlassHandle)) return getConstantPoolCacheKlassObj();
if (handle.equals(instanceKlassKlassHandle)) return getInstanceKlassKlassObj(); if (handle.equals(instanceKlassKlassHandle)) return getInstanceKlassKlassObj();
@ -363,7 +356,6 @@ public class ObjectHeap {
if (klass != null) { if (klass != null) {
if (klass.equals(methodKlassHandle)) return new Method(handle, this); if (klass.equals(methodKlassHandle)) return new Method(handle, this);
if (klass.equals(constMethodKlassHandle)) return new ConstMethod(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(constantPoolKlassHandle)) return new ConstantPool(handle, this);
if (klass.equals(constantPoolCacheKlassHandle)) return new ConstantPoolCache(handle, this); if (klass.equals(constantPoolCacheKlassHandle)) return new ConstantPoolCache(handle, this);
if (!VM.getVM().isCore()) { if (!VM.getVM().isCore()) {

View File

@ -34,7 +34,7 @@ import sun.jvm.hotspot.utilities.*;
// A Symbol is a canonicalized string. // A Symbol is a canonicalized string.
// All Symbols reside in global symbolTable. // All Symbols reside in global symbolTable.
public class Symbol extends Oop { public class Symbol extends VMObject {
static { static {
VM.registerVMInitializedObserver(new Observer() { VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) { public void update(Observable o, Object data) {
@ -44,9 +44,10 @@ public class Symbol extends Oop {
} }
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("symbolOopDesc"); Type type = db.lookupType("Symbol");
length = new CIntField(type.getCIntegerField("_length"), 0); length = type.getCIntegerField("_length");
baseOffset = type.getField("_body").getOffset(); baseOffset = type.getField("_body").getOffset();
idHash = type.getCIntegerField("_identity_hash");
} }
// Format: // Format:
@ -55,8 +56,15 @@ public class Symbol extends Oop {
// [length] byte size of uft8 string // [length] byte size of uft8 string
// ..body.. // ..body..
Symbol(OopHandle handle, ObjectHeap heap) { public static Symbol create(Address addr) {
super(handle, heap); if (addr == null) {
return null;
}
return new Symbol(addr);
}
Symbol(Address addr) {
super(addr);
} }
public boolean isSymbol() { return true; } public boolean isSymbol() { return true; }
@ -64,15 +72,19 @@ public class Symbol extends Oop {
private static long baseOffset; // tells where the array part starts private static long baseOffset; // tells where the array part starts
// Fields // Fields
private static CIntField length; private static CIntegerField length;
// Accessors for declared fields // Accessors for declared fields
public long getLength() { return length.getValue(this); } public long getLength() { return length.getValue(this.addr); }
public byte getByteAt(long index) { 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) { public boolean equals(byte[] modUTF8Chars) {
int l = (int) getLength(); int l = (int) getLength();
if (l != modUTF8Chars.length) return false; if (l != modUTF8Chars.length) return false;
@ -98,7 +110,9 @@ public class Symbol extends Oop {
// Decode the byte array and return the string. // Decode the byte array and return the string.
try { try {
return readModifiedUTF8(asByteArray()); return readModifiedUTF8(asByteArray());
} catch(IOException e) { } catch(Exception e) {
System.err.println(addr);
e.printStackTrace();
return null; return null;
} }
} }
@ -111,28 +125,13 @@ public class Symbol extends Oop {
tty.print("#" + asString()); 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 /** Note: this comparison is used for vtable sorting only; it
doesn't matter what order it defines, as long as it is a total, 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 relative order in memory never changes, so use address
comparison for speed. */ comparison for speed. */
public int fastCompare(Symbol other) { 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 { private static String readModifiedUTF8(byte[] buf) throws IOException {

View File

@ -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");
}
}

View File

@ -229,7 +229,7 @@ public class ClassWriter implements /* imports */ ClassConstants
case JVM_CONSTANT_Class: { case JVM_CONSTANT_Class: {
dos.writeByte(cpConstType); dos.writeByte(cpConstType);
// Klass already resolved. ConstantPool constains klassOop. // Klass already resolved. ConstantPool constains klassOop.
Klass refKls = (Klass) cpool.getObjAt(ci); Klass refKls = (Klass) cpool.getObjAtRaw(ci);
String klassName = refKls.getName().asString(); String klassName = refKls.getName().asString();
Short s = (Short) utf8ToIndex.get(klassName); Short s = (Short) utf8ToIndex.get(klassName);
@ -255,7 +255,7 @@ public class ClassWriter implements /* imports */ ClassConstants
case JVM_CONSTANT_String: { case JVM_CONSTANT_String: {
dos.writeByte(cpConstType); dos.writeByte(cpConstType);
String str = OopUtilities.stringOopToString(cpool.getObjAt(ci)); String str = OopUtilities.stringOopToString(cpool.getObjAtRaw(ci));
Short s = (Short) utf8ToIndex.get(str); Short s = (Short) utf8ToIndex.get(str);
dos.writeShort(s.shortValue()); dos.writeShort(s.shortValue());
if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);

View File

@ -56,7 +56,7 @@ import sun.jvm.hotspot.debugger.*;
</PRE> </PRE>
FIXME: among other things, this interface is not sufficient to 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]). */ jbyte _body[1]). */
public interface Field { public interface Field {
/** Get the name of this field */ /** Get the name of this field */

View File

@ -530,7 +530,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
case JVM_CONSTANT_Class: case JVM_CONSTANT_Class:
buf.cell("JVM_CONSTANT_Class"); buf.cell("JVM_CONSTANT_Class");
Klass klass = (Klass) cpool.getObjAt(index); Klass klass = (Klass) cpool.getObjAtRaw(index);
if (klass instanceof InstanceKlass) { if (klass instanceof InstanceKlass) {
buf.cell(genKlassLink((InstanceKlass) klass)); buf.cell(genKlassLink((InstanceKlass) klass));
} else { } else {
@ -555,7 +555,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
case JVM_CONSTANT_String: case JVM_CONSTANT_String:
buf.cell("JVM_CONSTANT_String"); buf.cell("JVM_CONSTANT_String");
buf.cell("\"" + buf.cell("\"" +
escapeHTMLSpecialChars(OopUtilities.stringOopToString(cpool.getObjAt(index))) + "\""); escapeHTMLSpecialChars(OopUtilities.stringOopToString(cpool.getObjAtRaw(index))) + "\"");
break; break;
case JVM_CONSTANT_Fieldref: case JVM_CONSTANT_Fieldref:
@ -672,11 +672,11 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
buf.beginTag("ul"); buf.beginTag("ul");
for (int exp = 0; exp < exceptions.length; exp++) { for (int exp = 0; exp < exceptions.length; exp++) {
short cpIndex = (short) exceptions[exp].getClassCPIndex(); short cpIndex = (short) exceptions[exp].getClassCPIndex();
Oop obj = cpool.getObjAt(cpIndex); ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
if (obj instanceof Symbol) { if (obj.isMetaData()) {
buf.li(((Symbol)obj).asString().replace('/', '.')); buf.li((obj.getSymbol()).asString().replace('/', '.'));
} else { } else {
buf.li(genKlassLink((InstanceKlass)obj)); buf.li(genKlassLink((InstanceKlass)obj.getOop()));
} }
} }
buf.endTag("ul"); buf.endTag("ul");
@ -756,7 +756,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
} else if (instr instanceof BytecodeLoadConstant) { } else if (instr instanceof BytecodeLoadConstant) {
BytecodeLoadConstant ldc = (BytecodeLoadConstant) instr; BytecodeLoadConstant ldc = (BytecodeLoadConstant) instr;
if (ldc.isKlassConstant()) { if (ldc.isKlassConstant()) {
Oop oop = ldc.getKlass(); Object oop = ldc.getKlass();
if (oop instanceof Klass) { if (oop instanceof Klass) {
buf.append("<a href='"); buf.append("<a href='");
buf.append(genKlassHref((InstanceKlass) oop)); buf.append(genKlassHref((InstanceKlass) oop));
@ -803,13 +803,13 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
buf.cell(Integer.toString(exceptionTable.getIntAt(e + 1))); buf.cell(Integer.toString(exceptionTable.getIntAt(e + 1)));
buf.cell(Integer.toString(exceptionTable.getIntAt(e + 2))); buf.cell(Integer.toString(exceptionTable.getIntAt(e + 2)));
short cpIndex = (short) exceptionTable.getIntAt(e + 3); short cpIndex = (short) exceptionTable.getIntAt(e + 3);
Oop obj = cpIndex == 0? null : cpool.getObjAt(cpIndex); ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
if (obj == null) { if (obj == null) {
buf.cell("Any"); buf.cell("Any");
} else if (obj instanceof Symbol) { } else if (obj.isMetaData()) {
buf.cell(((Symbol)obj).asString().replace('/', '.')); buf.cell(obj.getSymbol().asString().replace('/', '.'));
} else { } else {
buf.cell(genKlassLink((InstanceKlass)obj)); buf.cell(genKlassLink((InstanceKlass)obj.getOop()));
} }
buf.endTag("tr"); buf.endTag("tr");
} }

View File

@ -40,7 +40,7 @@ public class Hashtable extends BasicHashtable {
private static synchronized void initialize(TypeDataBase db) { private static synchronized void initialize(TypeDataBase db) {
// just to confirm that type exists // just to confirm that type exists
Type type = db.lookupType("Hashtable"); Type type = db.lookupType("Hashtable<intptr_t>");
} }
// derived class may return Class<? extends HashtableEntry> // derived class may return Class<? extends HashtableEntry>

View File

@ -41,16 +41,16 @@ public class HashtableEntry extends BasicHashtableEntry {
} }
private static synchronized void initialize(TypeDataBase db) { private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("HashtableEntry"); Type type = db.lookupType("HashtableEntry<intptr_t>");
literalField = type.getOopField("_literal"); literalField = type.getAddressField("_literal");
} }
// Fields // Fields
private static OopField literalField; private static AddressField literalField;
// Accessors // Accessors
public Oop literal() { public Address literalValue() {
return VM.getVM().getObjectHeap().newOop(literalField.getValue(addr)); return literalField.getValue(addr);
} }
public HashtableEntry(Address addr) { public HashtableEntry(Address addr) {

View File

@ -740,7 +740,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
for (Iterator itr = fields.iterator(); itr.hasNext();) { for (Iterator itr = fields.iterator(); itr.hasNext();) {
Field field = (Field) itr.next(); Field field = (Field) itr.next();
Symbol name = symTbl.probe(field.getID().getName()); Symbol name = symTbl.probe(field.getID().getName());
writeObjectID(name); writeSymbolID(name);
char typeCode = (char) field.getSignature().getByteAt(0); char typeCode = (char) field.getSignature().getByteAt(0);
int kind = signatureToHprofKind(typeCode); int kind = signatureToHprofKind(typeCode);
out.writeByte((byte)kind); out.writeByte((byte)kind);
@ -852,7 +852,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
private void writeSymbol(Symbol sym) throws IOException { private void writeSymbol(Symbol sym) throws IOException {
byte[] buf = sym.asString().getBytes("UTF-8"); byte[] buf = sym.asString().getBytes("UTF-8");
writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE); writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE);
writeObjectID(sym); writeSymbolID(sym);
out.write(buf); out.write(buf);
} }
@ -869,7 +869,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
out.writeInt(serialNum); out.writeInt(serialNum);
writeObjectID(clazz); writeObjectID(clazz);
out.writeInt(DUMMY_STACK_TRACE_ID); out.writeInt(DUMMY_STACK_TRACE_ID);
writeObjectID(k.getName()); writeSymbolID(k.getName());
serialNum++; serialNum++;
} catch (IOException exp) { } catch (IOException exp) {
throw new RuntimeException(exp); throw new RuntimeException(exp);
@ -901,6 +901,10 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
writeObjectID(address); writeObjectID(address);
} }
private void writeSymbolID(Symbol sym) throws IOException {
writeObjectID(getAddressValue(sym.getAddress()));
}
private void writeObjectID(long address) throws IOException { private void writeObjectID(long address) throws IOException {
if (OBJ_ID_SIZE == 4) { if (OBJ_ID_SIZE == 4) {
out.writeInt((int) address); out.writeInt((int) address);

View File

@ -33,9 +33,9 @@
# Don't put quotes (fail windows build). # Don't put quotes (fail windows build).
HOTSPOT_VM_COPYRIGHT=Copyright 2011 HOTSPOT_VM_COPYRIGHT=Copyright 2011
HS_MAJOR_VER=20 HS_MAJOR_VER=21
HS_MINOR_VER=0 HS_MINOR_VER=0
HS_BUILD_NUMBER=07 HS_BUILD_NUMBER=01
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=7 JDK_MINOR_VER=7

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -129,27 +129,6 @@ void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
} }
// 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 // Implementation of NewInstanceStub
NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) { NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {

View File

@ -710,7 +710,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
case throw_array_store_exception_id: case throw_array_store_exception_id:
{ {
__ set_info("throw_array_store_exception", dont_gc_arguments); __ 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; break;

View File

@ -2541,7 +2541,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
in_sig_bt[i++] = bt; // Collect remaining bits of signature in_sig_bt[i++] = bt; // Collect remaining bits of signature
out_sig_bt[total_c_args++] = bt; out_sig_bt[total_c_args++] = bt;
if( bt == T_OBJECT) { if( bt == T_OBJECT) {
symbolOop s = ss.as_symbol_or_null(); Symbol* s = ss.as_symbol_or_null();
if (s == vmSymbols::java_lang_String()) { if (s == vmSymbols::java_lang_String()) {
total_strings++; total_strings++;
out_sig_bt[total_c_args-1] = T_ADDRESS; out_sig_bt[total_c_args-1] = T_ADDRESS;

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -411,20 +411,6 @@ void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
} }
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) { void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
//---------------slow case: call to native----------------- //---------------slow case: call to native-----------------
__ bind(_entry); __ bind(_entry);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -733,8 +733,8 @@ void LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
// generate compare-and-swap; produces zero condition if swap occurs // generate compare-and-swap; produces zero condition if swap occurs
int value_offset = sun_misc_AtomicLongCSImpl::value_offset(); int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
LIR_Opr addr = obj.result(); LIR_Opr addr = new_pointer_register();
__ add(addr, LIR_OprFact::intConst(value_offset), addr); __ 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 t1 = LIR_OprFact::illegalOpr; // no temp needed
LIR_Opr t2 = 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); __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);

View File

@ -1337,7 +1337,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
{ StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments); { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
// tos + 0: link // tos + 0: link
// + 1: return address // + 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; break;

View File

@ -1974,7 +1974,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
in_sig_bt[i++] = bt; // Collect remaining bits of signature in_sig_bt[i++] = bt; // Collect remaining bits of signature
out_sig_bt[total_c_args++] = bt; out_sig_bt[total_c_args++] = bt;
if( bt == T_OBJECT) { 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()) { if (s == vmSymbols::java_lang_String()) {
total_strings++; total_strings++;
out_sig_bt[total_c_args-1] = T_ADDRESS; out_sig_bt[total_c_args-1] = T_ADDRESS;

View File

@ -1980,7 +1980,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm,
in_sig_bt[i++] = bt; // Collect remaining bits of signature in_sig_bt[i++] = bt; // Collect remaining bits of signature
out_sig_bt[total_c_args++] = bt; out_sig_bt[total_c_args++] = bt;
if( bt == T_OBJECT) { 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()) { if (s == vmSymbols::java_lang_String()) {
total_strings++; total_strings++;
out_sig_bt[total_c_args-1] = T_ADDRESS; out_sig_bt[total_c_args-1] = T_ADDRESS;

View File

@ -49,7 +49,7 @@
#include "oops/klass.hpp" #include "oops/klass.hpp"
#include "oops/methodOop.hpp" #include "oops/methodOop.hpp"
#include "oops/oop.hpp" #include "oops/oop.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
#include "runtime/virtualspace.hpp" #include "runtime/virtualspace.hpp"
#include "runtime/vmStructs.hpp" #include "runtime/vmStructs.hpp"
#include "utilities/accessFlags.hpp" #include "utilities/accessFlags.hpp"
@ -215,8 +215,8 @@ int generateJvmOffsets(GEN_variant gen_variant) {
GEN_VALUE(AccessFlags_NATIVE, JVM_ACC_NATIVE); GEN_VALUE(AccessFlags_NATIVE, JVM_ACC_NATIVE);
GEN_VALUE(constMethodOopDesc_has_linenumber_table, constMethodOopDesc::_has_linenumber_table); GEN_VALUE(constMethodOopDesc_has_linenumber_table, constMethodOopDesc::_has_linenumber_table);
GEN_OFFS(AccessFlags, _flags); GEN_OFFS(AccessFlags, _flags);
GEN_OFFS(symbolOopDesc, _length); GEN_OFFS(Symbol, _length);
GEN_OFFS(symbolOopDesc, _body); GEN_OFFS(Symbol, _body);
printf("\n"); printf("\n");
GEN_OFFS(methodOopDesc, _constMethod); GEN_OFFS(methodOopDesc, _constMethod);

View File

@ -114,8 +114,8 @@ dtrace:helper:ustack:
copyin_offset(OFFSET_HeapBlockHeader_used); copyin_offset(OFFSET_HeapBlockHeader_used);
copyin_offset(OFFSET_oopDesc_metadata); copyin_offset(OFFSET_oopDesc_metadata);
copyin_offset(OFFSET_symbolOopDesc_length); copyin_offset(OFFSET_Symbol_length);
copyin_offset(OFFSET_symbolOopDesc_body); copyin_offset(OFFSET_Symbol_body);
copyin_offset(OFFSET_methodOopDesc_constMethod); copyin_offset(OFFSET_methodOopDesc_constMethod);
copyin_offset(OFFSET_methodOopDesc_constants); copyin_offset(OFFSET_methodOopDesc_constants);
@ -366,13 +366,13 @@ dtrace:helper:ustack:
this->nameIndex * sizeof (pointer) + SIZE_constantPoolOopDesc); this->nameIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
this->nameSymbolLength = copyin_uint16(this->nameSymbol + this->nameSymbolLength = copyin_uint16(this->nameSymbol +
OFFSET_symbolOopDesc_length); OFFSET_Symbol_length);
this->signatureSymbol = copyin_ptr(this->constantPool + this->signatureSymbol = copyin_ptr(this->constantPool +
this->signatureIndex * sizeof (pointer) + SIZE_constantPoolOopDesc); this->signatureIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
this->signatureSymbolLength = copyin_uint16(this->signatureSymbol + this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
OFFSET_symbolOopDesc_length); OFFSET_Symbol_length);
this->klassPtr = copyin_ptr(this->constantPool + this->klassPtr = copyin_ptr(this->constantPool +
OFFSET_constantPoolOopDesc_pool_holder); OFFSET_constantPoolOopDesc_pool_holder);
@ -381,7 +381,7 @@ dtrace:helper:ustack:
OFFSET_Klass_name + SIZE_oopDesc); OFFSET_Klass_name + SIZE_oopDesc);
this->klassSymbolLength = copyin_uint16(this->klassSymbol + this->klassSymbolLength = copyin_uint16(this->klassSymbol +
OFFSET_symbolOopDesc_length); OFFSET_Symbol_length);
/* /*
* Enough for three strings, plus the '.', plus the trailing '\0'. * Enough for three strings, plus the '.', plus the trailing '\0'.
@ -390,7 +390,7 @@ dtrace:helper:ustack:
this->nameSymbolLength + this->nameSymbolLength +
this->signatureSymbolLength + 2 + 1); this->signatureSymbolLength + 2 + 1);
copyinto(this->klassSymbol + OFFSET_symbolOopDesc_body, copyinto(this->klassSymbol + OFFSET_Symbol_body,
this->klassSymbolLength, this->result); this->klassSymbolLength, this->result);
/* /*
@ -398,11 +398,11 @@ dtrace:helper:ustack:
*/ */
this->result[this->klassSymbolLength] = '.'; this->result[this->klassSymbolLength] = '.';
copyinto(this->nameSymbol + OFFSET_symbolOopDesc_body, copyinto(this->nameSymbol + OFFSET_Symbol_body,
this->nameSymbolLength, this->nameSymbolLength,
this->result + this->klassSymbolLength + 1); this->result + this->klassSymbolLength + 1);
copyinto(this->signatureSymbol + OFFSET_symbolOopDesc_body, copyinto(this->signatureSymbol + OFFSET_Symbol_body,
this->signatureSymbolLength, this->signatureSymbolLength,
this->result + this->klassSymbolLength + this->result + this->klassSymbolLength +
this->nameSymbolLength + 1); this->nameSymbolLength + 1);

View File

@ -524,10 +524,10 @@ name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t
CHECK_FAIL(err); CHECK_FAIL(err);
err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &nameSymbol); err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &nameSymbol);
CHECK_FAIL(err); 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); CHECK_FAIL(err);
nameString = (char*)calloc(nameSymbolLength + 1, 1); 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); CHECK_FAIL(err);
/* To get signature string */ /* To get signature string */
@ -535,10 +535,10 @@ name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t
CHECK_FAIL(err); CHECK_FAIL(err);
err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol); err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol);
CHECK_FAIL(err); 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); CHECK_FAIL(err);
signatureString = (char*)calloc(signatureSymbolLength + 1, 1); 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); CHECK_FAIL(err);
/* To get klass string */ /* To get klass string */
@ -546,10 +546,10 @@ name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t
CHECK_FAIL(err); CHECK_FAIL(err);
err = read_pointer(J, klassPtr + OFFSET_Klass_name + SIZE_oopDesc, &klassSymbol); err = read_pointer(J, klassPtr + OFFSET_Klass_name + SIZE_oopDesc, &klassSymbol);
CHECK_FAIL(err); 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); CHECK_FAIL(err);
klassString = (char*)calloc(klassSymbolLength + 1, 1); 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); CHECK_FAIL(err);
result[0] = '\0'; result[0] = '\0';

View File

@ -142,7 +142,7 @@ int DTraceJSDT::pd_activate(
++strcount; ++strcount;
for(int prbc = 0; prbc < provider->probe_count; ++prbc) { for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
JVM_DTraceProbe* p = &(provider->probes[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 // function + name + one per argument
strcount += 2 + ArgumentCount(sig).size(); strcount += 2 + ArgumentCount(sig).size();
} }
@ -178,7 +178,7 @@ int DTraceJSDT::pd_activate(
stroffs[curstr++] = string_index; stroffs[curstr++] = string_index;
string_index += strlen(name) + 1; 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); SignatureStream ss(sig);
for ( ; !ss.at_return_type(); ss.next()) { for ( ; !ss.at_return_type(); ss.next()) {
BasicType bt = ss.type(); BasicType bt = ss.type();
@ -227,7 +227,7 @@ int DTraceJSDT::pd_activate(
uint32_t argscount = 0; uint32_t argscount = 0;
for(int prbc = 0; prbc < provider->probe_count; ++prbc) { for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
JVM_DTraceProbe* p = &(provider->probes[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(); argscount += ArgumentCount(sig).size();
} }
secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]); secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]);
@ -298,7 +298,7 @@ int DTraceJSDT::pd_activate(
strcpy(str, name); strcpy(str, name);
str += strlen(name) + 1; 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); SignatureStream ss(sig);
for ( ; !ss.at_return_type(); ss.next()) { for ( ; !ss.at_return_type(); ss.next()) {
BasicType bt = ss.type(); BasicType bt = ss.type();
@ -433,7 +433,7 @@ int DTraceJSDT::pd_activate(
uint8_t* par = (uint8_t*)(dof + sec->dofs_offset); uint8_t* par = (uint8_t*)(dof + sec->dofs_offset);
for (int prbc = 0; prbc < provider->probe_count; ++prbc) { for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
JVM_DTraceProbe* p = &(provider->probes[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(); uint8_t count = (uint8_t)ArgumentCount(sig).size();
for (uint8_t i = 0; i < count; ++i) { for (uint8_t i = 0; i < count; ++i) {
*par++ = i; *par++ = i;

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -898,4 +898,4 @@ void Canonicalizer::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {}
void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
void Canonicalizer::do_ProfileCall(ProfileCall* x) {} void Canonicalizer::do_ProfileCall(ProfileCall* x) {}
void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {} void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {}
void Canonicalizer::do_RuntimeCall(RuntimeCall* x) {}

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -102,6 +102,7 @@ class Canonicalizer: InstructionVisitor {
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileCall (ProfileCall* x);
virtual void do_ProfileInvoke (ProfileInvoke* x); virtual void do_ProfileInvoke (ProfileInvoke* x);
virtual void do_RuntimeCall (RuntimeCall* x);
}; };
#endif // SHARE_VM_C1_C1_CANONICALIZER_HPP #endif // SHARE_VM_C1_C1_CANONICALIZER_HPP

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -476,18 +476,12 @@ class SimpleExceptionStub: public CodeStub {
class ArrayStoreExceptionStub: public CodeStub { class ArrayStoreExceptionStub: public SimpleExceptionStub {
private: private:
CodeEmitInfo* _info; CodeEmitInfo* _info;
public: public:
ArrayStoreExceptionStub(CodeEmitInfo* info); ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, 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);
}
#ifndef PRODUCT #ifndef PRODUCT
virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); } virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); }
#endif // PRODUCT #endif // PRODUCT

View File

@ -1396,6 +1396,13 @@ void GraphBuilder::method_return(Value x) {
if (continuation() != NULL) { if (continuation() != NULL) {
assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet"); 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 // If the inlined method is synchronized, the monitor must be
// released before we jump to the continuation block. // released before we jump to the continuation block.
if (method()->is_synchronized()) { if (method()->is_synchronized()) {
@ -3301,6 +3308,13 @@ void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool
Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI); Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI);
assert(exception->is_pinned(), "must be"); 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; int bci = SynchronizationEntryBCI;
if (lock) { if (lock) {
assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing"); assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing");
@ -3486,6 +3500,11 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
inline_sync_entry(lock, sync_handler); 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); BlockBegin* callee_start_block = block_at(0);
if (callee_start_block != NULL) { if (callee_start_block != NULL) {

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -106,6 +106,7 @@ class UnsafePrefetchRead;
class UnsafePrefetchWrite; class UnsafePrefetchWrite;
class ProfileCall; class ProfileCall;
class ProfileInvoke; class ProfileInvoke;
class RuntimeCall;
// A Value is a reference to the instruction creating the value // A Value is a reference to the instruction creating the value
typedef Instruction* Value; typedef Instruction* Value;
@ -202,6 +203,7 @@ class InstructionVisitor: public StackObj {
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0;
virtual void do_ProfileCall (ProfileCall* x) = 0; virtual void do_ProfileCall (ProfileCall* x) = 0;
virtual void do_ProfileInvoke (ProfileInvoke* x) = 0; virtual void do_ProfileInvoke (ProfileInvoke* x) = 0;
virtual void do_RuntimeCall (RuntimeCall* x) = 0;
}; };
@ -2267,6 +2269,38 @@ LEAF(ProfileCall, Instruction)
virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); } 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 // Use to trip invocation counter of an inlined method
LEAF(ProfileInvoke, Instruction) LEAF(ProfileInvoke, Instruction)

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -841,4 +841,13 @@ void InstructionPrinter::do_ProfileInvoke(ProfileInvoke* x) {
} }
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 #endif // PRODUCT

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -131,6 +131,7 @@ class InstructionPrinter: public InstructionVisitor {
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileCall (ProfileCall* x);
virtual void do_ProfileInvoke (ProfileInvoke* x); virtual void do_ProfileInvoke (ProfileInvoke* x);
virtual void do_RuntimeCall (RuntimeCall* x);
}; };
#endif // PRODUCT #endif // PRODUCT

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -396,7 +396,7 @@ LIR_OpTypeCheck::LIR_OpTypeCheck(LIR_Code code, LIR_Opr object, LIR_Opr array, L
, _should_profile(false) , _should_profile(false)
{ {
if (code == lir_store_check) { 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"); assert(info_for_exception != NULL, "store_check throws exceptions");
} else { } else {
ShouldNotReachHere(); ShouldNotReachHere();

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -2741,6 +2741,31 @@ void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info,
} }
} }
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) { LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
LIRItemList args(1); LIRItemList args(1);
LIRItem value(arg1, this); LIRItem value(arg1, this);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -522,6 +522,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileCall (ProfileCall* x);
virtual void do_ProfileInvoke (ProfileInvoke* x); virtual void do_ProfileInvoke (ProfileInvoke* x);
virtual void do_RuntimeCall (RuntimeCall* x);
}; };

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -496,6 +496,7 @@ public:
void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
void do_ProfileCall (ProfileCall* x); void do_ProfileCall (ProfileCall* x);
void do_ProfileInvoke (ProfileInvoke* x); void do_ProfileInvoke (ProfileInvoke* x);
void do_RuntimeCall (RuntimeCall* x);
}; };
@ -664,6 +665,7 @@ void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {}
void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); } void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); }
void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {} void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {}
void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {}
void NullCheckEliminator::visit(Value* p) { void NullCheckEliminator::visit(Value* p) {

View File

@ -339,8 +339,10 @@ JRT_ENTRY(void, Runtime1::unimplemented_entry(JavaThread* thread, StubID id))
JRT_END JRT_END
JRT_ENTRY(void, Runtime1::throw_array_store_exception(JavaThread* thread)) JRT_ENTRY(void, Runtime1::throw_array_store_exception(JavaThread* thread, oopDesc* obj))
THROW(vmSymbolHandles::java_lang_ArrayStoreException()); 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 JRT_END

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -143,9 +143,9 @@ class Runtime1: public AllStatic {
static void throw_index_exception(JavaThread* thread, int index); static void throw_index_exception(JavaThread* thread, int index);
static void throw_div0_exception(JavaThread* thread); static void throw_div0_exception(JavaThread* thread);
static void throw_null_pointer_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_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 monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock);
static void monitorexit (JavaThread* thread, BasicObjectLock* lock); static void monitorexit (JavaThread* thread, BasicObjectLock* lock);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -192,11 +192,12 @@ class ValueNumberingVisitor: public InstructionVisitor {
void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ } void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }
void do_RoundFP (RoundFP* x) { /* nothing to do */ } void do_RoundFP (RoundFP* x) { /* nothing to do */ }
void do_UnsafeGetRaw (UnsafeGetRaw* 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_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }
void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ } void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ }
void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ } void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }
void do_ProfileCall (ProfileCall* 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 */ };
}; };

View File

@ -233,6 +233,10 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod*
// compute size of arguments // compute size of arguments
int arg_size = target->arg_size(); 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) { if (!target->is_loaded() && code == Bytecodes::_invokestatic) {
arg_size--; arg_size--;
} }
@ -250,6 +254,10 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod*
ArgumentMap arg = state._stack[i]; ArgumentMap arg = state._stack[i];
skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base)); 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) { if (skip_callee) {
TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8())); 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++) { for (i = 0; i < arg_size; i++) {

View File

@ -60,7 +60,6 @@ class ciReturnAddress;
class ciKlass; class ciKlass;
class ciInstanceKlass; class ciInstanceKlass;
class ciMethodKlass; class ciMethodKlass;
class ciSymbolKlass;
class ciArrayKlass; class ciArrayKlass;
class ciObjArrayKlass; class ciObjArrayKlass;
class ciTypeArrayKlass; class ciTypeArrayKlass;
@ -112,7 +111,6 @@ friend class ciReturnAddress; \
friend class ciKlass; \ friend class ciKlass; \
friend class ciInstanceKlass; \ friend class ciInstanceKlass; \
friend class ciMethodKlass; \ friend class ciMethodKlass; \
friend class ciSymbolKlass; \
friend class ciArrayKlass; \ friend class ciArrayKlass; \
friend class ciObjArrayKlass; \ friend class ciObjArrayKlass; \
friend class ciTypeArrayKlass; \ friend class ciTypeArrayKlass; \

View File

@ -68,7 +68,6 @@
ciObject* ciEnv::_null_object_instance; ciObject* ciEnv::_null_object_instance;
ciMethodKlass* ciEnv::_method_klass_instance; ciMethodKlass* ciEnv::_method_klass_instance;
ciSymbolKlass* ciEnv::_symbol_klass_instance;
ciKlassKlass* ciEnv::_klass_klass_instance; ciKlassKlass* ciEnv::_klass_klass_instance;
ciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance; ciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance;
ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance; ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance;
@ -202,6 +201,7 @@ ciEnv::ciEnv(Arena* arena) {
ciEnv::~ciEnv() { ciEnv::~ciEnv() {
CompilerThread* current_thread = CompilerThread::current(); CompilerThread* current_thread = CompilerThread::current();
_factory->remove_symbols();
current_thread->set_env(NULL); current_thread->set_env(NULL);
} }
@ -234,7 +234,7 @@ void ciEnv::cache_dtrace_flags() {
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// helper for lazy exception creation // 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; VM_ENTRY_MARK;
if (handle == NULL) { if (handle == NULL) {
// Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance. // Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance.
@ -261,7 +261,7 @@ ciInstance* ciEnv::ArrayIndexOutOfBoundsException_instance() {
if (_ArrayIndexOutOfBoundsException_instance == NULL) { if (_ArrayIndexOutOfBoundsException_instance == NULL) {
_ArrayIndexOutOfBoundsException_instance _ArrayIndexOutOfBoundsException_instance
= get_or_create_exception(_ArrayIndexOutOfBoundsException_handle, = get_or_create_exception(_ArrayIndexOutOfBoundsException_handle,
vmSymbolHandles::java_lang_ArrayIndexOutOfBoundsException()); vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
} }
return _ArrayIndexOutOfBoundsException_instance; return _ArrayIndexOutOfBoundsException_instance;
} }
@ -269,7 +269,7 @@ ciInstance* ciEnv::ArrayStoreException_instance() {
if (_ArrayStoreException_instance == NULL) { if (_ArrayStoreException_instance == NULL) {
_ArrayStoreException_instance _ArrayStoreException_instance
= get_or_create_exception(_ArrayStoreException_handle, = get_or_create_exception(_ArrayStoreException_handle,
vmSymbolHandles::java_lang_ArrayStoreException()); vmSymbols::java_lang_ArrayStoreException());
} }
return _ArrayStoreException_instance; return _ArrayStoreException_instance;
} }
@ -277,7 +277,7 @@ ciInstance* ciEnv::ClassCastException_instance() {
if (_ClassCastException_instance == NULL) { if (_ClassCastException_instance == NULL) {
_ClassCastException_instance _ClassCastException_instance
= get_or_create_exception(_ClassCastException_handle, = get_or_create_exception(_ClassCastException_handle,
vmSymbolHandles::java_lang_ClassCastException()); vmSymbols::java_lang_ClassCastException());
} }
return _ClassCastException_instance; return _ClassCastException_instance;
} }
@ -377,14 +377,16 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
EXCEPTION_CONTEXT; EXCEPTION_CONTEXT;
// Now we need to check the SystemDictionary // Now we need to check the SystemDictionary
symbolHandle sym(THREAD, name->get_symbolOop()); Symbol* sym = name->get_symbol();
if (sym->byte_at(0) == 'L' && if (sym->byte_at(0) == 'L' &&
sym->byte_at(sym->utf8_length()-1) == ';') { sym->byte_at(sym->utf8_length()-1) == ';') {
// This is a name from a signature. Strip off the trimmings. // This is a name from a signature. Strip off the trimmings.
sym = oopFactory::new_symbol_handle(sym->as_utf8()+1, // Call recursive to keep scope of strippedsym.
sym->utf8_length()-2, TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); sym->utf8_length()-2,
name = get_object(sym())->as_symbol(); 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 // Check for prior unloaded klass. The SystemDictionary's answers
@ -430,13 +432,14 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
(sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) {
// We have an unloaded array. // We have an unloaded array.
// Build it on the fly if the element class exists. // Build it on the fly if the element class exists.
symbolOop elem_sym = oopFactory::new_symbol(sym->as_utf8()+1, TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
sym->utf8_length()-1, sym->utf8_length()-1,
KILL_COMPILE_ON_FATAL_(fail_type)); KILL_COMPILE_ON_FATAL_(fail_type));
// Get element ciKlass recursively. // Get element ciKlass recursively.
ciKlass* elem_klass = ciKlass* elem_klass =
get_klass_by_name_impl(accessing_klass, get_klass_by_name_impl(accessing_klass,
get_object(elem_sym)->as_symbol(), get_symbol(elem_sym),
require_local); require_local);
if (elem_klass != NULL && elem_klass->is_loaded()) { if (elem_klass != NULL && elem_klass->is_loaded()) {
// Now make an array for it // Now make an array for it
@ -475,7 +478,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
ciInstanceKlass* accessor) { ciInstanceKlass* accessor) {
EXCEPTION_CONTEXT; EXCEPTION_CONTEXT;
KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index)); KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index));
symbolHandle klass_name; Symbol* klass_name = NULL;
if (klass.is_null()) { if (klass.is_null()) {
// The klass has not been inserted into the constant pool. // The klass has not been inserted into the constant pool.
// Try to look it up by name. // Try to look it up by name.
@ -490,10 +493,10 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
// very recently. // very recently.
klass = KlassHandle(THREAD, cpool->resolved_klass_at(index)); klass = KlassHandle(THREAD, cpool->resolved_klass_at(index));
} else if (tag.is_symbol()) { } else if (tag.is_symbol()) {
klass_name = symbolHandle(THREAD, cpool->symbol_at(index)); klass_name = cpool->symbol_at(index);
} else { } else {
assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag"); 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 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
if (klass.is_null()) { if (klass.is_null()) {
// Not found in constant pool. Use the name to do the lookup. // Not found in constant pool. Use the name to do the lookup.
ciKlass* k = get_klass_by_name_impl(accessor, ciKlass* k = get_klass_by_name_impl(accessor,
get_object(klass_name())->as_symbol(), get_symbol(klass_name),
false); false);
// Calculate accessibility the hard way. // Calculate accessibility the hard way.
if (!k->is_loaded()) { if (!k->is_loaded()) {
@ -519,7 +522,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
// Check for prior unloaded klass. The SystemDictionary's answers // Check for prior unloaded klass. The SystemDictionary's answers
// can vary over time but the compiler needs consistency. // 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); ciKlass* unloaded_klass = check_get_unloaded_klass(accessor, name);
if (unloaded_klass != NULL) { if (unloaded_klass != NULL) {
is_accessible = false; is_accessible = false;
@ -605,7 +608,7 @@ ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,
return ciConstant(T_OBJECT, ciobj); return ciConstant(T_OBJECT, ciobj);
} else if (tag.is_method_type()) { } else if (tag.is_method_type()) {
// must execute Java code to link this CP entry into cache[i].f1 // 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); ciObject* ciobj = get_unloaded_method_type_constant(signature);
return ciConstant(T_OBJECT, ciobj); return ciConstant(T_OBJECT, ciobj);
} else if (tag.is_method_handle()) { } else if (tag.is_method_handle()) {
@ -613,8 +616,8 @@ ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,
int ref_kind = cpool->method_handle_ref_kind_at(index); int ref_kind = cpool->method_handle_ref_kind_at(index);
int callee_index = cpool->method_handle_klass_index_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); 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* name = get_symbol(cpool->method_handle_name_ref_at(index));
ciSymbol* signature = get_object(cpool->method_handle_signature_ref_at(index))->as_symbol(); ciSymbol* signature = get_symbol(cpool->method_handle_signature_ref_at(index));
ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind); ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind);
return ciConstant(T_OBJECT, ciobj); return ciConstant(T_OBJECT, ciobj);
} else { } else {
@ -674,33 +677,31 @@ ciField* ciEnv::get_field_by_index(ciInstanceKlass* accessor,
// name, signature, and bytecode. // name, signature, and bytecode.
methodOop ciEnv::lookup_method(instanceKlass* accessor, methodOop ciEnv::lookup_method(instanceKlass* accessor,
instanceKlass* holder, instanceKlass* holder,
symbolOop name, Symbol* name,
symbolOop sig, Symbol* sig,
Bytecodes::Code bc) { Bytecodes::Code bc) {
EXCEPTION_CONTEXT; EXCEPTION_CONTEXT;
KlassHandle h_accessor(THREAD, accessor); KlassHandle h_accessor(THREAD, accessor);
KlassHandle h_holder(THREAD, holder); 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)); LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
methodHandle dest_method; methodHandle dest_method;
switch (bc) { switch (bc) {
case Bytecodes::_invokestatic: case Bytecodes::_invokestatic:
dest_method = 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; break;
case Bytecodes::_invokespecial: case Bytecodes::_invokespecial:
dest_method = 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; break;
case Bytecodes::_invokeinterface: case Bytecodes::_invokeinterface:
dest_method = 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); h_accessor, true);
break; break;
case Bytecodes::_invokevirtual: case Bytecodes::_invokevirtual:
dest_method = 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); h_accessor, true);
break; break;
default: ShouldNotReachHere(); default: ShouldNotReachHere();
@ -721,8 +722,8 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
// Get the method's name and signature. // Get the method's name and signature.
symbolOop name_sym = cpool->name_ref_at(index); Symbol* name_sym = cpool->name_ref_at(index);
symbolOop sig_sym = cpool->signature_ref_at(index); Symbol* sig_sym = cpool->signature_ref_at(index);
if (holder_is_accessible) { // Our declared holder is loaded. if (holder_is_accessible) { // Our declared holder is loaded.
instanceKlass* lookup = declared_holder->get_instanceKlass(); instanceKlass* lookup = declared_holder->get_instanceKlass();
@ -738,8 +739,8 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
// lookup. // lookup.
return get_unloaded_method(declared_holder, return get_unloaded_method(declared_holder,
get_object(name_sym)->as_symbol(), get_symbol(name_sym),
get_object(sig_sym)->as_symbol()); get_symbol(sig_sym));
} }
@ -759,7 +760,7 @@ ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
// compiler, but it is simpler to stop the code path here with an unlinked method. // compiler, but it is simpler to stop the code path here with an unlinked method.
if (!is_resolved) { if (!is_resolved) {
ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); 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); return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym);
} }

View File

@ -79,7 +79,6 @@ private:
// Distinguished instances of certain ciObjects.. // Distinguished instances of certain ciObjects..
static ciObject* _null_object_instance; static ciObject* _null_object_instance;
static ciMethodKlass* _method_klass_instance; static ciMethodKlass* _method_klass_instance;
static ciSymbolKlass* _symbol_klass_instance;
static ciKlassKlass* _klass_klass_instance; static ciKlassKlass* _klass_klass_instance;
static ciInstanceKlassKlass* _instance_klass_klass_instance; static ciInstanceKlassKlass* _instance_klass_klass_instance;
static ciTypeArrayKlassKlass* _type_array_klass_klass_instance; static ciTypeArrayKlassKlass* _type_array_klass_klass_instance;
@ -160,8 +159,8 @@ private:
klassOop resolved_klassOop); klassOop resolved_klassOop);
methodOop lookup_method(instanceKlass* accessor, methodOop lookup_method(instanceKlass* accessor,
instanceKlass* holder, instanceKlass* holder,
symbolOop name, Symbol* name,
symbolOop sig, Symbol* sig,
Bytecodes::Code bc); Bytecodes::Code bc);
// Get a ciObject from the object factory. Ensures uniqueness // Get a ciObject from the object factory. Ensures uniqueness
@ -174,9 +173,18 @@ private:
} }
} }
ciSymbol* get_symbol(Symbol* o) {
if (o == NULL) {
ShouldNotReachHere();
return NULL;
} else {
return _factory->get_symbol(o);
}
}
ciMethod* get_method_from_handle(jobject method); 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 // Get a ciMethod representing either an unfound method or
// a method with an unloaded holder. Ensures uniqueness of // a method with an unloaded holder. Ensures uniqueness of

View File

@ -79,15 +79,15 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with(NULL) {
constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants());
// Get the field's name, signature, and type. // Get the field's name, signature, and type.
symbolHandle name (thread, cpool->name_ref_at(index)); Symbol* name = cpool->name_ref_at(index);
_name = ciEnv::current(thread)->get_object(name())->as_symbol(); _name = ciEnv::current(thread)->get_symbol(name);
int nt_index = cpool->name_and_type_ref_index_at(index); int nt_index = cpool->name_and_type_ref_index_at(index);
int sig_index = cpool->signature_ref_index_at(nt_index); int sig_index = cpool->signature_ref_index_at(nt_index);
symbolHandle signature (thread, cpool->symbol_at(sig_index)); Symbol* signature = cpool->symbol_at(sig_index);
_signature = ciEnv::current(thread)->get_object(signature())->as_symbol(); _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 // If the field is a pointer type, get the klass of the
// field. // field.
@ -100,7 +100,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with(NULL) {
_type = ciType::make(field_type); _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. // Get the field's declared holder.
// //
@ -130,7 +130,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with(NULL) {
// Perform the field lookup. // Perform the field lookup.
fieldDescriptor field_desc; fieldDescriptor field_desc;
klassOop canonical_holder = 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) { if (canonical_holder == NULL) {
// Field lookup failed. Will be detected by will_link. // Field lookup failed. Will be detected by will_link.
_holder = declared_holder; _holder = declared_holder;
@ -150,8 +150,8 @@ ciField::ciField(fieldDescriptor *fd): _known_to_link_with(NULL) {
// Get the field's name, signature, and type. // Get the field's name, signature, and type.
ciEnv* env = CURRENT_ENV; ciEnv* env = CURRENT_ENV;
_name = env->get_object(fd->name())->as_symbol(); _name = env->get_symbol(fd->name());
_signature = env->get_object(fd->signature())->as_symbol(); _signature = env->get_symbol(fd->signature());
BasicType field_type = fd->field_type(); BasicType field_type = fd->field_type();

View File

@ -380,7 +380,7 @@ ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature,
VM_ENTRY_MARK; VM_ENTRY_MARK;
instanceKlass* k = get_instanceKlass(); instanceKlass* k = get_instanceKlass();
fieldDescriptor fd; 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) { if (def == NULL) {
return NULL; return NULL;
} }
@ -541,8 +541,8 @@ ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) {
VM_ENTRY_MARK; VM_ENTRY_MARK;
instanceKlass* k = get_instanceKlass(); instanceKlass* k = get_instanceKlass();
symbolOop name_sym = name->get_symbolOop(); Symbol* name_sym = name->get_symbol();
symbolOop sig_sym= signature->get_symbolOop(); Symbol* sig_sym= signature->get_symbol();
methodOop m = k->find_method(name_sym, sig_sym); methodOop m = k->find_method(name_sym, sig_sym);
if (m == NULL) return NULL; if (m == NULL) return NULL;

View File

@ -39,9 +39,9 @@ ciKlass::ciKlass(KlassHandle h_k) : ciType(h_k) {
assert(get_oop()->is_klass(), "wrong type"); assert(get_oop()->is_klass(), "wrong type");
Klass* k = get_Klass(); Klass* k = get_Klass();
_layout_helper = k->layout_helper(); _layout_helper = k->layout_helper();
symbolOop klass_name = k->name(); Symbol* klass_name = k->name();
assert(klass_name != NULL, "wrong ciKlass constructor"); assert(klass_name != NULL, "wrong ciKlass constructor");
_name = CURRENT_ENV->get_object(klass_name)->as_symbol(); _name = CURRENT_ENV->get_symbol(klass_name);
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------

View File

@ -122,9 +122,9 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
// generating _signature may allow GC and therefore move m. // generating _signature may allow GC and therefore move m.
// These fields are always filled in. // 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(); _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); _signature = new (env->arena()) ciSignature(_holder, sig_symbol);
_method_data = NULL; _method_data = NULL;
// Take a snapshot of these values, so they will be commensurate with the MDO. // Take a snapshot of these values, so they will be commensurate with the MDO.
@ -649,8 +649,8 @@ ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) {
KlassHandle caller_klass (THREAD, caller->get_klassOop()); KlassHandle caller_klass (THREAD, caller->get_klassOop());
KlassHandle h_recv (THREAD, exact_receiver->get_klassOop()); KlassHandle h_recv (THREAD, exact_receiver->get_klassOop());
KlassHandle h_resolved (THREAD, holder()->get_klassOop()); KlassHandle h_resolved (THREAD, holder()->get_klassOop());
symbolHandle h_name (THREAD, name()->get_symbolOop()); Symbol* h_name = name()->get_symbol();
symbolHandle h_signature (THREAD, signature()->get_symbolOop()); Symbol* h_signature = signature()->get_symbol();
methodHandle m; methodHandle m;
// Only do exact lookup if receiver klass has been linked. Otherwise, // Only do exact lookup if receiver klass has been linked. Otherwise,
@ -702,8 +702,8 @@ int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) {
KlassHandle caller_klass (THREAD, caller->get_klassOop()); KlassHandle caller_klass (THREAD, caller->get_klassOop());
KlassHandle h_recv (THREAD, receiver->get_klassOop()); KlassHandle h_recv (THREAD, receiver->get_klassOop());
symbolHandle h_name (THREAD, name()->get_symbolOop()); Symbol* h_name = name()->get_symbol();
symbolHandle h_signature (THREAD, signature()->get_symbolOop()); Symbol* h_signature = signature()->get_symbol();
vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass); vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass);
if (vtable_index == methodOopDesc::nonvirtual_vtable_index) { if (vtable_index == methodOopDesc::nonvirtual_vtable_index) {

View File

@ -110,7 +110,7 @@ ciSymbol* ciObjArrayKlass::construct_array_name(ciSymbol* element_name,
EXCEPTION_CONTEXT; EXCEPTION_CONTEXT;
int element_len = element_name->utf8_length(); 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; char* name;
if (base_name_sym->byte_at(0) == '[' || if (base_name_sym->byte_at(0) == '[' ||

View File

@ -268,10 +268,6 @@ public:
assert(is_type_array_klass(), "bad cast"); assert(is_type_array_klass(), "bad cast");
return (ciTypeArrayKlass*)this; return (ciTypeArrayKlass*)this;
} }
ciSymbolKlass* as_symbol_klass() {
assert(is_symbol_klass(), "bad cast");
return (ciSymbolKlass*)this;
}
ciKlassKlass* as_klass_klass() { ciKlassKlass* as_klass_klass() {
assert(is_klass_klass(), "bad cast"); assert(is_klass_klass(), "bad cast");
return (ciKlassKlass*)this; return (ciKlassKlass*)this;

View File

@ -38,7 +38,6 @@
#include "ci/ciObjArrayKlassKlass.hpp" #include "ci/ciObjArrayKlassKlass.hpp"
#include "ci/ciObjectFactory.hpp" #include "ci/ciObjectFactory.hpp"
#include "ci/ciSymbol.hpp" #include "ci/ciSymbol.hpp"
#include "ci/ciSymbolKlass.hpp"
#include "ci/ciTypeArray.hpp" #include "ci/ciTypeArray.hpp"
#include "ci/ciTypeArrayKlass.hpp" #include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciTypeArrayKlassKlass.hpp" #include "ci/ciTypeArrayKlassKlass.hpp"
@ -98,6 +97,8 @@ ciObjectFactory::ciObjectFactory(Arena* arena,
_unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL); _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL);
_return_addresses = _return_addresses =
new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL); new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL);
_symbols = new (arena) GrowableArray<ciSymbol*>(arena, 100, 0, NULL);
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@ -127,19 +128,19 @@ void ciObjectFactory::init_shared_objects() {
// Create the shared symbols, but not in _shared_ci_objects. // Create the shared symbols, but not in _shared_ci_objects.
int i; int i;
for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { 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);
assert(vmSymbols::find_sid(sym_handle()) == i, "1-1 mapping"); assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping");
ciSymbol* sym = new (_arena) ciSymbol(sym_handle, (vmSymbols::SID) i); ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i);
init_ident_of(sym); init_ident_of(sym);
_shared_ci_symbols[i] = sym; _shared_ci_symbols[i] = sym;
} }
#ifdef ASSERT #ifdef ASSERT
for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { 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); 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 #endif
} }
@ -157,8 +158,6 @@ void ciObjectFactory::init_shared_objects() {
init_ident_of(ciEnv::_null_object_instance); init_ident_of(ciEnv::_null_object_instance);
ciEnv::_method_klass_instance = ciEnv::_method_klass_instance =
get(Universe::methodKlassObj())->as_method_klass(); get(Universe::methodKlassObj())->as_method_klass();
ciEnv::_symbol_klass_instance =
get(Universe::symbolKlassObj())->as_symbol_klass();
ciEnv::_klass_klass_instance = ciEnv::_klass_klass_instance =
get(Universe::klassKlassObj())->as_klass_klass(); get(Universe::klassKlassObj())->as_klass_klass();
ciEnv::_instance_klass_klass_instance = ciEnv::_instance_klass_klass_instance =
@ -188,7 +187,7 @@ void ciObjectFactory::init_shared_objects() {
} }
} }
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 // Create dummy instanceKlass and objArrayKlass object and assign them idents
ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL); ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL);
init_ident_of(ciEnv::_unloaded_ciinstance_klass); init_ident_of(ciEnv::_unloaded_ciinstance_klass);
@ -218,6 +217,30 @@ void ciObjectFactory::init_shared_objects() {
_shared_ci_objects = _ci_objects; _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 // ciObjectFactory::get
// //
@ -255,15 +278,6 @@ ciObject* ciObjectFactory::get(oop key) {
return bucket->object(); 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 // The ciObject does not yet exist. Create it and insert it
// into the cache. // into the cache.
Handle keyHandle(key); Handle keyHandle(key);
@ -297,11 +311,7 @@ ciObject* ciObjectFactory::get(oop key) {
ciObject* ciObjectFactory::create_new_object(oop o) { ciObject* ciObjectFactory::create_new_object(oop o) {
EXCEPTION_CONTEXT; EXCEPTION_CONTEXT;
if (o->is_symbol()) { if (o->is_klass()) {
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()) {
KlassHandle h_k(THREAD, (klassOop)o); KlassHandle h_k(THREAD, (klassOop)o);
Klass* k = ((klassOop)o)->klass_part(); Klass* k = ((klassOop)o)->klass_part();
if (k->oop_is_instance()) { if (k->oop_is_instance()) {
@ -312,8 +322,6 @@ ciObject* ciObjectFactory::create_new_object(oop o) {
return new (arena()) ciTypeArrayKlass(h_k); return new (arena()) ciTypeArrayKlass(h_k);
} else if (k->oop_is_method()) { } else if (k->oop_is_method()) {
return new (arena()) ciMethodKlass(h_k); return new (arena()) ciMethodKlass(h_k);
} else if (k->oop_is_symbol()) {
return new (arena()) ciSymbolKlass(h_k);
} else if (k->oop_is_klass()) { } else if (k->oop_is_klass()) {
if (k->oop_is_objArrayKlass()) { if (k->oop_is_objArrayKlass()) {
return new (arena()) ciObjArrayKlassKlass(h_k); return new (arena()) ciObjArrayKlassKlass(h_k);
@ -426,22 +434,20 @@ ciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass,
// unloaded instanceKlass. Deal with both. // unloaded instanceKlass. Deal with both.
if (name->byte_at(0) == '[') { if (name->byte_at(0) == '[') {
// Decompose the name.' // Decompose the name.'
jint dimension = 0; FieldArrayInfo fd;
symbolOop element_name = NULL; BasicType element_type = FieldType::get_array_info(name->get_symbol(),
BasicType element_type= FieldType::get_array_info(name->get_symbolOop(), fd, THREAD);
&dimension,
&element_name,
THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION;
CURRENT_THREAD_ENV->record_out_of_memory_failure(); CURRENT_THREAD_ENV->record_out_of_memory_failure();
return ciEnv::_unloaded_ciobjarrayklass; return ciEnv::_unloaded_ciobjarrayklass;
} }
int dimension = fd.dimension();
assert(element_type != T_ARRAY, "unsuccessful decomposition"); assert(element_type != T_ARRAY, "unsuccessful decomposition");
ciKlass* element_klass = NULL; ciKlass* element_klass = NULL;
if (element_type == T_OBJECT) { if (element_type == T_OBJECT) {
ciEnv *env = CURRENT_THREAD_ENV; 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 = element_klass =
env->get_klass_by_name(accessing_klass, ci_name, false)->as_instance_klass(); env->get_klass_by_name(accessing_klass, ci_name, false)->as_instance_klass();
} else { } else {
@ -573,6 +579,10 @@ void ciObjectFactory::init_ident_of(ciObject* obj) {
obj->set_ident(_next_ident++); obj->set_ident(_next_ident++);
} }
void ciObjectFactory::init_ident_of(ciSymbol* obj) {
obj->set_ident(_next_ident++);
}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciObjectFactory::find // ciObjectFactory::find

View File

@ -48,6 +48,7 @@ private:
GrowableArray<ciKlass*>* _unloaded_klasses; GrowableArray<ciKlass*>* _unloaded_klasses;
GrowableArray<ciInstance*>* _unloaded_instances; GrowableArray<ciInstance*>* _unloaded_instances;
GrowableArray<ciReturnAddress*>* _return_addresses; GrowableArray<ciReturnAddress*>* _return_addresses;
GrowableArray<ciSymbol*>* _symbols; // keep list of symbols created
int _next_ident; int _next_ident;
public: public:
@ -76,6 +77,7 @@ private:
void insert_non_perm(NonPermObject* &where, oop key, ciObject* obj); void insert_non_perm(NonPermObject* &where, oop key, ciObject* obj);
void init_ident_of(ciObject* obj); void init_ident_of(ciObject* obj);
void init_ident_of(ciSymbol* obj);
Arena* arena() { return _arena; } Arena* arena() { return _arena; }
@ -88,13 +90,15 @@ public:
static void initialize(); static void initialize();
void init_shared_objects(); void init_shared_objects();
void remove_symbols();
ciObjectFactory(Arena* arena, int expected_size); ciObjectFactory(Arena* arena, int expected_size);
// Get the ciObject corresponding to some oop. // Get the ciObject corresponding to some oop.
ciObject* get(oop key); ciObject* get(oop key);
ciSymbol* get_symbol(Symbol* key);
// Get the ciSymbol corresponding to one of the vmSymbols. // Get the ciSymbol corresponding to one of the vmSymbols.
static ciSymbol* vm_symbol_at(int index); static ciSymbol* vm_symbol_at(int index);

View File

@ -47,7 +47,8 @@ ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol) {
int size = 0; int size = 0;
int count = 0; int count = 0;
symbolHandle sh (THREAD, symbol->get_symbolOop()); ResourceMark rm(THREAD);
Symbol* sh = symbol->get_symbol();
SignatureStream ss(sh); SignatureStream ss(sh);
for (; ; ss.next()) { for (; ; ss.next()) {
// Process one element of the signature // Process one element of the signature
@ -55,14 +56,14 @@ ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol) {
if (!ss.is_object()) { if (!ss.is_object()) {
type = ciType::make(ss.type()); type = ciType::make(ss.type());
} else { } else {
symbolOop name = ss.as_symbol(THREAD); Symbol* name = ss.as_symbol(THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
type = ss.is_array() ? (ciType*)ciEnv::unloaded_ciobjarrayklass() type = ss.is_array() ? (ciType*)ciEnv::unloaded_ciobjarrayklass()
: (ciType*)ciEnv::unloaded_ciinstance_klass(); : (ciType*)ciEnv::unloaded_ciinstance_klass();
env->record_out_of_memory_failure(); env->record_out_of_memory_failure();
CLEAR_PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION;
} else { } 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); type = env->get_klass_by_name_impl(_accessing_klass, klass_name, false);
} }
} }

View File

@ -48,7 +48,7 @@ private:
void get_all_klasses(); void get_all_klasses();
symbolOop get_symbolOop() const { return _symbol->get_symbolOop(); } Symbol* get_symbol() const { return _symbol->get_symbol(); }
public: public:
ciSymbol* as_symbol() const { return _symbol; } ciSymbol* as_symbol() const { return _symbol; }

View File

@ -30,23 +30,27 @@
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciSymbol::ciSymbol // ciSymbol::ciSymbol
// //
// Preallocated handle variant. Used with handles from vmSymboHandles. // Preallocated symbol variant. Used with symbols from vmSymbols.
ciSymbol::ciSymbol(symbolHandle h_s, vmSymbols::SID sid) ciSymbol::ciSymbol(Symbol* s, vmSymbols::SID sid)
: ciObject(h_s), _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"); assert(sid_ok(), "must be in vmSymbols");
} }
// Normal case for non-famous symbols. // Normal case for non-famous symbols.
ciSymbol::ciSymbol(symbolOop s) ciSymbol::ciSymbol(Symbol* s)
: ciObject(s), _sid(vmSymbols::NO_SID) : _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"); assert(sid_ok(), "must not be in vmSymbols");
} }
// ciSymbol // ciSymbol
// //
// This class represents a symbolOop in the HotSpot virtual // This class represents a Symbol* in the HotSpot virtual
// machine. // machine.
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@ -55,20 +59,20 @@ ciSymbol::ciSymbol(symbolOop s)
// The text of the symbol as a null-terminated C string. // The text of the symbol as a null-terminated C string.
const char* ciSymbol::as_utf8() { const char* ciSymbol::as_utf8() {
VM_QUICK_ENTRY_MARK; VM_QUICK_ENTRY_MARK;
symbolOop s = get_symbolOop(); Symbol* s = get_symbol();
return s->as_utf8(); return s->as_utf8();
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciSymbol::base // ciSymbol::base
jbyte* ciSymbol::base() { const jbyte* ciSymbol::base() {
GUARDED_VM_ENTRY(return get_symbolOop()->base();) GUARDED_VM_ENTRY(return get_symbol()->base();)
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciSymbol::byte_at // ciSymbol::byte_at
int ciSymbol::byte_at(int i) { 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 @@ int ciSymbol::byte_at(int i) {
// //
// Tests if the symbol starts with the given prefix. // Tests if the symbol starts with the given prefix.
bool ciSymbol::starts_with(const char* prefix, int len) const { 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 @@ bool ciSymbol::starts_with(const char* prefix, int len) const {
// //
// Determines where the symbol contains the given substring. // Determines where the symbol contains the given substring.
int ciSymbol::index_of_at(int i, const char* str, int len) const { 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 // ciSymbol::utf8_length
int 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 @@ void ciSymbol::print_impl(outputStream* st) {
// //
// Print the value of this symbol on an outputStream // Print the value of this symbol on an outputStream
void ciSymbol::print_symbol_on(outputStream *st) { 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 @@ void ciSymbol::print_symbol_on(outputStream *st) {
// Make a ciSymbol from a C string (implementation). // Make a ciSymbol from a C string (implementation).
ciSymbol* ciSymbol::make_impl(const char* s) { ciSymbol* ciSymbol::make_impl(const char* s) {
EXCEPTION_CONTEXT; EXCEPTION_CONTEXT;
// For some reason, oopFactory::new_symbol doesn't declare its TempNewSymbol sym = SymbolTable::new_symbol(s, THREAD);
// char* argument as const.
symbolOop sym = oopFactory::new_symbol((char*)s, (int)strlen(s), THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION;
CURRENT_THREAD_ENV->record_out_of_memory_failure(); CURRENT_THREAD_ENV->record_out_of_memory_failure();
return ciEnv::_unloaded_cisymbol; return ciEnv::_unloaded_cisymbol;
} }
return CURRENT_THREAD_ENV->get_object(sym)->as_symbol(); return CURRENT_THREAD_ENV->get_symbol(sym);
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------

View File

@ -28,15 +28,18 @@
#include "ci/ciObject.hpp" #include "ci/ciObject.hpp"
#include "ci/ciObjectFactory.hpp" #include "ci/ciObjectFactory.hpp"
#include "classfile/vmSymbols.hpp" #include "classfile/vmSymbols.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
// ciSymbol // ciSymbol
// //
// This class represents a symbolOop in the HotSpot virtual // This class represents a Symbol* in the HotSpot virtual
// machine. // machine.
class ciSymbol : public ciObject { class ciSymbol : public ResourceObj {
Symbol* _symbol;
uint _ident;
CI_PACKAGE_ACCESS 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 ciEnv;
friend class ciInstanceKlass; friend class ciInstanceKlass;
friend class ciSignature; friend class ciSignature;
@ -45,24 +48,28 @@ class ciSymbol : public ciObject {
private: private:
const vmSymbols::SID _sid; 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(Symbol* s); // normal case, for symbols not mentioned in vmSymbols
ciSymbol(symbolHandle s, vmSymbols::SID sid); // for use with vmSymbolHandles 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"; } const char* type_string() { return "ciSymbol"; }
void print_impl(outputStream* st); void print_impl(outputStream* st);
// This is public in symbolOop but private here, because the base can move: // This is public in Symbol* but private here, because the base can move:
jbyte* base(); const jbyte* base();
// Make a ciSymbol from a C string (implementation). // Make a ciSymbol from a C string (implementation).
static ciSymbol* make_impl(const char* s); static ciSymbol* make_impl(const char* s);
void set_ident(uint id) { _ident = id; }
public: public:
// A number unique to this object.
uint ident() { return _ident; }
// The enumeration ID from vmSymbols, or vmSymbols::NO_SID if none. // The enumeration ID from vmSymbols, or vmSymbols::NO_SID if none.
vmSymbols::SID sid() const { return _sid; } vmSymbols::SID sid() const { return _sid; }
@ -79,9 +86,6 @@ public:
// Determines where the symbol contains the given substring. // Determines where the symbol contains the given substring.
int index_of_at(int i, const char* str, int len) const; 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_on(outputStream* st);
void print_symbol() { void print_symbol() {
print_symbol_on(tty); print_symbol_on(tty);
@ -96,6 +100,13 @@ public:
static ciSymbol* name() { return ciObjectFactory::vm_symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(name)); } static ciSymbol* name() { return ciObjectFactory::vm_symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(name)); }
VM_SYMBOLS_DO(CI_SYMBOL_DECLARE, CI_SYMBOL_DECLARE) VM_SYMBOLS_DO(CI_SYMBOL_DECLARE, CI_SYMBOL_DECLARE)
#undef 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 #endif // SHARE_VM_CI_CISYMBOL_HPP

View File

@ -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;
}

View File

@ -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

View File

@ -49,7 +49,6 @@
#include "ci/ciSignature.hpp" #include "ci/ciSignature.hpp"
#include "ci/ciStreams.hpp" #include "ci/ciStreams.hpp"
#include "ci/ciSymbol.hpp" #include "ci/ciSymbol.hpp"
#include "ci/ciSymbolKlass.hpp"
#include "ci/ciTypeArray.hpp" #include "ci/ciTypeArray.hpp"
#include "ci/ciTypeArrayKlass.hpp" #include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciTypeArrayKlassKlass.hpp" #include "ci/ciTypeArrayKlassKlass.hpp"

View File

@ -31,25 +31,25 @@
void ClassFileParser::classfile_parse_error(const char* msg, TRAPS) { void ClassFileParser::classfile_parse_error(const char* msg, TRAPS) {
ResourceMark rm(THREAD); 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()); msg, _class_name->as_C_string());
} }
void ClassFileParser::classfile_parse_error(const char* msg, int index, TRAPS) { void ClassFileParser::classfile_parse_error(const char* msg, int index, TRAPS) {
ResourceMark rm(THREAD); 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()); msg, index, _class_name->as_C_string());
} }
void ClassFileParser::classfile_parse_error(const char* msg, const char *name, TRAPS) { void ClassFileParser::classfile_parse_error(const char* msg, const char *name, TRAPS) {
ResourceMark rm(THREAD); 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()); msg, name, _class_name->as_C_string());
} }
void ClassFileParser::classfile_parse_error(const char* msg, int index, const char *name, TRAPS) { void ClassFileParser::classfile_parse_error(const char* msg, int index, const char *name, TRAPS) {
ResourceMark rm(THREAD); 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()); msg, index, name, _class_name->as_C_string());
} }
@ -57,7 +57,7 @@ void StackMapStream::stackmap_format_error(const char* msg, TRAPS) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_ClassFormatError(), vmSymbols::java_lang_ClassFormatError(),
"StackMapTable format error: %s", msg "StackMapTable format error: %s", msg
); );
} }

View File

@ -41,7 +41,7 @@
#include "oops/klassOop.hpp" #include "oops/klassOop.hpp"
#include "oops/klassVtable.hpp" #include "oops/klassVtable.hpp"
#include "oops/methodOop.hpp" #include "oops/methodOop.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp" #include "prims/jvmtiExport.hpp"
#include "runtime/javaCalls.hpp" #include "runtime/javaCalls.hpp"
#include "runtime/perfData.hpp" #include "runtime/perfData.hpp"
@ -267,14 +267,14 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
} }
unsigned int hash; 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) { if (result == NULL) {
names[names_count] = (char*)utf8_buffer; names[names_count] = (char*)utf8_buffer;
lengths[names_count] = utf8_length; lengths[names_count] = utf8_length;
indices[names_count] = index; indices[names_count] = index;
hashValues[names_count++] = hash; hashValues[names_count++] = hash;
if (names_count == SymbolTable::symbol_alloc_batch_size) { 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; names_count = 0;
} }
} else { } else {
@ -291,7 +291,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
// Allocate the remaining symbols // Allocate the remaining symbols
if (names_count > 0) { 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(). // Copy _current pointer of local copy back to stream().
@ -301,6 +301,23 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
cfs0->set_current(cfs1.current()); 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); } bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); }
constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) { constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
@ -319,6 +336,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
constantPoolHandle cp (THREAD, constant_pool); constantPoolHandle cp (THREAD, constant_pool);
cp->set_partially_loaded(); // Enables heap verify to work on partial constantPoolOops 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 // parsing constant pool entries
parse_constant_pool_entries(cp, length, CHECK_(nullHandle)); parse_constant_pool_entries(cp, length, CHECK_(nullHandle));
@ -411,7 +429,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
cp->tag_at(string_index).is_utf8(), cp->tag_at(string_index).is_utf8(),
"Invalid constant pool index %u in class file %s", "Invalid constant pool index %u in class file %s",
string_index, CHECK_(nullHandle)); 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); cp->unresolved_string_at_put(index, sym);
} }
break; break;
@ -526,6 +544,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
} }
if (!_need_verify) { if (!_need_verify) {
cp_in_error.set_in_error(false);
return cp; return cp;
} }
@ -535,7 +554,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
jbyte tag = cp->tag_at(index).value(); jbyte tag = cp->tag_at(index).value();
switch (tag) { switch (tag) {
case JVM_CONSTANT_UnresolvedClass: { 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 // check the name, even if _cp_patches will overwrite it
verify_legal_class_name(class_name, CHECK_(nullHandle)); verify_legal_class_name(class_name, CHECK_(nullHandle));
break; break;
@ -544,8 +563,8 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
if (_need_verify && _major_version >= JAVA_7_VERSION) { if (_need_verify && _major_version >= JAVA_7_VERSION) {
int sig_index = cp->signature_ref_index_at(index); int sig_index = cp->signature_ref_index_at(index);
int name_index = cp->name_ref_index_at(index); int name_index = cp->name_ref_index_at(index);
symbolHandle name(THREAD, cp->symbol_at(name_index)); Symbol* name = cp->symbol_at(name_index);
symbolHandle sig(THREAD, cp->symbol_at(sig_index)); Symbol* sig = cp->symbol_at(sig_index);
if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) { if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) {
verify_legal_method_signature(name, sig, CHECK_(nullHandle)); verify_legal_method_signature(name, sig, CHECK_(nullHandle));
} else { } else {
@ -562,8 +581,8 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index);
// already verified to be utf8 // already verified to be utf8
int signature_ref_index = cp->signature_ref_index_at(name_and_type_ref_index); int signature_ref_index = cp->signature_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);
symbolHandle signature(THREAD, cp->symbol_at(signature_ref_index)); Symbol* signature = cp->symbol_at(signature_ref_index);
if (tag == JVM_CONSTANT_Fieldref) { if (tag == JVM_CONSTANT_Fieldref) {
verify_legal_field_name(name, CHECK_(nullHandle)); verify_legal_field_name(name, CHECK_(nullHandle));
if (_need_verify && _major_version >= JAVA_7_VERSION) { if (_need_verify && _major_version >= JAVA_7_VERSION) {
@ -590,11 +609,11 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
} }
if (tag == JVM_CONSTANT_Methodref) { if (tag == JVM_CONSTANT_Methodref) {
// 4509014: If a class method name begins with '<', it must be "<init>". // 4509014: If a class method name begins with '<', it must be "<init>".
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(); unsigned int name_len = name->utf8_length();
assert(name_len > 0, "bad method name"); // already verified as legal name assert(name_len > 0, "bad method name"); // already verified as legal name
if (name->byte_at(0) == '<') { if (name->byte_at(0) == '<') {
if (name() != vmSymbols::object_initializer_name()) { if (name != vmSymbols::object_initializer_name()) {
classfile_parse_error( classfile_parse_error(
"Bad method name at constant pool index %u in class file %s", "Bad method name at constant pool index %u in class file %s",
name_ref_index, CHECK_(nullHandle)); name_ref_index, CHECK_(nullHandle));
@ -615,15 +634,15 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
{ {
int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index); 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); 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 (ref_kind == JVM_REF_newInvokeSpecial) {
if (name() != vmSymbols::object_initializer_name()) { if (name != vmSymbols::object_initializer_name()) {
classfile_parse_error( classfile_parse_error(
"Bad constructor name at constant pool index %u in class file %s", "Bad constructor name at constant pool index %u in class file %s",
name_ref_index, CHECK_(nullHandle)); name_ref_index, CHECK_(nullHandle));
} }
} else { } else {
if (name() == vmSymbols::object_initializer_name()) { if (name == vmSymbols::object_initializer_name()) {
classfile_parse_error( classfile_parse_error(
"Bad method name at constant pool index %u in class file %s", "Bad method name at constant pool index %u in class file %s",
name_ref_index, CHECK_(nullHandle)); name_ref_index, CHECK_(nullHandle));
@ -636,14 +655,18 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
break; break;
} }
case JVM_CONSTANT_MethodType: { case JVM_CONSTANT_MethodType: {
symbolHandle no_name = vmSymbolHandles::type_name(); // place holder Symbol* no_name = vmSymbols::type_name(); // place holder
symbolHandle signature(THREAD, cp->method_type_signature_at(index)); Symbol* signature = cp->method_type_signature_at(index);
verify_legal_method_signature(no_name, signature, CHECK_(nullHandle)); verify_legal_method_signature(no_name, signature, CHECK_(nullHandle));
break; break;
} }
case JVM_CONSTANT_Utf8: {
assert(cp->symbol_at(index)->refcount() != 0, "count corrupted");
}
} // end of switch } // end of switch
} // end of for } // end of for
cp_in_error.set_in_error(false);
return cp; return cp;
} }
@ -665,8 +688,8 @@ void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Hand
guarantee_property(java_lang_String::is_instance(patch()), guarantee_property(java_lang_String::is_instance(patch()),
"Illegal class patch at %d in class file %s", "Illegal class patch at %d in class file %s",
index, CHECK); index, CHECK);
symbolHandle name = java_lang_String::as_symbol(patch(), CHECK); Symbol* name = java_lang_String::as_symbol(patch(), CHECK);
cp->unresolved_klass_at_put(index, name()); cp->unresolved_klass_at_put(index, name);
} }
break; break;
@ -717,15 +740,15 @@ void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Hand
class NameSigHash: public ResourceObj { class NameSigHash: public ResourceObj {
public: public:
symbolOop _name; // name Symbol* _name; // name
symbolOop _sig; // signature Symbol* _sig; // signature
NameSigHash* _next; // Next entry in hash table NameSigHash* _next; // Next entry in hash table
}; };
#define HASH_ROW_SIZE 256 #define HASH_ROW_SIZE 256
unsigned int hash(symbolOop name, symbolOop sig) { unsigned int hash(Symbol* name, Symbol* sig) {
unsigned int raw_hash = 0; unsigned int raw_hash = 0;
raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2); raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2);
raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize; raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize;
@ -742,8 +765,8 @@ void initialize_hashtable(NameSigHash** table) {
// Return true if no duplicate is found. And name/sig is added as a new entry in table. // 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. // The old format checker uses heap sort to find duplicates.
// NOTE: caller should guarantee that GC doesn't happen during the life cycle // NOTE: caller should guarantee that GC doesn't happen during the life cycle
// of table since we don't expect symbolOop's to move. // of table since we don't expect Symbol*'s to move.
bool put_after_lookup(symbolOop name, symbolOop sig, NameSigHash** table) { bool put_after_lookup(Symbol* name, Symbol* sig, NameSigHash** table) {
assert(name != NULL, "name in constant pool is NULL"); assert(name != NULL, "name in constant pool is NULL");
// First lookup for duplicates // First lookup for duplicates
@ -773,7 +796,7 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
int length, int length,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
symbolHandle class_name, Symbol* class_name,
TRAPS) { TRAPS) {
ClassFileStream* cfs = stream(); ClassFileStream* cfs = stream();
assert(length > 0, "only called for length>0"); assert(length > 0, "only called for length>0");
@ -793,7 +816,7 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
if (cp->tag_at(interface_index).is_klass()) { if (cp->tag_at(interface_index).is_klass()) {
interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index)); interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
} else { } 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. // 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. // But need to make sure it's not an array type.
@ -830,7 +853,7 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
debug_only(No_Safepoint_Verifier nsv;) debug_only(No_Safepoint_Verifier nsv;)
for (index = 0; index < length; index++) { for (index = 0; index < length; index++) {
klassOop k = (klassOop)interfaces->obj_at(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 no duplicates, add (name, NULL) in hashtable interface_names.
if (!put_after_lookup(name, NULL, interface_names)) { if (!put_after_lookup(name, NULL, interface_names)) {
dup = true; dup = true;
@ -908,7 +931,7 @@ void ClassFileParser::parse_field_attributes(constantPoolHandle cp,
"Invalid field attribute index %u in class file %s", "Invalid field attribute index %u in class file %s",
attribute_name_index, attribute_name_index,
CHECK); 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()) { if (is_static && attribute_name == vmSymbols::tag_constant_value()) {
// ignore if non-static // ignore if non-static
if (constantvalue_index != 0) { if (constantvalue_index != 0) {
@ -1031,7 +1054,7 @@ typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_int
valid_cp_range(name_index, cp_size) && cp->tag_at(name_index).is_utf8(), 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", "Invalid constant pool index %u for field name in class file %s",
name_index, CHECK_(nullHandle)); 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)); verify_legal_field_name(name, CHECK_(nullHandle));
u2 signature_index = cfs->get_u2_fast(); u2 signature_index = cfs->get_u2_fast();
@ -1040,7 +1063,7 @@ typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_int
cp->tag_at(signature_index).is_utf8(), cp->tag_at(signature_index).is_utf8(),
"Invalid constant pool index %u for field signature in class file %s", "Invalid constant pool index %u for field signature in class file %s",
signature_index, CHECK_(nullHandle)); 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)); verify_legal_field_signature(name, sig, CHECK_(nullHandle));
u2 constantvalue_index = 0; u2 constantvalue_index = 0;
@ -1166,9 +1189,9 @@ typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_int
debug_only(No_Safepoint_Verifier nsv;) debug_only(No_Safepoint_Verifier nsv;)
for (int i = 0; i < length*instanceKlass::next_offset; i += instanceKlass::next_offset) { for (int i = 0; i < length*instanceKlass::next_offset; i += instanceKlass::next_offset) {
int name_index = fields->ushort_at(i + instanceKlass::name_index_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); 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 no duplicates, add name/signature in hashtable names_and_sigs.
if (!put_after_lookup(name, sig, names_and_sigs)) { if (!put_after_lookup(name, sig, names_and_sigs)) {
dup = true; dup = true;
@ -1422,16 +1445,16 @@ u2* ClassFileParser::parse_localvariable_table(u4 code_length,
"Signature index %u in %s has bad constant type in class file %s", "Signature index %u in %s has bad constant type in class file %s",
descriptor_index, tbl_name, CHECK_NULL); descriptor_index, tbl_name, CHECK_NULL);
symbolHandle name(THREAD, cp->symbol_at(name_index)); Symbol* name = cp->symbol_at(name_index);
symbolHandle sig(THREAD, cp->symbol_at(descriptor_index)); Symbol* sig = cp->symbol_at(descriptor_index);
verify_legal_field_name(name, CHECK_NULL); verify_legal_field_name(name, CHECK_NULL);
u2 extra_slot = 0; u2 extra_slot = 0;
if (!isLVTT) { if (!isLVTT) {
verify_legal_field_signature(name, sig, CHECK_NULL); verify_legal_field_signature(name, sig, CHECK_NULL);
// 4894874: check special cases for double and long local variables // 4894874: check special cases for double and long local variables
if (sig() == vmSymbols::type_signature(T_DOUBLE) || if (sig == vmSymbols::type_signature(T_DOUBLE) ||
sig() == vmSymbols::type_signature(T_LONG)) { sig == vmSymbols::type_signature(T_LONG)) {
extra_slot = 1; extra_slot = 1;
} }
} }
@ -1539,7 +1562,7 @@ u2* ClassFileParser::parse_checked_exceptions(u2* checked_exceptions_length,
} }
void ClassFileParser::throwIllegalSignature( void ClassFileParser::throwIllegalSignature(
const char* type, symbolHandle name, symbolHandle sig, TRAPS) { const char* type, Symbol* name, Symbol* sig, TRAPS) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow(THREAD_AND_LOCATION, Exceptions::fthrow(THREAD_AND_LOCATION,
vmSymbols::java_lang_ClassFormatError(), vmSymbols::java_lang_ClassFormatError(),
@ -1580,7 +1603,7 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
cp->tag_at(name_index).is_utf8(), cp->tag_at(name_index).is_utf8(),
"Illegal constant pool index %u for method name in class file %s", "Illegal constant pool index %u for method name in class file %s",
name_index, CHECK_(nullHandle)); 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)); verify_legal_method_name(name, CHECK_(nullHandle));
u2 signature_index = cfs->get_u2_fast(); u2 signature_index = cfs->get_u2_fast();
@ -1589,7 +1612,7 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
cp->tag_at(signature_index).is_utf8(), cp->tag_at(signature_index).is_utf8(),
"Illegal constant pool index %u for method signature in class file %s", "Illegal constant pool index %u for method signature in class file %s",
signature_index, CHECK_(nullHandle)); signature_index, CHECK_(nullHandle));
symbolHandle signature(THREAD, cp->symbol_at(signature_index)); Symbol* signature = cp->symbol_at(signature_index);
AccessFlags access_flags; AccessFlags access_flags;
if (name == vmSymbols::class_initializer_name()) { if (name == vmSymbols::class_initializer_name()) {
@ -1660,7 +1683,7 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
"Invalid method attribute name index %u in class file %s", "Invalid method attribute name index %u in class file %s",
method_attribute_name_index, CHECK_(nullHandle)); 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()) { if (method_attribute_name == vmSymbols::tag_code()) {
// Parse Code attribute // Parse Code attribute
if (_need_verify) { if (_need_verify) {
@ -2057,16 +2080,16 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
0, 0,
CHECK_(nullHandle)); CHECK_(nullHandle));
if (name() == vmSymbols::finalize_method_name() && if (name == vmSymbols::finalize_method_name() &&
signature() == vmSymbols::void_method_signature()) { signature == vmSymbols::void_method_signature()) {
if (m->is_empty_method()) { if (m->is_empty_method()) {
_has_empty_finalizer = true; _has_empty_finalizer = true;
} else { } else {
_has_finalizer = true; _has_finalizer = true;
} }
} }
if (name() == vmSymbols::object_initializer_name() && if (name == vmSymbols::object_initializer_name() &&
signature() == vmSymbols::void_method_signature() && signature == vmSymbols::void_method_signature() &&
m->is_vanilla_constructor()) { m->is_vanilla_constructor()) {
_has_vanilla_constructor = true; _has_vanilla_constructor = true;
} }
@ -2193,7 +2216,7 @@ typeArrayHandle ClassFileParser::sort_methods(objArrayHandle methods,
} }
} }
// Sort method array by ascending method name (for faster lookups & vtable construction) // 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(), methodOopDesc::sort_methods(methods(),
methods_annotations(), methods_annotations(),
methods_parameter_annotations(), methods_parameter_annotations(),
@ -2242,9 +2265,10 @@ void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantP
if (JvmtiExport::can_get_source_debug_extension()) { if (JvmtiExport::can_get_source_debug_extension()) {
// Optimistically assume that only 1 byte UTF format is used // Optimistically assume that only 1 byte UTF format is used
// (common case) // (common case)
symbolOop sde_symbol = oopFactory::new_symbol((char*)sde_buffer, TempNewSymbol sde_symbol = SymbolTable::new_symbol((const char*)sde_buffer, length, CHECK);
length, CHECK);
k->set_source_debug_extension(sde_symbol); 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 // Got utf8 string, set stream position forward
cfs->skip_u1(length, CHECK); cfs->skip_u1(length, CHECK);
@ -2440,7 +2464,7 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
cp->tag_at(attribute_name_index).is_utf8(), cp->tag_at(attribute_name_index).is_utf8(),
"Attribute name has bad constant pool index %u in class file %s", "Attribute name has bad constant pool index %u in class file %s",
attribute_name_index, CHECK); 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()) { if (tag == vmSymbols::tag_source_file()) {
// Check for SourceFile tag // Check for SourceFile tag
if (_need_verify) { if (_need_verify) {
@ -2607,7 +2631,7 @@ static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
case T_OBJECT: case T_OBJECT:
{ {
#ifdef ASSERT #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"); assert(fd->signature() == sym, "just checking");
#endif #endif
oop string = fd->string_initial_value(CHECK); oop string = fd->string_initial_value(CHECK);
@ -2650,8 +2674,8 @@ void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_pt
(*fields_ptr)()->ushort_at(i + instanceKlass::name_index_offset); (*fields_ptr)()->ushort_at(i + instanceKlass::name_index_offset);
int sig_index = int sig_index =
(*fields_ptr)()->ushort_at(i + instanceKlass::signature_index_offset); (*fields_ptr)()->ushort_at(i + instanceKlass::signature_index_offset);
symbolOop f_name = cp->symbol_at(name_index); Symbol* f_name = cp->symbol_at(name_index);
symbolOop f_sig = cp->symbol_at(sig_index); Symbol* f_sig = cp->symbol_at(sig_index);
if (f_sig == vmSymbols::reference_signature() && reference_index == 0) { if (f_sig == vmSymbols::reference_signature() && reference_index == 0) {
// Save the index for reference signature for later use. // Save the index for reference signature for later use.
// The fake discovered field does not entries in the // The fake discovered field does not entries in the
@ -2805,9 +2829,8 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
int name_index = fields->ushort_at(i + instanceKlass::name_index_offset); int name_index = fields->ushort_at(i + instanceKlass::name_index_offset);
int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset); int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset);
int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset); int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset);
symbolOop f_name = cp->symbol_at(name_index); Symbol* f_name = cp->symbol_at(name_index);
symbolOop f_sig = cp->symbol_at(sig_index); Symbol* f_sig = cp->symbol_at(sig_index);
if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) { if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) {
if (f_sig == vmSymbols::machine_word_signature()) { if (f_sig == vmSymbols::machine_word_signature()) {
// If the signature of vmentry is already changed, we're done. // If the signature of vmentry is already changed, we're done.
@ -2841,12 +2864,12 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
} }
instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
KlassHandle host_klass, KlassHandle host_klass,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
symbolHandle& parsed_name, TempNewSymbol& parsed_name,
bool verify, bool verify,
TRAPS) { TRAPS) {
// So that JVMTI can cache class file in the state before retransformable agents // So that JVMTI can cache class file in the state before retransformable agents
@ -2899,7 +2922,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
cfs->set_verify(_need_verify); cfs->set_verify(_need_verify);
// Save the class file name for easier error message printing. // 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 cfs->guarantee_more(8, CHECK_(nullHandle)); // magic, major, minor
// Magic value // Magic value
@ -2914,10 +2937,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
// Check version numbers - we check this even with verifier off // Check version numbers - we check this even with verifier off
if (!is_supported_version(major_version, minor_version)) { if (!is_supported_version(major_version, minor_version)) {
if (name.is_null()) { if (name == NULL) {
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_UnsupportedClassVersionError(), vmSymbols::java_lang_UnsupportedClassVersionError(),
"Unsupported major.minor version %u.%u", "Unsupported major.minor version %u.%u",
major_version, major_version,
minor_version); minor_version);
@ -2925,7 +2948,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_UnsupportedClassVersionError(), vmSymbols::java_lang_UnsupportedClassVersionError(),
"%s : Unsupported major.minor version %u.%u", "%s : Unsupported major.minor version %u.%u",
name->as_C_string(), name->as_C_string(),
major_version, major_version,
@ -2944,6 +2967,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
// Constant pool // Constant pool
constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle)); constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));
ConstantPoolCleaner error_handler(cp); // set constant pool to be cleaned up.
int cp_size = cp->length(); int cp_size = cp->length();
cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len
@ -2968,12 +2993,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
"Invalid this class index %u in constant pool in class file %s", "Invalid this class index %u in constant pool in class file %s",
this_class_index, CHECK_(nullHandle)); this_class_index, CHECK_(nullHandle));
symbolHandle class_name (THREAD, cp->unresolved_klass_at(this_class_index)); Symbol* class_name = cp->unresolved_klass_at(this_class_index);
assert(class_name.not_null(), "class_name can't be null"); assert(class_name != NULL, "class_name can't be null");
// It's important to set parsed_name *before* resolving the super class. // It's important to set parsed_name *before* resolving the super class.
// (it's used for cleanup by the caller if parsing fails) // (it's used for cleanup by the caller if parsing fails)
parsed_name = class_name; 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 // Update _class_name which could be null previously to be class_name
_class_name = class_name; _class_name = class_name;
@ -2993,11 +3021,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
{ HandleMark hm(THREAD); { HandleMark hm(THREAD);
// Checks if name in class file matches requested name // 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); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_NoClassDefFoundError(), vmSymbols::java_lang_NoClassDefFoundError(),
"%s (wrong name: %s)", "%s (wrong name: %s)",
name->as_C_string(), name->as_C_string(),
class_name->as_C_string() class_name->as_C_string()
@ -3006,14 +3034,14 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
} }
if (TraceClassLoadingPreorder) { 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()); if (cfs->source() != NULL) tty->print(" from %s", cfs->source());
tty->print_cr("]"); tty->print_cr("]");
} }
u2 super_class_index = cfs->get_u2_fast(); u2 super_class_index = cfs->get_u2_fast();
if (super_class_index == 0) { 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", "Invalid superclass index %u in class file %s",
super_class_index, super_class_index,
CHECK_(nullHandle)); CHECK_(nullHandle));
@ -3075,11 +3103,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
// We check super class after class file is parsed and format is checked // We check super class after class file is parsed and format is checked
if (super_class_index > 0 && super_klass.is_null()) { 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()) { if (access_flags.is_interface()) {
// Before attempting to resolve the superclass, check for class format // Before attempting to resolve the superclass, check for class format
// errors not checked yet. // 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", "Interfaces must have java.lang.Object as superclass in class file %s",
CHECK_(nullHandle)); CHECK_(nullHandle));
} }
@ -3100,7 +3128,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_IncompatibleClassChangeError(), vmSymbols::java_lang_IncompatibleClassChangeError(),
"class %s has interface %s as super class", "class %s has interface %s as super class",
class_name->as_klass_external_name(), class_name->as_klass_external_name(),
super_klass->external_name() super_klass->external_name()
@ -3193,18 +3221,18 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
next_nonstatic_field_offset = first_nonstatic_field_offset; next_nonstatic_field_offset = first_nonstatic_field_offset;
// Add fake fields for java.lang.Class instances (also see below) // 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)); java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
} }
// adjust the vmentry field declaration in java.dyn.MethodHandle // 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)); java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
} }
// Add a fake "discovered" field if it is not present // Add a fake "discovered" field if it is not present
// for compatibility with earlier jdk's. // 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()) { && class_loader.is_null()) {
java_lang_ref_Reference_fix_pre(&fields, cp, &fac, CHECK_(nullHandle)); java_lang_ref_Reference_fix_pre(&fields, cp, &fac, CHECK_(nullHandle));
} }
@ -3236,7 +3264,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
// Add fake fields for java.lang.Class instances (also see above). // Add fake fields for java.lang.Class instances (also see above).
// FieldsAllocationStyle and CompactFields values will be reset to default. // 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); java_lang_Class_fix_post(&next_nonstatic_field_offset);
nonstatic_oop_offsets[0] = first_nonstatic_field_offset; nonstatic_oop_offsets[0] = first_nonstatic_field_offset;
const uint fake_oop_count = (next_nonstatic_field_offset - const uint fake_oop_count = (next_nonstatic_field_offset -
@ -3279,22 +3307,22 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
// (see in JavaClasses::compute_hard_coded_offsets()). // (see in JavaClasses::compute_hard_coded_offsets()).
// Use default fields allocation order for them. // Use default fields allocation order for them.
if( (allocation_style != 0 || compact_fields ) && class_loader.is_null() && if( (allocation_style != 0 || compact_fields ) && class_loader.is_null() &&
(class_name() == vmSymbols::java_lang_AssertionStatusDirectives() || (class_name == vmSymbols::java_lang_AssertionStatusDirectives() ||
class_name() == vmSymbols::java_lang_Class() || class_name == vmSymbols::java_lang_Class() ||
class_name() == vmSymbols::java_lang_ClassLoader() || class_name == vmSymbols::java_lang_ClassLoader() ||
class_name() == vmSymbols::java_lang_ref_Reference() || class_name == vmSymbols::java_lang_ref_Reference() ||
class_name() == vmSymbols::java_lang_ref_SoftReference() || class_name == vmSymbols::java_lang_ref_SoftReference() ||
class_name() == vmSymbols::java_lang_StackTraceElement() || class_name == vmSymbols::java_lang_StackTraceElement() ||
class_name() == vmSymbols::java_lang_String() || class_name == vmSymbols::java_lang_String() ||
class_name() == vmSymbols::java_lang_Throwable() || class_name == vmSymbols::java_lang_Throwable() ||
class_name() == vmSymbols::java_lang_Boolean() || class_name == vmSymbols::java_lang_Boolean() ||
class_name() == vmSymbols::java_lang_Character() || class_name == vmSymbols::java_lang_Character() ||
class_name() == vmSymbols::java_lang_Float() || class_name == vmSymbols::java_lang_Float() ||
class_name() == vmSymbols::java_lang_Double() || class_name == vmSymbols::java_lang_Double() ||
class_name() == vmSymbols::java_lang_Byte() || class_name == vmSymbols::java_lang_Byte() ||
class_name() == vmSymbols::java_lang_Short() || class_name == vmSymbols::java_lang_Short() ||
class_name() == vmSymbols::java_lang_Integer() || class_name == vmSymbols::java_lang_Integer() ||
class_name() == vmSymbols::java_lang_Long())) { class_name == vmSymbols::java_lang_Long())) {
allocation_style = 0; // Allocate oops first allocation_style = 0; // Allocate oops first
compact_fields = false; // Don't compact fields compact_fields = false; // Don't compact fields
} }
@ -3543,6 +3571,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
this_klass->set_has_nonstatic_fields(has_nonstatic_fields); this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
this_klass->set_static_oop_field_size(fac.static_oop_count); this_klass->set_static_oop_field_size(fac.static_oop_count);
cp->set_pool_holder(this_klass()); 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_constants(cp());
this_klass->set_local_interfaces(local_interfaces()); this_klass->set_local_interfaces(local_interfaces());
this_klass->set_fields(fields()); this_klass->set_fields(fields());
@ -3935,7 +3964,7 @@ void ClassFileParser::check_super_class_access(instanceKlassHandle this_klass, T
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_IllegalAccessError(), vmSymbols::java_lang_IllegalAccessError(),
"class %s cannot access its superclass %s", "class %s cannot access its superclass %s",
this_klass->external_name(), this_klass->external_name(),
instanceKlass::cast(super)->external_name() instanceKlass::cast(super)->external_name()
@ -3955,7 +3984,7 @@ void ClassFileParser::check_super_interface_access(instanceKlassHandle this_klas
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_IllegalAccessError(), vmSymbols::java_lang_IllegalAccessError(),
"class %s cannot access its superinterface %s", "class %s cannot access its superinterface %s",
this_klass->external_name(), this_klass->external_name(),
instanceKlass::cast(k)->external_name() instanceKlass::cast(k)->external_name()
@ -3979,8 +4008,8 @@ void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass
(!m->is_static()) && (!m->is_static()) &&
(m->name() != vmSymbols::object_initializer_name())) { (m->name() != vmSymbols::object_initializer_name())) {
symbolOop name = m->name(); Symbol* name = m->name();
symbolOop signature = m->signature(); Symbol* signature = m->signature();
klassOop k = this_klass->super(); klassOop k = this_klass->super();
methodOop super_m = NULL; methodOop super_m = NULL;
while (k != NULL) { while (k != NULL) {
@ -4003,7 +4032,7 @@ void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_VerifyError(), vmSymbols::java_lang_VerifyError(),
"class %s overrides final method %s.%s", "class %s overrides final method %s.%s",
this_klass->external_name(), this_klass->external_name(),
name->as_C_string(), name->as_C_string(),
@ -4037,7 +4066,7 @@ void ClassFileParser::check_illegal_static_method(instanceKlassHandle this_klass
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_VerifyError(), vmSymbols::java_lang_VerifyError(),
"Illegal static method %s in interface %s", "Illegal static method %s in interface %s",
m->name()->as_C_string(), m->name()->as_C_string(),
this_klass->external_name() this_klass->external_name()
@ -4067,7 +4096,7 @@ void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_ClassFormatError(), vmSymbols::java_lang_ClassFormatError(),
"Illegal class modifiers in class %s: 0x%X", "Illegal class modifiers in class %s: 0x%X",
_class_name->as_C_string(), flags _class_name->as_C_string(), flags
); );
@ -4127,7 +4156,7 @@ void ClassFileParser::verify_legal_field_modifiers(
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_ClassFormatError(), vmSymbols::java_lang_ClassFormatError(),
"Illegal field modifiers in class %s: 0x%X", "Illegal field modifiers in class %s: 0x%X",
_class_name->as_C_string(), flags); _class_name->as_C_string(), flags);
return; return;
@ -4135,7 +4164,7 @@ void ClassFileParser::verify_legal_field_modifiers(
} }
void ClassFileParser::verify_legal_method_modifiers( 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; } if (!_need_verify) { return; }
const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; const bool is_public = (flags & JVM_ACC_PUBLIC) != 0;
@ -4180,7 +4209,7 @@ void ClassFileParser::verify_legal_method_modifiers(
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_ClassFormatError(), vmSymbols::java_lang_ClassFormatError(),
"Method %s in class %s has illegal modifiers: 0x%X", "Method %s in class %s has illegal modifiers: 0x%X",
name->as_C_string(), _class_name->as_C_string(), flags); name->as_C_string(), _class_name->as_C_string(), flags);
return; return;
@ -4251,7 +4280,7 @@ void ClassFileParser::verify_legal_utf8(const unsigned char* buffer, int length,
} }
// Checks if name is a legal class name. // 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; } if (!_need_verify || _relax_verify) { return; }
char buf[fixed_buffer_size]; char buf[fixed_buffer_size];
@ -4281,7 +4310,7 @@ void ClassFileParser::verify_legal_class_name(symbolHandle name, TRAPS) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_ClassFormatError(), vmSymbols::java_lang_ClassFormatError(),
"Illegal class name \"%s\" in class file %s", bytes, "Illegal class name \"%s\" in class file %s", bytes,
_class_name->as_C_string() _class_name->as_C_string()
); );
@ -4290,7 +4319,7 @@ void ClassFileParser::verify_legal_class_name(symbolHandle name, TRAPS) {
} }
// Checks if name is a legal field name. // 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; } if (!_need_verify || _relax_verify) { return; }
char buf[fixed_buffer_size]; char buf[fixed_buffer_size];
@ -4314,7 +4343,7 @@ void ClassFileParser::verify_legal_field_name(symbolHandle name, TRAPS) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_ClassFormatError(), vmSymbols::java_lang_ClassFormatError(),
"Illegal field name \"%s\" in class %s", bytes, "Illegal field name \"%s\" in class %s", bytes,
_class_name->as_C_string() _class_name->as_C_string()
); );
@ -4323,10 +4352,10 @@ void ClassFileParser::verify_legal_field_name(symbolHandle name, TRAPS) {
} }
// Checks if name is a legal method name. // 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; } 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 buf[fixed_buffer_size];
char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
unsigned int length = name->utf8_length(); unsigned int length = name->utf8_length();
@ -4351,7 +4380,7 @@ void ClassFileParser::verify_legal_method_name(symbolHandle name, TRAPS) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Exceptions::fthrow( Exceptions::fthrow(
THREAD_AND_LOCATION, THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_ClassFormatError(), vmSymbols::java_lang_ClassFormatError(),
"Illegal method name \"%s\" in class %s", bytes, "Illegal method name \"%s\" in class %s", bytes,
_class_name->as_C_string() _class_name->as_C_string()
); );
@ -4361,7 +4390,7 @@ void ClassFileParser::verify_legal_method_name(symbolHandle name, TRAPS) {
// Checks if signature is a legal field signature. // 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; } if (!_need_verify) { return; }
char buf[fixed_buffer_size]; char buf[fixed_buffer_size];
@ -4376,7 +4405,7 @@ void ClassFileParser::verify_legal_field_signature(symbolHandle name, symbolHand
// Checks if signature is a legal method signature. // Checks if signature is a legal method signature.
// Returns number of parameters // 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) { if (!_need_verify) {
// make sure caller's args_size will be less than 0 even for non-static // 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(). // method so it will be recomputed in compute_size_of_parameters().
@ -4508,8 +4537,8 @@ char* ClassFileParser::skip_over_field_name(char* name, bool slash_ok, unsigned
// public static boolean isJavaIdentifierStart(char ch); // public static boolean isJavaIdentifierStart(char ch);
JavaCalls::call_static(&result, JavaCalls::call_static(&result,
klass, klass,
vmSymbolHandles::isJavaIdentifierStart_name(), vmSymbols::isJavaIdentifierStart_name(),
vmSymbolHandles::int_bool_signature(), vmSymbols::int_bool_signature(),
&args, &args,
THREAD); THREAD);
@ -4525,8 +4554,8 @@ char* ClassFileParser::skip_over_field_name(char* name, bool slash_ok, unsigned
// public static boolean isJavaIdentifierPart(char ch); // public static boolean isJavaIdentifierPart(char ch);
JavaCalls::call_static(&result, JavaCalls::call_static(&result,
klass, klass,
vmSymbolHandles::isJavaIdentifierPart_name(), vmSymbols::isJavaIdentifierPart_name(),
vmSymbolHandles::int_bool_signature(), vmSymbols::int_bool_signature(),
&args, &args,
THREAD); THREAD);

View File

@ -32,6 +32,7 @@
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "utilities/accessFlags.hpp" #include "utilities/accessFlags.hpp"
class TempNewSymbol;
// Parser for for .class files // Parser for for .class files
// //
// The bytes describing the class file structure is read from a Stream object // The bytes describing the class file structure is read from a Stream object
@ -42,7 +43,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
bool _relax_verify; bool _relax_verify;
u2 _major_version; u2 _major_version;
u2 _minor_version; u2 _minor_version;
symbolHandle _class_name; Symbol* _class_name;
KlassHandle _host_klass; KlassHandle _host_klass;
GrowableArray<Handle>* _cp_patches; // overrides for CP entries GrowableArray<Handle>* _cp_patches; // overrides for CP entries
@ -73,7 +74,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int length, int length,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
symbolHandle class_name, Symbol* class_name,
TRAPS); TRAPS);
// Field parsing // Field parsing
@ -209,21 +210,21 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
} }
void throwIllegalSignature( 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 is_supported_version(u2 major, u2 minor);
bool has_illegal_visibility(jint flags); bool has_illegal_visibility(jint flags);
void verify_constantvalue(int constantvalue_index, int signature_index, constantPoolHandle cp, TRAPS); 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_utf8(const unsigned char* buffer, int length, TRAPS);
void verify_legal_class_name(symbolHandle name, TRAPS); void verify_legal_class_name(Symbol* name, TRAPS);
void verify_legal_field_name(symbolHandle name, TRAPS); void verify_legal_field_name(Symbol* name, TRAPS);
void verify_legal_method_name(symbolHandle name, TRAPS); void verify_legal_method_name(Symbol* name, TRAPS);
void verify_legal_field_signature(symbolHandle fieldname, symbolHandle signature, TRAPS); void verify_legal_field_signature(Symbol* fieldname, Symbol* signature, TRAPS);
int verify_legal_method_signature(symbolHandle methodname, symbolHandle signature, TRAPS); int verify_legal_method_signature(Symbol* methodname, Symbol* signature, TRAPS);
void verify_legal_class_modifiers(jint flags, TRAPS); void verify_legal_class_modifiers(jint flags, TRAPS);
void verify_legal_field_modifiers(jint flags, bool is_interface, 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); 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_name(char* name, bool slash_ok, unsigned int length);
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS); char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
@ -272,21 +273,21 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
// //
// "parsed_name" is updated by this method, and is the name found // "parsed_name" is updated by this method, and is the name found
// while parsing the stream. // while parsing the stream.
instanceKlassHandle parseClassFile(symbolHandle name, instanceKlassHandle parseClassFile(Symbol* name,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
symbolHandle& parsed_name, TempNewSymbol& parsed_name,
bool verify, bool verify,
TRAPS) { TRAPS) {
KlassHandle no_host_klass; KlassHandle no_host_klass;
return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD); 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 class_loader,
Handle protection_domain, Handle protection_domain,
KlassHandle host_klass, KlassHandle host_klass,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
symbolHandle& parsed_name, TempNewSymbol& parsed_name,
bool verify, bool verify,
TRAPS); TRAPS);

View File

@ -41,7 +41,7 @@
#include "oops/instanceKlass.hpp" #include "oops/instanceKlass.hpp"
#include "oops/instanceRefKlass.hpp" #include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
#include "prims/jvm_misc.hpp" #include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp" #include "runtime/arguments.hpp"
#include "runtime/compilationPolicy.hpp" #include "runtime/compilationPolicy.hpp"
@ -752,11 +752,7 @@ void PackageHashtable::copy_table(char** top, char* end,
} }
} }
if (*top + n + sizeof(intptr_t) >= end) { if (*top + n + sizeof(intptr_t) >= end) {
warning("\nThe shared miscellaneous data space is not large " report_out_of_shared_space(SharedMiscData);
"enough to \npreload requested classes. Use "
"-XX:SharedMiscDataSize= to increase \nthe initial "
"size of the miscellaneous data space.\n");
exit(2);
} }
// Copy the table data (the strings) to the shared space. // Copy the table data (the strings) to the shared space.
@ -875,9 +871,9 @@ objArrayOop ClassLoader::get_system_packages(TRAPS) {
} }
instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) { instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
ResourceMark rm(THREAD); 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); ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
stringStream st; stringStream st;
@ -912,7 +908,7 @@ instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {
ClassFileParser parser(stream); ClassFileParser parser(stream);
Handle class_loader; Handle class_loader;
Handle protection_domain; Handle protection_domain;
symbolHandle parsed_name; TempNewSymbol parsed_name = NULL;
instanceKlassHandle result = parser.parseClassFile(h_name, instanceKlassHandle result = parser.parseClassFile(h_name,
class_loader, class_loader,
protection_domain, protection_domain,
@ -1308,7 +1304,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
if (_compile_the_world_counter > CompileTheWorldStopAt) return; if (_compile_the_world_counter > CompileTheWorldStopAt) return;
// Construct name without extension // 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 // Use loader to load and initialize class
klassOop ik = SystemDictionary::resolve_or_null(sym, loader, Handle(), THREAD); klassOop ik = SystemDictionary::resolve_or_null(sym, loader, Handle(), THREAD);
instanceKlassHandle k (THREAD, ik); instanceKlassHandle k (THREAD, ik);

View File

@ -280,7 +280,7 @@ class ClassLoader: AllStatic {
} }
// Load individual .class file // 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 // 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. // the name of the directory or ZIP file that the package was loaded from.

View File

@ -36,7 +36,7 @@ int Dictionary::_current_class_index = 0;
Dictionary::Dictionary(int table_size) Dictionary::Dictionary(int table_size)
: TwoOopHashtable(table_size, sizeof(DictionaryEntry)) { : TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry)) {
_current_class_index = 0; _current_class_index = 0;
_current_class_entry = NULL; _current_class_entry = NULL;
}; };
@ -45,7 +45,7 @@ Dictionary::Dictionary(int table_size)
Dictionary::Dictionary(int table_size, HashtableBucket* t, Dictionary::Dictionary(int table_size, HashtableBucket* t,
int number_of_entries) int number_of_entries)
: TwoOopHashtable(table_size, sizeof(DictionaryEntry), t, number_of_entries) { : TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry), t, number_of_entries) {
_current_class_index = 0; _current_class_index = 0;
_current_class_entry = NULL; _current_class_entry = NULL;
}; };
@ -54,7 +54,7 @@ Dictionary::Dictionary(int table_size, HashtableBucket* t,
DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass, DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass,
oop loader) { oop loader) {
DictionaryEntry* entry; DictionaryEntry* entry;
entry = (DictionaryEntry*)Hashtable::new_entry(hash, klass); entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(hash, klass);
entry->set_loader(loader); entry->set_loader(loader);
entry->set_pd_set(NULL); entry->set_pd_set(NULL);
return entry; return entry;
@ -62,7 +62,7 @@ DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass,
DictionaryEntry* Dictionary::new_entry() { DictionaryEntry* Dictionary::new_entry() {
DictionaryEntry* entry = (DictionaryEntry*)Hashtable::new_entry(0L, NULL); DictionaryEntry* entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(0L, NULL);
entry->set_loader(NULL); entry->set_loader(NULL);
entry->set_pd_set(NULL); entry->set_pd_set(NULL);
return entry; return entry;
@ -76,7 +76,7 @@ void Dictionary::free_entry(DictionaryEntry* entry) {
entry->set_pd_set(to_delete->next()); entry->set_pd_set(to_delete->next());
delete to_delete; delete to_delete;
} }
Hashtable::free_entry(entry); Hashtable<klassOop>::free_entry(entry);
} }
@ -298,7 +298,7 @@ void Dictionary::always_strong_classes_do(OopClosure* blk) {
for (DictionaryEntry *probe = bucket(index); for (DictionaryEntry *probe = bucket(index);
probe != NULL; probe != NULL;
probe = probe->next()) { probe = probe->next()) {
oop e = probe->klass(); klassOop e = probe->klass();
oop class_loader = probe->loader(); oop class_loader = probe->loader();
if (is_strongly_reachable(class_loader, e)) { if (is_strongly_reachable(class_loader, e)) {
blk->do_oop((oop*)probe->klass_addr()); blk->do_oop((oop*)probe->klass_addr());
@ -421,11 +421,11 @@ klassOop Dictionary::try_get_next_class() {
// also cast to volatile; we do this to ensure store order is maintained // also cast to volatile; we do this to ensure store order is maintained
// by the compilers. // 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) { KlassHandle obj) {
assert_locked_or_safepoint(SystemDictionary_lock); assert_locked_or_safepoint(SystemDictionary_lock);
assert(obj() != NULL, "adding NULL obj"); 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); unsigned int hash = compute_hash(class_name, class_loader);
int index = hash_to_index(hash); int index = hash_to_index(hash);
@ -444,15 +444,14 @@ void Dictionary::add_klass(symbolHandle class_name, Handle class_loader,
// Callers should be aware that an entry could be added just after // 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. // _buckets[index] is read here, so the caller will not see the new entry.
DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash, DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
symbolHandle class_name, Symbol* class_name,
Handle class_loader) { Handle class_loader) {
symbolOop name_ = class_name(); oop loader = class_loader();
oop loader_ = class_loader();
debug_only(_lookup_count++); debug_only(_lookup_count++);
for (DictionaryEntry* entry = bucket(index); for (DictionaryEntry* entry = bucket(index);
entry != NULL; entry != NULL;
entry = entry->next()) { entry = entry->next()) {
if (entry->hash() == hash && entry->equals(name_, loader_)) { if (entry->hash() == hash && entry->equals(class_name, loader)) {
return entry; return entry;
} }
debug_only(_lookup_length++); debug_only(_lookup_length++);
@ -461,7 +460,7 @@ DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
} }
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) { Handle loader, Handle protection_domain, TRAPS) {
DictionaryEntry* entry = get_entry(index, hash, name, loader); DictionaryEntry* entry = get_entry(index, hash, name, loader);
if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {
@ -473,7 +472,7 @@ klassOop Dictionary::find(int index, unsigned int hash, symbolHandle name,
klassOop Dictionary::find_class(int index, unsigned int hash, klassOop Dictionary::find_class(int index, unsigned int hash,
symbolHandle name, Handle loader) { Symbol* name, Handle loader) {
assert_locked_or_safepoint(SystemDictionary_lock); assert_locked_or_safepoint(SystemDictionary_lock);
assert (index == index_for(name, loader), "incorrect index?"); assert (index == index_for(name, loader), "incorrect index?");
@ -486,7 +485,7 @@ klassOop Dictionary::find_class(int index, unsigned int hash,
// that table is static. // that table is static.
klassOop Dictionary::find_shared_class(int index, unsigned int hash, klassOop Dictionary::find_shared_class(int index, unsigned int hash,
symbolHandle name) { Symbol* name) {
assert (index == index_for(name, Handle()), "incorrect index?"); assert (index == index_for(name, Handle()), "incorrect index?");
DictionaryEntry* entry = get_entry(index, hash, name, Handle()); DictionaryEntry* entry = get_entry(index, hash, name, Handle());
@ -498,7 +497,7 @@ void Dictionary::add_protection_domain(int index, unsigned int hash,
instanceKlassHandle klass, instanceKlassHandle klass,
Handle loader, Handle protection_domain, Handle loader, Handle protection_domain,
TRAPS) { TRAPS) {
symbolHandle klass_name(THREAD, klass->name()); Symbol* klass_name = klass->name();
DictionaryEntry* entry = get_entry(index, hash, klass_name, loader); DictionaryEntry* entry = get_entry(index, hash, klass_name, loader);
assert(entry != NULL,"entry must be present, we just created it"); assert(entry != NULL,"entry must be present, we just created it");
@ -513,7 +512,7 @@ void Dictionary::add_protection_domain(int index, unsigned int hash,
bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, bool Dictionary::is_valid_protection_domain(int index, unsigned int hash,
symbolHandle name, Symbol* name,
Handle loader, Handle loader,
Handle protection_domain) { Handle protection_domain) {
DictionaryEntry* entry = get_entry(index, hash, name, loader); DictionaryEntry* entry = get_entry(index, hash, name, loader);
@ -545,7 +544,7 @@ void Dictionary::reorder_dictionary() {
DictionaryEntry* p = master_list; DictionaryEntry* p = master_list;
master_list = master_list->next(); master_list = master_list->next();
p->set_next(NULL); 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())); unsigned int hash = compute_hash(class_name, Handle(thread, p->loader()));
int index = hash_to_index(hash); int index = hash_to_index(hash);
p->set_hash(hash); p->set_hash(hash);
@ -555,22 +554,22 @@ void Dictionary::reorder_dictionary() {
} }
SymbolPropertyTable::SymbolPropertyTable(int table_size) SymbolPropertyTable::SymbolPropertyTable(int table_size)
: Hashtable(table_size, sizeof(SymbolPropertyEntry)) : Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry))
{ {
} }
SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t, SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t,
int number_of_entries) int number_of_entries)
: Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) : Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
{ {
} }
SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash, SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash,
symbolHandle sym, Symbol* sym,
intptr_t sym_mode) { intptr_t sym_mode) {
assert(index == index_for(sym, sym_mode), "incorrect index?"); assert(index == index_for(sym, sym_mode), "incorrect index?");
for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { 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; return p;
} }
} }
@ -579,13 +578,13 @@ SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int has
SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash, 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_locked_or_safepoint(SystemDictionary_lock);
assert(index == index_for(sym, sym_mode), "incorrect index?"); assert(index == index_for(sym, sym_mode), "incorrect index?");
assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry"); assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry");
SymbolPropertyEntry* p = new_entry(hash, sym(), sym_mode); SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode);
Hashtable::add_entry(index, p); Hashtable<Symbol*>::add_entry(index, p);
return p; return p;
} }
@ -593,7 +592,6 @@ SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash
void SymbolPropertyTable::oops_do(OopClosure* f) { void SymbolPropertyTable::oops_do(OopClosure* f) {
for (int index = 0; index < table_size(); index++) { for (int index = 0; index < table_size(); index++) {
for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {
f->do_oop((oop*) p->symbol_addr());
if (p->property_oop() != NULL) { if (p->property_oop() != NULL) {
f->do_oop(p->property_oop_addr()); f->do_oop(p->property_oop_addr());
} }

View File

@ -36,7 +36,7 @@ class DictionaryEntry;
// The data structure for the system dictionary (and the shared system // The data structure for the system dictionary (and the shared system
// dictionary). // dictionary).
class Dictionary : public TwoOopHashtable { class Dictionary : public TwoOopHashtable<klassOop> {
friend class VMStructs; friend class VMStructs;
private: private:
// current iteration index. // current iteration index.
@ -45,19 +45,19 @@ private:
static DictionaryEntry* _current_class_entry; static DictionaryEntry* _current_class_entry;
DictionaryEntry* get_entry(int index, unsigned int hash, DictionaryEntry* get_entry(int index, unsigned int hash,
symbolHandle name, Handle loader); Symbol* name, Handle loader);
DictionaryEntry* bucket(int i) { DictionaryEntry* bucket(int i) {
return (DictionaryEntry*)Hashtable::bucket(i); return (DictionaryEntry*)Hashtable<klassOop>::bucket(i);
} }
// The following method is not MT-safe and must be done under lock. // The following method is not MT-safe and must be done under lock.
DictionaryEntry** bucket_addr(int i) { DictionaryEntry** bucket_addr(int i) {
return (DictionaryEntry**)Hashtable::bucket_addr(i); return (DictionaryEntry**)Hashtable<klassOop>::bucket_addr(i);
} }
void add_entry(int index, DictionaryEntry* new_entry) { void add_entry(int index, DictionaryEntry* new_entry) {
Hashtable::add_entry(index, (HashtableEntry*)new_entry); Hashtable<klassOop>::add_entry(index, (HashtableEntry<oop>*)new_entry);
} }
@ -71,12 +71,12 @@ public:
void free_entry(DictionaryEntry* entry); 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, 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 // Compiler support
klassOop try_get_next_class(); klassOop try_get_next_class();
@ -95,7 +95,7 @@ public:
// Classes loaded by the bootstrap loader are always strongly reachable. // Classes loaded by the bootstrap loader are always strongly reachable.
// If we're not doing class unloading, all classes are 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"); assert (klass != NULL, "should have non-null klass");
return (class_loader == NULL || !ClassUnloading); return (class_loader == NULL || !ClassUnloading);
} }
@ -105,10 +105,10 @@ public:
bool do_unloading(BoolObjectClosure* is_alive); bool do_unloading(BoolObjectClosure* is_alive);
// Protection domains // 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); Handle loader, Handle protection_domain, TRAPS);
bool is_valid_protection_domain(int index, unsigned int hash, bool is_valid_protection_domain(int index, unsigned int hash,
symbolHandle name, Handle class_loader, Symbol* name, Handle class_loader,
Handle protection_domain); Handle protection_domain);
void add_protection_domain(int index, unsigned int hash, void add_protection_domain(int index, unsigned int hash,
instanceKlassHandle klass, Handle loader, instanceKlassHandle klass, Handle loader,
@ -147,7 +147,7 @@ class ProtectionDomainEntry :public CHeapObj {
// An entry in the system dictionary, this describes a class as // An entry in the system dictionary, this describes a class as
// { klassOop, loader, protection_domain }. // { klassOop, loader, protection_domain }.
class DictionaryEntry : public HashtableEntry { class DictionaryEntry : public HashtableEntry<klassOop> {
friend class VMStructs; friend class VMStructs;
private: private:
// Contains the set of approved protection domains that can access // Contains the set of approved protection domains that can access
@ -166,11 +166,11 @@ class DictionaryEntry : public HashtableEntry {
klassOop* klass_addr() { return (klassOop*)literal_addr(); } klassOop* klass_addr() { return (klassOop*)literal_addr(); }
DictionaryEntry* next() const { DictionaryEntry* next() const {
return (DictionaryEntry*)HashtableEntry::next(); return (DictionaryEntry*)HashtableEntry<klassOop>::next();
} }
DictionaryEntry** next_addr() { DictionaryEntry** next_addr() {
return (DictionaryEntry**)HashtableEntry::next_addr(); return (DictionaryEntry**)HashtableEntry<klassOop>::next_addr();
} }
oop loader() const { return _loader; } oop loader() const { return _loader; }
@ -209,7 +209,7 @@ class DictionaryEntry : public HashtableEntry {
} }
} }
bool equals(symbolOop class_name, oop class_loader) const { bool equals(Symbol* class_name, oop class_loader) const {
klassOop klass = (klassOop)literal(); klassOop klass = (klassOop)literal();
return (instanceKlass::cast(klass)->name() == class_name && return (instanceKlass::cast(klass)->name() == class_name &&
_loader == class_loader); _loader == class_loader);
@ -226,9 +226,9 @@ class DictionaryEntry : public HashtableEntry {
} }
}; };
// Entry in a SymbolPropertyTable, mapping a single symbolOop // Entry in a SymbolPropertyTable, mapping a single Symbol*
// to a managed and an unmanaged pointer. // to a managed and an unmanaged pointer.
class SymbolPropertyEntry : public HashtableEntry { class SymbolPropertyEntry : public HashtableEntry<Symbol*> {
friend class VMStructs; friend class VMStructs;
private: private:
intptr_t _symbol_mode; // secondary key intptr_t _symbol_mode; // secondary key
@ -236,7 +236,7 @@ class SymbolPropertyEntry : public HashtableEntry {
address _property_data; address _property_data;
public: public:
symbolOop symbol() const { return (symbolOop) literal(); } Symbol* symbol() const { return literal(); }
intptr_t symbol_mode() const { return _symbol_mode; } intptr_t symbol_mode() const { return _symbol_mode; }
void set_symbol_mode(intptr_t m) { _symbol_mode = m; } void set_symbol_mode(intptr_t m) { _symbol_mode = m; }
@ -248,14 +248,13 @@ class SymbolPropertyEntry : public HashtableEntry {
void set_property_data(address p) { _property_data = p; } void set_property_data(address p) { _property_data = p; }
SymbolPropertyEntry* next() const { SymbolPropertyEntry* next() const {
return (SymbolPropertyEntry*)HashtableEntry::next(); return (SymbolPropertyEntry*)HashtableEntry<Symbol*>::next();
} }
SymbolPropertyEntry** next_addr() { SymbolPropertyEntry** next_addr() {
return (SymbolPropertyEntry**)HashtableEntry::next_addr(); return (SymbolPropertyEntry**)HashtableEntry<Symbol*>::next_addr();
} }
oop* symbol_addr() { return literal_addr(); }
oop* property_oop_addr() { return &_property_oop; } oop* property_oop_addr() { return &_property_oop; }
void print_on(outputStream* st) const { void print_on(outputStream* st) const {
@ -279,16 +278,16 @@ class SymbolPropertyEntry : public HashtableEntry {
// A system-internal mapping of symbols to pointers, both managed // A system-internal mapping of symbols to pointers, both managed
// and unmanaged. Used to record the auto-generation of each method // and unmanaged. Used to record the auto-generation of each method
// MethodHandle.invoke(S)T, for all signatures (S)T. // MethodHandle.invoke(S)T, for all signatures (S)T.
class SymbolPropertyTable : public Hashtable { class SymbolPropertyTable : public Hashtable<Symbol*> {
friend class VMStructs; friend class VMStructs;
private: private:
SymbolPropertyEntry* bucket(int i) { SymbolPropertyEntry* bucket(int i) {
return (SymbolPropertyEntry*) Hashtable::bucket(i); return (SymbolPropertyEntry*) Hashtable<Symbol*>::bucket(i);
} }
// The following method is not MT-safe and must be done under lock. // The following method is not MT-safe and must be done under lock.
SymbolPropertyEntry** bucket_addr(int i) { SymbolPropertyEntry** bucket_addr(int i) {
return (SymbolPropertyEntry**) Hashtable::bucket_addr(i); return (SymbolPropertyEntry**) Hashtable<Symbol*>::bucket_addr(i);
} }
void add_entry(int index, SymbolPropertyEntry* new_entry) { void add_entry(int index, SymbolPropertyEntry* new_entry) {
@ -298,8 +297,10 @@ private:
ShouldNotReachHere(); ShouldNotReachHere();
} }
SymbolPropertyEntry* new_entry(unsigned int hash, symbolOop symbol, intptr_t symbol_mode) { SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {
SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable::new_entry(hash, symbol); SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*>::new_entry(hash, symbol);
// Hashtable with Symbol* literal must increment and decrement refcount.
symbol->increment_refcount();
entry->set_symbol_mode(symbol_mode); entry->set_symbol_mode(symbol_mode);
entry->set_property_oop(NULL); entry->set_property_oop(NULL);
entry->set_property_data(NULL); entry->set_property_data(NULL);
@ -311,23 +312,25 @@ public:
SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries); SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries);
void free_entry(SymbolPropertyEntry* entry) { void free_entry(SymbolPropertyEntry* entry) {
Hashtable::free_entry(entry); // decrement Symbol refcount here because hashtable doesn't.
entry->literal()->decrement_refcount();
Hashtable<Symbol*>::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. // Use the regular identity_hash.
return Hashtable::compute_hash(sym) ^ symbol_mode; return Hashtable<Symbol*>::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)); return hash_to_index(compute_hash(name, symbol_mode));
} }
// need not be locked; no state change // 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 // 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 // GC support
void oops_do(OopClosure* f); void oops_do(OopClosure* f);
@ -343,6 +346,4 @@ public:
#endif #endif
void verify(); void verify();
}; };
#endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP #endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP

View File

@ -93,7 +93,7 @@ void JavaAssertions::addOption(const char* name, bool enable) {
} }
oop JavaAssertions::createAssertionStatusDirectives(TRAPS) { 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); klassOop k = SystemDictionary::resolve_or_fail(asd_sym, true, CHECK_NULL);
instanceKlassHandle asd_klass (THREAD, k); instanceKlassHandle asd_klass (THREAD, k);
asd_klass->initialize(CHECK_NULL); asd_klass->initialize(CHECK_NULL);

View File

@ -36,7 +36,7 @@
#include "oops/klass.hpp" #include "oops/klass.hpp"
#include "oops/klassOop.hpp" #include "oops/klassOop.hpp"
#include "oops/methodOop.hpp" #include "oops/methodOop.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
#include "oops/typeArrayOop.hpp" #include "oops/typeArrayOop.hpp"
#include "runtime/fieldDescriptor.hpp" #include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
@ -57,7 +57,7 @@
#endif #endif
static bool find_field(instanceKlass* ik, static bool find_field(instanceKlass* ik,
symbolOop name_symbol, symbolOop signature_symbol, Symbol* name_symbol, Symbol* signature_symbol,
fieldDescriptor* fd, fieldDescriptor* fd,
bool allow_super = false) { bool allow_super = false) {
if (allow_super) if (allow_super)
@ -69,7 +69,7 @@ static bool find_field(instanceKlass* ik,
// Helpful routine for computing field offsets at run time rather than hardcoding them // Helpful routine for computing field offsets at run time rather than hardcoding them
static void static void
compute_offset(int &dest_offset, 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) { bool allow_super = false) {
fieldDescriptor fd; fieldDescriptor fd;
instanceKlass* ik = instanceKlass::cast(klass_oop); instanceKlass* ik = instanceKlass::cast(klass_oop);
@ -84,7 +84,7 @@ compute_offset(int &dest_offset,
// Same as above but for "optional" offsets that might not be present in certain JDK versions // Same as above but for "optional" offsets that might not be present in certain JDK versions
static void static void
compute_optional_offset(int& dest_offset, 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) { bool allow_super = false) {
fieldDescriptor fd; fieldDescriptor fd;
instanceKlass* ik = instanceKlass::cast(klass_oop); instanceKlass* ik = instanceKlass::cast(klass_oop);
@ -164,7 +164,7 @@ oop java_lang_String::create_oop_from_str(const char* utf8_str, TRAPS) {
return h_obj(); 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()); int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length());
Handle h_obj = basic_create(length, false, CHECK_NH); Handle h_obj = basic_create(length, false, CHECK_NH);
if (length > 0) { if (length > 0) {
@ -278,17 +278,17 @@ jchar* java_lang_String::as_unicode_string(oop java_string, int& length) {
return result; 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(); oop obj = java_string();
typeArrayOop value = java_lang_String::value(obj); typeArrayOop value = java_lang_String::value(obj);
int offset = java_lang_String::offset(obj); int offset = java_lang_String::offset(obj);
int length = java_lang_String::length(obj); int length = java_lang_String::length(obj);
jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
symbolOop sym = SymbolTable::lookup_unicode(base, length, THREAD); Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD);
return symbolHandle(THREAD, sym); 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); typeArrayOop value = java_lang_String::value(java_string);
int offset = java_lang_String::offset(java_string); int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string); int length = java_lang_String::length(java_string);
@ -437,7 +437,7 @@ klassOop java_lang_Class::as_klassOop(oop java_class) {
void java_lang_Class::print_signature(oop java_class, outputStream* st) { void java_lang_Class::print_signature(oop java_class, outputStream* st) {
assert(java_lang_Class::is_instance(java_class), "must be a Class object"); assert(java_lang_Class::is_instance(java_class), "must be a Class object");
symbolOop name = NULL; Symbol* name = NULL;
bool is_instance = false; bool is_instance = false;
if (is_primitive(java_class)) { if (is_primitive(java_class)) {
name = vmSymbols::type_signature(primitive_type(java_class)); name = vmSymbols::type_signature(primitive_type(java_class));
@ -455,25 +455,32 @@ void java_lang_Class::print_signature(oop java_class, outputStream* st) {
if (is_instance) st->print(";"); 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"); assert(java_lang_Class::is_instance(java_class), "must be a Class object");
symbolOop name = NULL; Symbol* name;
if (is_primitive(java_class)) { 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 { } else {
klassOop k = as_klassOop(java_class); klassOop k = as_klassOop(java_class);
if (!Klass::cast(k)->oop_is_instance()) { if (!Klass::cast(k)->oop_is_instance()) {
return Klass::cast(k)->name(); name = Klass::cast(k)->name();
name->increment_refcount();
} else { } else {
ResourceMark rm; ResourceMark rm;
const char* sigstr = Klass::cast(k)->signature_name(); const char* sigstr = Klass::cast(k)->signature_name();
int siglen = (int) strlen(sigstr); int siglen = (int) strlen(sigstr);
if (!intern_if_not_found) if (!intern_if_not_found) {
return SymbolTable::probe(sigstr, siglen); name = SymbolTable::probe(sigstr, siglen);
else } else {
return oopFactory::new_symbol(sigstr, siglen, THREAD); name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
}
} }
} }
return name;
} }
@ -1022,8 +1029,8 @@ void java_lang_Throwable::print_to_stream(Handle stream, const char* str) {
JavaCalls::call_virtual(&result, JavaCalls::call_virtual(&result,
stream, stream,
KlassHandle(THREAD, stream->klass()), KlassHandle(THREAD, stream->klass()),
vmSymbolHandles::println_name(), vmSymbols::println_name(),
vmSymbolHandles::char_array_void_signature(), vmSymbols::char_array_void_signature(),
arg, arg,
THREAD); THREAD);
} }
@ -1077,8 +1084,8 @@ void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) {
JavaCalls::call_virtual(&result, JavaCalls::call_virtual(&result,
h_throwable, h_throwable,
KlassHandle(THREAD, h_throwable->klass()), KlassHandle(THREAD, h_throwable->klass()),
vmSymbolHandles::getCause_name(), vmSymbols::getCause_name(),
vmSymbolHandles::void_throwable_signature(), vmSymbols::void_throwable_signature(),
THREAD); THREAD);
// Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
@ -1516,7 +1523,7 @@ oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
oop methodname = StringTable::intern(method->name(), CHECK_0); oop methodname = StringTable::intern(method->name(), CHECK_0);
java_lang_StackTraceElement::set_methodName(element(), methodname); java_lang_StackTraceElement::set_methodName(element(), methodname);
// Fill in source file name // 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); oop filename = StringTable::intern(source, CHECK_0);
java_lang_StackTraceElement::set_fileName(element(), filename); java_lang_StackTraceElement::set_fileName(element(), filename);
// File in source line number // File in source line number
@ -1732,7 +1739,7 @@ void java_lang_reflect_Constructor::compute_offsets() {
Handle java_lang_reflect_Constructor::create(TRAPS) { Handle java_lang_reflect_Constructor::create(TRAPS) {
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 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); klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
instanceKlassHandle klass (THREAD, k); instanceKlassHandle klass (THREAD, k);
// Ensure it is initialized // Ensure it is initialized
@ -1854,7 +1861,7 @@ void java_lang_reflect_Field::compute_offsets() {
Handle java_lang_reflect_Field::create(TRAPS) { Handle java_lang_reflect_Field::create(TRAPS) {
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 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); klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
instanceKlassHandle klass (THREAD, k); instanceKlassHandle klass (THREAD, k);
// Ensure it is initialized // Ensure it is initialized
@ -2422,16 +2429,19 @@ void java_dyn_MethodType::print_signature(oop mt, outputStream* st) {
java_lang_Class::print_signature(rtype(mt), st); 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; ResourceMark rm;
stringStream buffer(128); stringStream buffer(128);
print_signature(mt, &buffer); print_signature(mt, &buffer);
const char* sigstr = buffer.base(); const char* sigstr = buffer.base();
int siglen = (int) buffer.size(); int siglen = (int) buffer.size();
if (!intern_if_not_found) Symbol *name;
return SymbolTable::probe(sigstr, siglen); if (!intern_if_not_found) {
else name = SymbolTable::probe(sigstr, siglen);
return oopFactory::new_symbol(sigstr, siglen, THREAD); } else {
name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
}
return name;
} }
oop java_dyn_MethodType::rtype(oop mt) { oop java_dyn_MethodType::rtype(oop mt) {
@ -2908,13 +2918,12 @@ void JavaClasses::compute_offsets() {
bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) { bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
EXCEPTION_MARK; EXCEPTION_MARK;
fieldDescriptor fd; 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); klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
instanceKlassHandle h_klass (THREAD, k); instanceKlassHandle h_klass (THREAD, k);
//instanceKlassHandle h_klass(klass); TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) {
tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name); tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name);
return false; return false;
} }
@ -2935,12 +2944,12 @@ bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, con
bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) { bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
EXCEPTION_MARK; EXCEPTION_MARK;
fieldDescriptor fd; 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); klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
instanceKlassHandle h_klass (THREAD, k); instanceKlassHandle h_klass (THREAD, k);
symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) { if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
tty->print_cr("Static field %s.%s not found", klass_name, field_name); tty->print_cr("Static field %s.%s not found", klass_name, field_name);
return false; return false;
} }
@ -2960,12 +2969,12 @@ bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offs
bool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) { bool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) {
EXCEPTION_MARK; EXCEPTION_MARK;
fieldDescriptor fd; 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); klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
instanceKlassHandle h_klass (THREAD, k); instanceKlassHandle h_klass (THREAD, k);
symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) { if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
tty->print_cr("Static field %s.%s not found", klass_name, field_name); tty->print_cr("Static field %s.%s not found", klass_name, field_name);
return false; return false;
} }

View File

@ -78,7 +78,7 @@ class java_lang_String : AllStatic {
static oop create_oop_from_unicode(jchar* unicode, int len, TRAPS); static oop create_oop_from_unicode(jchar* unicode, int len, TRAPS);
static Handle create_from_str(const char* utf8_str, TRAPS); static Handle create_from_str(const char* utf8_str, TRAPS);
static oop create_oop_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 create_from_platform_dependent_str(const char* str, TRAPS);
static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS); static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS);
@ -116,8 +116,8 @@ class java_lang_String : AllStatic {
static Handle internalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '.', '/', THREAD); } static Handle internalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '.', '/', THREAD); }
// Conversion // Conversion
static symbolHandle as_symbol(Handle java_string, TRAPS); static Symbol* as_symbol(Handle java_string, TRAPS);
static symbolOop as_symbol_or_null(oop java_string); static Symbol* as_symbol_or_null(oop java_string);
// Testers // Testers
static bool is_instance(oop obj) { static bool is_instance(oop obj) {
@ -167,7 +167,7 @@ class java_lang_Class : AllStatic {
(*reference_klass) = KlassHandle(refk_oop); (*reference_klass) = KlassHandle(refk_oop);
return result; 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); static void print_signature(oop java_class, outputStream *st);
// Testing // Testing
static bool is_instance(oop obj) { static bool is_instance(oop obj) {
@ -1039,7 +1039,7 @@ class java_dyn_MethodType: AllStatic {
static oop ptype(oop mt, int index); static oop ptype(oop mt, int index);
static int ptype_count(oop mt); 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 void print_signature(oop mt, outputStream* st);
static bool is_instance(oop obj) { static bool is_instance(oop obj) {

View File

@ -31,28 +31,33 @@
#include "utilities/hashtable.inline.hpp" #include "utilities/hashtable.inline.hpp"
LoaderConstraintTable::LoaderConstraintTable(int nof_buckets) LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
: Hashtable(nof_buckets, sizeof(LoaderConstraintEntry)) {}; : Hashtable<klassOop>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
LoaderConstraintEntry* LoaderConstraintTable::new_entry( LoaderConstraintEntry* LoaderConstraintTable::new_entry(
unsigned int hash, symbolOop name, unsigned int hash, Symbol* name,
klassOop klass, int num_loaders, klassOop klass, int num_loaders,
int max_loaders) { int max_loaders) {
LoaderConstraintEntry* entry; LoaderConstraintEntry* entry;
entry = (LoaderConstraintEntry*)Hashtable::new_entry(hash, klass); entry = (LoaderConstraintEntry*)Hashtable<klassOop>::new_entry(hash, klass);
entry->set_name(name); entry->set_name(name);
entry->set_num_loaders(num_loaders); entry->set_num_loaders(num_loaders);
entry->set_max_loaders(max_loaders); entry->set_max_loaders(max_loaders);
return entry; return entry;
} }
void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) {
// decrement name refcount before freeing
entry->name()->decrement_refcount();
Hashtable<klassOop>::free_entry(entry);
}
void LoaderConstraintTable::oops_do(OopClosure* f) { void LoaderConstraintTable::oops_do(OopClosure* f) {
for (int index = 0; index < table_size(); index++) { for (int index = 0; index < table_size(); index++) {
for (LoaderConstraintEntry* probe = bucket(index); for (LoaderConstraintEntry* probe = bucket(index);
probe != NULL; probe != NULL;
probe = probe->next()) { probe = probe->next()) {
f->do_oop((oop*)(probe->name_addr()));
if (probe->klass() != NULL) { if (probe->klass() != NULL) {
f->do_oop((oop*)probe->klass_addr()); f->do_oop((oop*)probe->klass_addr());
} }
@ -65,27 +70,13 @@ void LoaderConstraintTable::oops_do(OopClosure* f) {
} }
} }
// 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 // The loaderConstraintTable must always be accessed with the
// SystemDictionary lock held. This is true even for readers as // SystemDictionary lock held. This is true even for readers as
// entries in the table could be being dynamically resized. // entries in the table could be being dynamically resized.
LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint( LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint(
symbolHandle name, Handle loader) { Symbol* name, Handle loader) {
unsigned int hash = compute_hash(name); unsigned int hash = compute_hash(name);
int index = hash_to_index(hash); int index = hash_to_index(hash);
@ -93,7 +84,7 @@ LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint(
while (*pp) { while (*pp) {
LoaderConstraintEntry* p = *pp; LoaderConstraintEntry* p = *pp;
if (p->hash() == hash) { if (p->hash() == hash) {
if (p->name() == name()) { if (p->name() == name) {
for (int i = p->num_loaders() - 1; i >= 0; i--) { for (int i = p->num_loaders() - 1; i >= 0; i--) {
if (p->loader(i) == loader()) { if (p->loader(i) == loader()) {
return pp; return pp;
@ -177,7 +168,6 @@ void LoaderConstraintTable::purge_loader_constraints(BoolObjectClosure* is_alive
free_entry(probe); free_entry(probe);
} else { } else {
#ifdef ASSERT #ifdef ASSERT
assert(is_alive->do_object_b(probe->name()), "name should be live");
if (probe->klass() != NULL) { if (probe->klass() != NULL) {
assert(is_alive->do_object_b(probe->klass()), "klass should be live"); assert(is_alive->do_object_b(probe->klass()), "klass should be live");
} }
@ -194,7 +184,7 @@ void LoaderConstraintTable::purge_loader_constraints(BoolObjectClosure* is_alive
} }
} }
bool LoaderConstraintTable::add_entry(symbolHandle class_name, bool LoaderConstraintTable::add_entry(Symbol* class_name,
klassOop klass1, Handle class_loader1, klassOop klass1, Handle class_loader1,
klassOop klass2, Handle class_loader2) { klassOop klass2, Handle class_loader2) {
int failure_code = 0; // encode different reasons for failing int failure_code = 0; // encode different reasons for failing
@ -233,7 +223,7 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
unsigned int hash = compute_hash(class_name); unsigned int hash = compute_hash(class_name);
int index = hash_to_index(hash); int index = hash_to_index(hash);
LoaderConstraintEntry* p; 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_loaders(NEW_C_HEAP_ARRAY(oop, 2));
p->set_loader(0, class_loader1()); p->set_loader(0, class_loader1());
p->set_loader(1, class_loader2()); p->set_loader(1, class_loader2());
@ -244,7 +234,7 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
ResourceMark rm; ResourceMark rm;
tty->print("[Adding new constraint for name: %s, loader[0]: %s," tty->print("[Adding new constraint for name: %s, loader[0]: %s,"
" loader[1]: %s ]\n", " loader[1]: %s ]\n",
class_name()->as_C_string(), class_name->as_C_string(),
SystemDictionary::loader_name(class_loader1()), SystemDictionary::loader_name(class_loader1()),
SystemDictionary::loader_name(class_loader2()) SystemDictionary::loader_name(class_loader2())
); );
@ -257,7 +247,7 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
ResourceMark rm; ResourceMark rm;
tty->print("[Setting class object in existing constraint for" tty->print("[Setting class object in existing constraint for"
" name: %s and loader %s ]\n", " name: %s and loader %s ]\n",
class_name()->as_C_string(), class_name->as_C_string(),
SystemDictionary::loader_name(class_loader1()) SystemDictionary::loader_name(class_loader1())
); );
} }
@ -288,7 +278,7 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
} }
tty->print("[Failed to add constraint for name: %s, loader[0]: %s," tty->print("[Failed to add constraint for name: %s, loader[0]: %s,"
" loader[1]: %s, Reason: %s ]\n", " 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_loader1()),
SystemDictionary::loader_name(class_loader2()), SystemDictionary::loader_name(class_loader2()),
reason reason
@ -303,14 +293,14 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
// violated // violated
bool LoaderConstraintTable::check_or_update(instanceKlassHandle k, bool LoaderConstraintTable::check_or_update(instanceKlassHandle k,
Handle loader, Handle loader,
symbolHandle name) { Symbol* name) {
LoaderConstraintEntry* p = *(find_loader_constraint(name, loader)); LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
if (p && p->klass() != NULL && p->klass() != k()) { if (p && p->klass() != NULL && p->klass() != k()) {
if (TraceLoaderConstraints) { if (TraceLoaderConstraints) {
ResourceMark rm; ResourceMark rm;
tty->print("[Constraint check failed for name %s, loader %s: " tty->print("[Constraint check failed for name %s, loader %s: "
"the presented class object differs from that stored ]\n", "the presented class object differs from that stored ]\n",
name()->as_C_string(), name->as_C_string(),
SystemDictionary::loader_name(loader())); SystemDictionary::loader_name(loader()));
} }
return false; return false;
@ -321,7 +311,7 @@ bool LoaderConstraintTable::check_or_update(instanceKlassHandle k,
ResourceMark rm; ResourceMark rm;
tty->print("[Updating constraint for name %s, loader %s, " tty->print("[Updating constraint for name %s, loader %s, "
"by setting class object ]\n", "by setting class object ]\n",
name()->as_C_string(), name->as_C_string(),
SystemDictionary::loader_name(loader())); SystemDictionary::loader_name(loader()));
} }
} }
@ -329,7 +319,7 @@ bool LoaderConstraintTable::check_or_update(instanceKlassHandle k,
} }
} }
klassOop LoaderConstraintTable::find_constrained_klass(symbolHandle name, klassOop LoaderConstraintTable::find_constrained_klass(Symbol* name,
Handle loader) { Handle loader) {
LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
if (p != NULL && p->klass() != NULL) if (p != NULL && p->klass() != NULL)
@ -442,11 +432,10 @@ void LoaderConstraintTable::verify(Dictionary* dictionary,
for (LoaderConstraintEntry* probe = bucket(cindex); for (LoaderConstraintEntry* probe = bucket(cindex);
probe != NULL; probe != NULL;
probe = probe->next()) { probe = probe->next()) {
guarantee(probe->name()->is_symbol(), "should be symbol");
if (probe->klass() != NULL) { if (probe->klass() != NULL) {
instanceKlass* ik = instanceKlass::cast(probe->klass()); instanceKlass* ik = instanceKlass::cast(probe->klass());
guarantee(ik->name() == probe->name(), "name should match"); guarantee(ik->name() == probe->name(), "name should match");
symbolHandle name (thread, ik->name()); Symbol* name = ik->name();
Handle loader(thread, ik->class_loader()); Handle loader(thread, ik->class_loader());
unsigned int d_hash = dictionary->compute_hash(name, loader); unsigned int d_hash = dictionary->compute_hash(name, loader);
int d_index = dictionary->hash_to_index(d_hash); int d_index = dictionary->hash_to_index(d_hash);

View File

@ -31,7 +31,7 @@
class LoaderConstraintEntry; class LoaderConstraintEntry;
class LoaderConstraintTable : public Hashtable { class LoaderConstraintTable : public Hashtable<klassOop> {
friend class VMStructs; friend class VMStructs;
private: private:
@ -40,39 +40,39 @@ private:
_nof_buckets = 1009 // number of buckets in hash table _nof_buckets = 1009 // number of buckets in hash table
}; };
LoaderConstraintEntry** find_loader_constraint(symbolHandle name, LoaderConstraintEntry** find_loader_constraint(Symbol* name,
Handle loader); Handle loader);
public: public:
LoaderConstraintTable(int nof_buckets); 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, klassOop klass, int num_loaders,
int max_loaders); int max_loaders);
void free_entry(LoaderConstraintEntry *entry);
LoaderConstraintEntry* bucket(int i) { LoaderConstraintEntry* bucket(int i) {
return (LoaderConstraintEntry*)Hashtable::bucket(i); return (LoaderConstraintEntry*)Hashtable<klassOop>::bucket(i);
} }
LoaderConstraintEntry** bucket_addr(int i) { LoaderConstraintEntry** bucket_addr(int i) {
return (LoaderConstraintEntry**)Hashtable::bucket_addr(i); return (LoaderConstraintEntry**)Hashtable<klassOop>::bucket_addr(i);
} }
// GC support // GC support
void oops_do(OopClosure* f); void oops_do(OopClosure* f);
void always_strong_classes_do(OopClosure* blk);
// Check class loader constraints // 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); klassOop klass2, Handle loader2);
// Note: The main entry point for this module is via SystemDictionary. // 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, // Handle loader1, Handle loader2,
// bool is_method, TRAPS) // bool is_method, TRAPS)
klassOop find_constrained_klass(symbolHandle name, Handle loader); klassOop find_constrained_klass(Symbol* name, Handle loader);
// Class loader constraints // Class loader constraints
@ -83,7 +83,7 @@ public:
LoaderConstraintEntry** pp2, klassOop klass); LoaderConstraintEntry** pp2, klassOop klass);
bool check_or_update(instanceKlassHandle k, Handle loader, bool check_or_update(instanceKlassHandle k, Handle loader,
symbolHandle name); Symbol* name);
void purge_loader_constraints(BoolObjectClosure* is_alive); void purge_loader_constraints(BoolObjectClosure* is_alive);
@ -94,34 +94,36 @@ public:
#endif #endif
}; };
class LoaderConstraintEntry : public HashtableEntry { class LoaderConstraintEntry : public HashtableEntry<klassOop> {
friend class VMStructs; friend class VMStructs;
private: private:
symbolOop _name; // class name Symbol* _name; // class name
int _num_loaders; int _num_loaders;
int _max_loaders; int _max_loaders;
oop* _loaders; // initiating loaders oop* _loaders; // initiating loaders
public: public:
klassOop klass() { return (klassOop)literal(); } klassOop klass() { return literal(); }
klassOop* klass_addr() { return (klassOop*)literal_addr(); } klassOop* klass_addr() { return literal_addr(); }
void set_klass(klassOop k) { set_literal(k); } void set_klass(klassOop k) { set_literal(k); }
LoaderConstraintEntry* next() { LoaderConstraintEntry* next() {
return (LoaderConstraintEntry*)HashtableEntry::next(); return (LoaderConstraintEntry*)HashtableEntry<klassOop>::next();
} }
LoaderConstraintEntry** next_addr() { LoaderConstraintEntry** next_addr() {
return (LoaderConstraintEntry**)HashtableEntry::next_addr(); return (LoaderConstraintEntry**)HashtableEntry<klassOop>::next_addr();
} }
void set_next(LoaderConstraintEntry* next) { void set_next(LoaderConstraintEntry* next) {
HashtableEntry::set_next(next); HashtableEntry<klassOop>::set_next(next);
} }
symbolOop name() { return _name; } Symbol* name() { return _name; }
symbolOop* name_addr() { return &_name; } void set_name(Symbol* name) {
void set_name(symbolOop name) { _name = name; } _name = name;
if (name != NULL) name->increment_refcount();
}
int num_loaders() { return _num_loaders; } int num_loaders() { return _num_loaders; }
void set_num_loaders(int i) { _num_loaders = i; } void set_num_loaders(int i) { _num_loaders = i; }

View File

@ -31,10 +31,12 @@
// Placeholder methods // Placeholder methods
PlaceholderEntry* PlaceholderTable::new_entry(int hash, symbolOop name, PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
oop loader, bool havesupername, oop loader, bool havesupername,
symbolOop supername) { Symbol* supername) {
PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable::new_entry(hash, name); PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*>::new_entry(hash, name);
// Hashtable with Symbol* literal must increment and decrement refcount.
name->increment_refcount();
entry->set_loader(loader); entry->set_loader(loader);
entry->set_havesupername(havesupername); entry->set_havesupername(havesupername);
entry->set_supername(supername); entry->set_supername(supername);
@ -46,33 +48,40 @@ PlaceholderEntry* PlaceholderTable::new_entry(int hash, symbolOop name,
return entry; 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<Symbol*>::free_entry(entry);
}
// Placeholder objects represent classes currently being loaded. // Placeholder objects represent classes currently being loaded.
// All threads examining the placeholder table must hold the // All threads examining the placeholder table must hold the
// SystemDictionary_lock, so we don't need special precautions // SystemDictionary_lock, so we don't need special precautions
// on store ordering here. // on store ordering here.
void PlaceholderTable::add_entry(int index, unsigned int hash, void PlaceholderTable::add_entry(int index, unsigned int hash,
symbolHandle class_name, Handle class_loader, Symbol* class_name, Handle class_loader,
bool havesupername, symbolHandle supername){ bool havesupername, Symbol* supername){
assert_locked_or_safepoint(SystemDictionary_lock); 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 // Both readers and writers are locked so it's safe to just
// create the placeholder and insert it in the list without a membar. // 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); add_entry(index, entry);
} }
// Remove a placeholder object. // Remove a placeholder object.
void PlaceholderTable::remove_entry(int index, unsigned int hash, void PlaceholderTable::remove_entry(int index, unsigned int hash,
symbolHandle class_name, Symbol* class_name,
Handle class_loader) { Handle class_loader) {
assert_locked_or_safepoint(SystemDictionary_lock); assert_locked_or_safepoint(SystemDictionary_lock);
PlaceholderEntry** p = bucket_addr(index); PlaceholderEntry** p = bucket_addr(index);
while (*p) { while (*p) {
PlaceholderEntry *probe = *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 // Delete entry
*p = probe->next(); *p = probe->next();
free_entry(probe); free_entry(probe);
@ -83,29 +92,28 @@ void PlaceholderTable::remove_entry(int index, unsigned int hash,
} }
PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash, PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash,
symbolHandle class_name, Symbol* class_name,
Handle class_loader) { Handle class_loader) {
assert_locked_or_safepoint(SystemDictionary_lock); assert_locked_or_safepoint(SystemDictionary_lock);
symbolOop class_name_ = class_name();
oop class_loader_ = class_loader(); oop class_loader_ = class_loader();
for (PlaceholderEntry *place_probe = bucket(index); for (PlaceholderEntry *place_probe = bucket(index);
place_probe != NULL; place_probe != NULL;
place_probe = place_probe->next()) { place_probe = place_probe->next()) {
if (place_probe->hash() == hash && if (place_probe->hash() == hash &&
place_probe->equals(class_name_, class_loader_)) { place_probe->equals(class_name, class_loader_)) {
return place_probe; return place_probe;
} }
} }
return NULL; return NULL;
} }
symbolOop PlaceholderTable::find_entry(int index, unsigned int hash, Symbol* PlaceholderTable::find_entry(int index, unsigned int hash,
symbolHandle class_name, Symbol* class_name,
Handle class_loader) { Handle class_loader) {
PlaceholderEntry* probe = get_entry(index, hash, class_name, 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 // find_and_add returns probe pointer - old or new
@ -113,7 +121,7 @@ symbolOop PlaceholderTable::find_entry(int index, unsigned int hash,
// If entry exists, reuse entry // If entry exists, reuse entry
// For both, push SeenThread for classloadAction // For both, push SeenThread for classloadAction
// if havesupername: this is used for circularity for instanceklass loading // 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); PlaceholderEntry* probe = get_entry(index, hash, name, loader);
if (probe == NULL) { if (probe == NULL) {
// Nothing found, add place holder // Nothing found, add place holder
@ -122,7 +130,7 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, s
} else { } else {
if (action == LOAD_SUPER) { if (action == LOAD_SUPER) {
probe->set_havesupername(true); probe->set_havesupername(true);
probe->set_supername(supername()); probe->set_supername(supername);
} }
} }
if (probe) probe->add_seen_thread(thread, action); if (probe) probe->add_seen_thread(thread, action);
@ -145,7 +153,7 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, s
// Therefore - must always check SD first // Therefore - must always check SD first
// Ignores the case where entry is not found // Ignores the case where entry is not found
void PlaceholderTable::find_and_remove(int index, unsigned int hash, 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); assert_locked_or_safepoint(SystemDictionary_lock);
PlaceholderEntry *probe = get_entry(index, hash, name, loader); PlaceholderEntry *probe = get_entry(index, hash, name, loader);
if (probe != NULL) { if (probe != NULL) {
@ -158,7 +166,7 @@ void PlaceholderTable::find_and_remove(int index, unsigned int hash,
} }
PlaceholderTable::PlaceholderTable(int table_size) PlaceholderTable::PlaceholderTable(int table_size)
: TwoOopHashtable(table_size, sizeof(PlaceholderEntry)) { : TwoOopHashtable<Symbol*>(table_size, sizeof(PlaceholderEntry)) {
} }
@ -174,26 +182,22 @@ void PlaceholderTable::oops_do(OopClosure* f) {
void PlaceholderEntry::oops_do(OopClosure* blk) { void PlaceholderEntry::oops_do(OopClosure* blk) {
assert(klass() != NULL, "should have a non-null klass"); assert(klassname() != NULL, "should have a non-null klass");
blk->do_oop((oop*)klass_addr());
if (_loader != NULL) { if (_loader != NULL) {
blk->do_oop(loader_addr()); blk->do_oop(loader_addr());
} }
if (_supername != NULL) {
blk->do_oop((oop*)supername_addr());
}
if (_instanceKlass != NULL) { if (_instanceKlass != NULL) {
blk->do_oop((oop*)instanceKlass_addr()); blk->do_oop((oop*)instanceKlass_addr());
} }
} }
// do all entries in the placeholder table // 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 (int index = 0; index < table_size(); index++) {
for (PlaceholderEntry* probe = bucket(index); for (PlaceholderEntry* probe = bucket(index);
probe != NULL; probe != NULL;
probe = probe->next()) { probe = probe->next()) {
f(probe->klass(), probe->loader()); f(probe->klassname(), probe->loader());
} }
} }
} }
@ -202,7 +206,7 @@ void PlaceholderTable::entries_do(void f(symbolOop, oop)) {
#ifndef PRODUCT #ifndef PRODUCT
// Note, doesn't append a cr // Note, doesn't append a cr
void PlaceholderEntry::print() const { void PlaceholderEntry::print() const {
klass()->print_value(); klassname()->print_value();
if (loader() != NULL) { if (loader() != NULL) {
tty->print(", loader "); tty->print(", loader ");
loader()->print_value(); loader()->print_value();
@ -238,7 +242,6 @@ void PlaceholderEntry::verify() const {
guarantee(instanceKlass() == NULL guarantee(instanceKlass() == NULL
|| Klass::cast(instanceKlass())->oop_is_instance(), || Klass::cast(instanceKlass())->oop_is_instance(),
"checking type of instanceKlass result"); "checking type of instanceKlass result");
klass()->verify();
} }
void PlaceholderTable::verify() { void PlaceholderTable::verify() {

View File

@ -34,35 +34,36 @@ class PlaceholderEntry;
// being loaded, as well as arrays of primitives. // being loaded, as well as arrays of primitives.
// //
class PlaceholderTable : public TwoOopHashtable { class PlaceholderTable : public TwoOopHashtable<Symbol*> {
friend class VMStructs; friend class VMStructs;
public: public:
PlaceholderTable(int table_size); 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) { PlaceholderEntry* bucket(int i) {
return (PlaceholderEntry*)Hashtable::bucket(i); return (PlaceholderEntry*)Hashtable<Symbol*>::bucket(i);
} }
PlaceholderEntry** bucket_addr(int i) { PlaceholderEntry** bucket_addr(int i) {
return (PlaceholderEntry**)Hashtable::bucket_addr(i); return (PlaceholderEntry**)Hashtable<Symbol*>::bucket_addr(i);
} }
void add_entry(int index, PlaceholderEntry* new_entry) { void add_entry(int index, PlaceholderEntry* new_entry) {
Hashtable::add_entry(index, (HashtableEntry*)new_entry); Hashtable<Symbol*>::add_entry(index, (HashtableEntry<Symbol*>*)new_entry);
} }
void add_entry(int index, unsigned int hash, symbolHandle name, void add_entry(int index, unsigned int hash, Symbol* name,
Handle loader, bool havesupername, symbolHandle supername); Handle loader, bool havesupername, Symbol* supername);
// This returns a symbolOop to match type for SystemDictionary // This returns a Symbol* to match type for SystemDictionary
symbolOop find_entry(int index, unsigned int hash, Symbol* find_entry(int index, unsigned int hash,
symbolHandle name, Handle loader); Symbol* name, Handle loader);
PlaceholderEntry* get_entry(int index, unsigned int hash, 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 to create a placeholder entry must enumerate an action
// caller claims ownership of that action // caller claims ownership of that action
@ -84,22 +85,22 @@ public:
// If no entry exists, add a placeholder entry and push SeenThread // If no entry exists, add a placeholder entry and push SeenThread
// If entry exists, reuse entry and push SeenThread for classloadAction // If entry exists, reuse entry and push SeenThread for classloadAction
PlaceholderEntry* find_and_add(int index, unsigned int hash, PlaceholderEntry* find_and_add(int index, unsigned int hash,
symbolHandle name, Handle loader, Symbol* name, Handle loader,
classloadAction action, symbolHandle supername, classloadAction action, Symbol* supername,
Thread* thread); Thread* thread);
void remove_entry(int index, unsigned int hash, void remove_entry(int index, unsigned int hash,
symbolHandle name, Handle loader); Symbol* name, Handle loader);
// Remove placeholder information // Remove placeholder information
void find_and_remove(int index, unsigned int hash, void find_and_remove(int index, unsigned int hash,
symbolHandle name, Handle loader, Thread* thread); Symbol* name, Handle loader, Thread* thread);
// GC support. // GC support.
void oops_do(OopClosure* f); void oops_do(OopClosure* f);
// JVMTI support // JVMTI support
void entries_do(void f(symbolOop, oop)); void entries_do(void f(Symbol*, oop));
#ifndef PRODUCT #ifndef PRODUCT
void print(); void print();
@ -151,14 +152,14 @@ public:
// on store ordering here. // on store ordering here.
// The system dictionary is the only user of this class. // The system dictionary is the only user of this class.
class PlaceholderEntry : public HashtableEntry { class PlaceholderEntry : public HashtableEntry<Symbol*> {
friend class VMStructs; friend class VMStructs;
private: private:
oop _loader; // initiating loader oop _loader; // initiating loader
bool _havesupername; // distinguish between null supername, and unknown bool _havesupername; // distinguish between null supername, and unknown
symbolOop _supername; Symbol* _supername;
Thread* _definer; // owner of define token Thread* _definer; // owner of define token
klassOop _instanceKlass; // instanceKlass from successful define klassOop _instanceKlass; // instanceKlass from successful define
SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class
@ -173,8 +174,7 @@ class PlaceholderEntry : public HashtableEntry {
public: public:
// Simple accessors, used only by SystemDictionary // Simple accessors, used only by SystemDictionary
symbolOop klass() const { return (symbolOop)literal(); } Symbol* klassname() const { return literal(); }
symbolOop* klass_addr() { return (symbolOop*)literal_addr(); }
oop loader() const { return _loader; } oop loader() const { return _loader; }
void set_loader(oop loader) { _loader = loader; } void set_loader(oop loader) { _loader = loader; }
@ -183,9 +183,11 @@ class PlaceholderEntry : public HashtableEntry {
bool havesupername() const { return _havesupername; } bool havesupername() const { return _havesupername; }
void set_havesupername(bool havesupername) { _havesupername = havesupername; } void set_havesupername(bool havesupername) { _havesupername = havesupername; }
symbolOop supername() const { return _supername; } Symbol* supername() const { return _supername; }
void set_supername(symbolOop supername) { _supername = supername; } void set_supername(Symbol* supername) {
symbolOop* supername_addr() { return &_supername; } _supername = supername;
if (_supername != NULL) _supername->increment_refcount();
}
Thread* definer() const {return _definer; } Thread* definer() const {return _definer; }
void set_definer(Thread* definer) { _definer = definer; } void set_definer(Thread* definer) { _definer = definer; }
@ -204,17 +206,17 @@ class PlaceholderEntry : public HashtableEntry {
void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; } void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
PlaceholderEntry* next() const { PlaceholderEntry* next() const {
return (PlaceholderEntry*)HashtableEntry::next(); return (PlaceholderEntry*)HashtableEntry<Symbol*>::next();
} }
PlaceholderEntry** next_addr() { PlaceholderEntry** next_addr() {
return (PlaceholderEntry**)HashtableEntry::next_addr(); return (PlaceholderEntry**)HashtableEntry<Symbol*>::next_addr();
} }
// Test for equality // Test for equality
// Entries are unique for class/classloader name pair // Entries are unique for class/classloader name pair
bool equals(symbolOop class_name, oop class_loader) const { bool equals(Symbol* class_name, oop class_loader) const {
return (klass() == class_name && loader() == class_loader); return (klassname() == class_name && loader() == class_loader);
} }
SeenThread* actionToQueue(PlaceholderTable::classloadAction action) { SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {

View File

@ -32,12 +32,12 @@
// add new entry to the table // add new entry to the table
void ResolutionErrorTable::add_entry(int index, unsigned int hash, 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_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); add_entry(index, entry);
} }
@ -57,20 +57,35 @@ ResolutionErrorEntry* ResolutionErrorTable::find_entry(int index, unsigned int h
return NULL; 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 // create new error entry
ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, constantPoolOop pool, 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<constantPoolOop>::new_entry(hash, pool);
entry->set_cp_index(cp_index); entry->set_cp_index(cp_index);
NOT_PRODUCT(entry->set_error(NULL);)
entry->set_error(error); entry->set_error(error);
return entry; return entry;
} }
void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) {
// decrement error refcount
assert(entry->error() != NULL, "error should be set");
entry->error()->decrement_refcount();
Hashtable<constantPoolOop>::free_entry(entry);
}
// create resolution error table // create resolution error table
ResolutionErrorTable::ResolutionErrorTable(int table_size) ResolutionErrorTable::ResolutionErrorTable(int table_size)
: Hashtable(table_size, sizeof(ResolutionErrorEntry)) { : Hashtable<constantPoolOop>(table_size, sizeof(ResolutionErrorEntry)) {
} }
// GC support // GC support
@ -80,7 +95,7 @@ void ResolutionErrorTable::oops_do(OopClosure* f) {
probe != NULL; probe != NULL;
probe = probe->next()) { probe = probe->next()) {
assert(probe->pool() != (constantPoolOop)NULL, "resolution error table is corrupt"); 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); probe->oops_do(f);
} }
} }
@ -89,20 +104,6 @@ void ResolutionErrorTable::oops_do(OopClosure* f) {
// GC support // GC support
void ResolutionErrorEntry::oops_do(OopClosure* blk) { void ResolutionErrorEntry::oops_do(OopClosure* blk) {
blk->do_oop((oop*)pool_addr()); 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 // Remove unloaded entries from the table

View File

@ -33,27 +33,28 @@ class ResolutionErrorEntry;
// ResolutionError objects are used to record errors encountered during // ResolutionError objects are used to record errors encountered during
// constant pool resolution (JVMS 5.4.3). // constant pool resolution (JVMS 5.4.3).
class ResolutionErrorTable : public Hashtable { class ResolutionErrorTable : public Hashtable<constantPoolOop> {
public: public:
ResolutionErrorTable(int table_size); 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) { ResolutionErrorEntry* bucket(int i) {
return (ResolutionErrorEntry*)Hashtable::bucket(i); return (ResolutionErrorEntry*)Hashtable<constantPoolOop>::bucket(i);
} }
ResolutionErrorEntry** bucket_addr(int i) { ResolutionErrorEntry** bucket_addr(int i) {
return (ResolutionErrorEntry**)Hashtable::bucket_addr(i); return (ResolutionErrorEntry**)Hashtable<constantPoolOop>::bucket_addr(i);
} }
void add_entry(int index, ResolutionErrorEntry* new_entry) { void add_entry(int index, ResolutionErrorEntry* new_entry) {
Hashtable::add_entry(index, (HashtableEntry*)new_entry); Hashtable<constantPoolOop>::add_entry(index, (HashtableEntry<constantPoolOop>*)new_entry);
} }
void add_entry(int index, unsigned int hash, 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 // find error given the constant pool and constant pool index
@ -68,18 +69,15 @@ public:
// purges unloaded entries from the table // purges unloaded entries from the table
void purge_resolution_errors(BoolObjectClosure* is_alive); void purge_resolution_errors(BoolObjectClosure* is_alive);
// this table keeps symbolOops alive
void always_strong_classes_do(OopClosure* blk);
// GC support. // GC support.
void oops_do(OopClosure* f); void oops_do(OopClosure* f);
}; };
class ResolutionErrorEntry : public HashtableEntry { class ResolutionErrorEntry : public HashtableEntry<constantPoolOop> {
private: private:
int _cp_index; int _cp_index;
symbolOop _error; Symbol* _error;
public: public:
constantPoolOop pool() const { return (constantPoolOop)literal(); } constantPoolOop pool() const { return (constantPoolOop)literal(); }
@ -88,16 +86,15 @@ class ResolutionErrorEntry : public HashtableEntry {
int cp_index() const { return _cp_index; } int cp_index() const { return _cp_index; }
void set_cp_index(int cp_index) { _cp_index = cp_index; } void set_cp_index(int cp_index) { _cp_index = cp_index; }
symbolOop error() const { return _error; } Symbol* error() const { return _error; }
void set_error(symbolOop e) { _error = e; } void set_error(Symbol* e);
symbolOop* error_addr() { return &_error; }
ResolutionErrorEntry* next() const { ResolutionErrorEntry* next() const {
return (ResolutionErrorEntry*)HashtableEntry::next(); return (ResolutionErrorEntry*)HashtableEntry<constantPoolOop>::next();
} }
ResolutionErrorEntry** next_addr() { ResolutionErrorEntry** next_addr() {
return (ResolutionErrorEntry**)HashtableEntry::next_addr(); return (ResolutionErrorEntry**)HashtableEntry<constantPoolOop>::next_addr();
} }
// GC support // GC support

View File

@ -27,7 +27,7 @@
#include "classfile/verifier.hpp" #include "classfile/verifier.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "utilities/globalDefinitions.hpp" #include "utilities/globalDefinitions.hpp"
@ -90,8 +90,7 @@ void StackMapFrame::initialize_object(
VerificationType StackMapFrame::set_locals_from_arg( VerificationType StackMapFrame::set_locals_from_arg(
const methodHandle m, VerificationType thisKlass, TRAPS) { const methodHandle m, VerificationType thisKlass, TRAPS) {
symbolHandle signature(THREAD, m->signature()); SignatureStream ss(m->signature());
SignatureStream ss(signature);
int init_local_num = 0; int init_local_num = 0;
if (!m->is_static()) { if (!m->is_static()) {
init_local_num++; init_local_num++;
@ -118,8 +117,14 @@ VerificationType StackMapFrame::set_locals_from_arg(
case T_OBJECT: case T_OBJECT:
case T_ARRAY: case T_ARRAY:
{ {
symbolOop sig = ss.as_symbol(CHECK_(VerificationType::bogus_type())); Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type()));
return VerificationType::reference_type(symbolHandle(THREAD, sig)); // 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_INT: return VerificationType::integer_type();
case T_BYTE: return VerificationType::byte_type(); case T_BYTE: return VerificationType::byte_type();
@ -157,7 +162,7 @@ bool StackMapFrame::is_assignable_to(
VerificationType* from, VerificationType* to, int32_t len, TRAPS) const { VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
for (int32_t i = 0; i < len; i++) { for (int32_t i = 0; i < len; i++) {
bool subtype = to[i].is_assignable_from( bool subtype = to[i].is_assignable_from(
from[i], verifier()->current_class(), THREAD); from[i], verifier(), THREAD);
if (!subtype) { if (!subtype) {
return false; return false;
} }
@ -187,7 +192,7 @@ VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
} }
VerificationType top = _stack[--_stack_size]; VerificationType top = _stack[--_stack_size];
bool subtype = type.is_assignable_from( bool subtype = type.is_assignable_from(
top, verifier()->current_class(), CHECK_(VerificationType::bogus_type())); top, verifier(), CHECK_(VerificationType::bogus_type()));
if (!subtype) { if (!subtype) {
verifier()->verify_error(_offset, "Bad type on operand stack"); verifier()->verify_error(_offset, "Bad type on operand stack");
return VerificationType::bogus_type(); return VerificationType::bogus_type();
@ -203,7 +208,7 @@ VerificationType StackMapFrame::get_local(
return VerificationType::bogus_type(); return VerificationType::bogus_type();
} }
bool subtype = type.is_assignable_from(_locals[index], bool subtype = type.is_assignable_from(_locals[index],
verifier()->current_class(), CHECK_(VerificationType::bogus_type())); verifier(), CHECK_(VerificationType::bogus_type()));
if (!subtype) { if (!subtype) {
verifier()->verify_error(_offset, "Bad local variable type"); verifier()->verify_error(_offset, "Bad local variable type");
return VerificationType::bogus_type(); return VerificationType::bogus_type();
@ -221,9 +226,9 @@ void StackMapFrame::get_local_2(
return; return;
} }
bool subtype1 = type1.is_assignable_from( bool subtype1 = type1.is_assignable_from(
_locals[index], verifier()->current_class(), CHECK); _locals[index], verifier(), CHECK);
bool subtype2 = type2.is_assignable_from( bool subtype2 = type2.is_assignable_from(
_locals[index+1], verifier()->current_class(), CHECK); _locals[index+1], verifier(), CHECK);
if (!subtype1 || !subtype2) { if (!subtype1 || !subtype2) {
verifier()->verify_error(_offset, "Bad local variable type"); verifier()->verify_error(_offset, "Bad local variable type");
return; return;

View File

@ -177,8 +177,7 @@ class StackMapFrame : public ResourceObj {
if (_stack_size != 0) { if (_stack_size != 0) {
VerificationType top = _stack[_stack_size - 1]; VerificationType top = _stack[_stack_size - 1];
bool subtype = type.is_assignable_from( bool subtype = type.is_assignable_from(
top, verifier()->current_class(), top, verifier(), CHECK_(VerificationType::bogus_type()));
CHECK_(VerificationType::bogus_type()));
if (subtype) { if (subtype) {
_stack_size --; _stack_size --;
NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
@ -194,11 +193,9 @@ class StackMapFrame : public ResourceObj {
assert(type2.is_long() || type2.is_double(), "must be long/double_2"); assert(type2.is_long() || type2.is_double(), "must be long/double_2");
if (_stack_size >= 2) { if (_stack_size >= 2) {
VerificationType top1 = _stack[_stack_size - 1]; VerificationType top1 = _stack[_stack_size - 1];
bool subtype1 = type1.is_assignable_from( bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK);
top1, verifier()->current_class(), CHECK);
VerificationType top2 = _stack[_stack_size - 2]; VerificationType top2 = _stack[_stack_size - 2];
bool subtype2 = type2.is_assignable_from( bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK);
top2, verifier()->current_class(), CHECK);
if (subtype1 && subtype2) { if (subtype1 && subtype2) {
_stack_size -= 2; _stack_size -= 2;
NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); ) NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )

View File

@ -184,8 +184,7 @@ VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) {
_stream->stackmap_format_error("bad class index", THREAD); _stream->stackmap_format_error("bad class index", THREAD);
return VerificationType::bogus_type(); return VerificationType::bogus_type();
} }
return VerificationType::reference_type( return VerificationType::reference_type(_cp->klass_name_at(class_index));
symbolHandle(THREAD, _cp->klass_name_at(class_index)));
} }
if (tag == ITEM_UninitializedThis) { if (tag == ITEM_UninitializedThis) {
if (flags != NULL) { if (flags != NULL) {

View File

@ -31,7 +31,6 @@
#include "memory/gcLocker.inline.hpp" #include "memory/gcLocker.inline.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "oops/oop.inline2.hpp" #include "oops/oop.inline2.hpp"
#include "oops/symbolKlass.hpp"
#include "runtime/mutexLocker.hpp" #include "runtime/mutexLocker.hpp"
#include "utilities/hashtable.inline.hpp" #include "utilities/hashtable.inline.hpp"
@ -39,14 +38,97 @@
SymbolTable* SymbolTable::_the_table = NULL; 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<Symbol*>* 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<Symbol*>** p = the_table()->bucket_addr(i); *p != NULL; ) {
HashtableEntry<Symbol*>* 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. // 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) { int len, unsigned int hash) {
for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { for (HashtableEntry<Symbol*>* e = bucket(index); e != NULL; e = e->next()) {
if (e->hash() == hash) { if (e->hash() == hash) {
symbolOop sym = symbolOop(e->literal()); Symbol* sym = e->literal();
if (sym->equals(name, len)) { if (sym->equals(name, len)) {
// something is referencing this symbol now.
sym->increment_refcount();
return sym; return sym;
} }
} }
@ -62,11 +144,11 @@ symbolOop SymbolTable::lookup(int index, const char* name,
// entries in the symbol table during normal execution (only during // entries in the symbol table during normal execution (only during
// safepoints). // 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); unsigned int hashValue = hash_symbol(name, len);
int index = the_table()->hash_to_index(hashValue); 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 // Found
if (s != NULL) return s; if (s != NULL) return s;
@ -75,7 +157,7 @@ symbolOop SymbolTable::lookup(const char* name, int len, TRAPS) {
return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL); 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; char* buffer;
int index, len; int index, len;
unsigned int hashValue; unsigned int hashValue;
@ -87,7 +169,7 @@ symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) {
len = end - begin; len = end - begin;
hashValue = hash_symbol(name, len); hashValue = hash_symbol(name, len);
index = the_table()->hash_to_index(hashValue); 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 // Found
if (s != NULL) return s; if (s != NULL) return s;
@ -111,18 +193,19 @@ symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) {
return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL); 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) { unsigned int& hash) {
hash = hash_symbol(name, len); hash = hash_symbol(name, len);
int index = the_table()->hash_to_index(hash); 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 // Suggestion: Push unicode-based lookup all the way into the hashing
// and probing logic, so there is no need for convert_to_utf8 until // and probing logic, so there is no need for convert_to_utf8 until
// an actual new symbolOop is created. // an actual new Symbol* is created.
symbolOop SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) { Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length); int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
char stack_buf[128]; char stack_buf[128];
if (utf8_length < (int) sizeof(stack_buf)) { if (utf8_length < (int) sizeof(stack_buf)) {
@ -137,7 +220,7 @@ symbolOop SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS
} }
} }
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) { unsigned int& hash) {
int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length); int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
char stack_buf[128]; char stack_buf[128];
@ -163,25 +246,23 @@ void SymbolTable::add(constantPoolHandle cp, int names_count,
// do it the hard way // do it the hard way
for (int i=0; i<names_count; i++) { for (int i=0; i<names_count; i++) {
int index = table->hash_to_index(hashValues[i]); int index = table->hash_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); hashValues[i], CHECK);
cp->symbol_at_put(cp_indices[i], sym); 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) { unsigned int hashValue, TRAPS) {
assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
"proposed name of symbol must be stable"); "proposed name of symbol must be stable");
// We assume that lookup() has been called already, that it failed, // We assume that lookup() has been called already, that it failed,
// and symbol was not found. We create the symbol here. // and symbol was not found. We create the symbol here.
symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); Symbol* sym = allocate_symbol(name, len, CHECK_NULL);
symbolOop s_oop = sk->allocate_symbol(name, len, CHECK_NULL);
symbolHandle sym (THREAD, s_oop);
// 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); MutexLocker ml(SymbolTable_lock, THREAD);
assert(sym->equals((char*)name, len), "symbol must be properly initialized"); assert(sym->equals((char*)name, len), "symbol must be properly initialized");
@ -189,51 +270,51 @@ symbolOop SymbolTable::basic_add(int index, u1 *name, int len,
// Since look-up was done lock-free, we need to check if another // Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol. // 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) { if (test != NULL) {
// A race occurred and another thread introduced the symbol, this one // A race occurred and another thread introduced the symbol, this one
// will be dropped and collected. // will be dropped and collected.
delete sym;
assert(test->refcount() != 0, "lookup should have incremented the count");
return test; return test;
} }
HashtableEntry* entry = new_entry(hashValue, sym()); HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym);
sym->increment_refcount();
add_entry(index, entry); add_entry(index, entry);
return sym(); return sym;
} }
bool SymbolTable::basic_add(constantPoolHandle cp, int names_count, bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
const char** names, int* lengths, const char** names, int* lengths,
int* cp_indices, unsigned int* hashValues, int* cp_indices, unsigned int* hashValues,
TRAPS) { TRAPS) {
symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); Symbol* syms[symbol_alloc_batch_size];
symbolOop sym_oops[symbol_alloc_batch_size]; bool allocated = allocate_symbols(names_count, (const u1**)names, lengths,
bool allocated = sk->allocate_symbols(names_count, names, lengths, syms, CHECK_false);
sym_oops, CHECK_false);
if (!allocated) { if (!allocated) {
return false; return false;
} }
symbolHandle syms[symbol_alloc_batch_size];
int i;
for (i=0; i<names_count; i++) {
syms[i] = symbolHandle(THREAD, sym_oops[i]);
}
// Allocation must be done before grabbing the SymbolTable_lock lock // Allocation must be done before grabbing the SymbolTable_lock lock
MutexLocker ml(SymbolTable_lock, THREAD); MutexLocker ml(SymbolTable_lock, THREAD);
for (i=0; i<names_count; i++) { for (int i=0; i<names_count; i++) {
assert(syms[i]->equals(names[i], lengths[i]), "symbol must be properly initialized"); assert(syms[i]->equals(names[i], lengths[i]), "symbol must be properly initialized");
// Since look-up was done lock-free, we need to check if another // Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol. // thread beat us in the race to insert the symbol.
int index = hash_to_index(hashValues[i]); 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) { if (test != NULL) {
// A race occurred and another thread introduced the symbol, this one // A race occurred and another thread introduced the symbol, this one
// will be dropped and collected. Use test instead. // will be dropped and collected. Use test instead.
cp->symbol_at_put(cp_indices[i], test); cp->symbol_at_put(cp_indices[i], test);
assert(test->refcount() != 0, "lookup should have incremented the count");
delete syms[i];
} else { } else {
symbolOop sym = syms[i](); Symbol* sym = syms[i];
HashtableEntry* entry = new_entry(hashValues[i], sym); HashtableEntry<Symbol*>* entry = new_entry(hashValues[i], sym);
sym->increment_refcount(); // increment refcount in external hashtable
add_entry(index, entry); add_entry(index, entry);
cp->symbol_at_put(cp_indices[i], sym); cp->symbol_at_put(cp_indices[i], sym);
} }
@ -245,12 +326,10 @@ bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
void SymbolTable::verify() { void SymbolTable::verify() {
for (int i = 0; i < the_table()->table_size(); ++i) { for (int i = 0; i < the_table()->table_size(); ++i) {
HashtableEntry* p = the_table()->bucket(i); HashtableEntry<Symbol*>* p = the_table()->bucket(i);
for ( ; p != NULL; p = p->next()) { for ( ; p != NULL; p = p->next()) {
symbolOop s = symbolOop(p->literal()); Symbol* s = (Symbol*)(p->literal());
guarantee(s != NULL, "symbol is NULL"); 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()); unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length());
guarantee(p->hash() == h, "broken hash in symbol table entry"); guarantee(p->hash() == h, "broken hash in symbol table entry");
guarantee(the_table()->hash_to_index(h) == i, guarantee(the_table()->hash_to_index(h) == i,
@ -279,10 +358,14 @@ void SymbolTable::print_histogram() {
int total = 0; int total = 0;
int max_symbols = 0; int max_symbols = 0;
int out_of_range = 0; int out_of_range = 0;
int memory_total = 0;
int count = 0;
for (i = 0; i < the_table()->table_size(); i++) { for (i = 0; i < the_table()->table_size(); i++) {
HashtableEntry* p = the_table()->bucket(i); HashtableEntry<Symbol*>* p = the_table()->bucket(i);
for ( ; p != NULL; p = p->next()) { 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; total += counter;
if (counter < results_length) { if (counter < results_length) {
results[counter]++; results[counter]++;
@ -293,6 +376,17 @@ void SymbolTable::print_histogram() {
} }
} }
tty->print_cr("Symbol Table:"); 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", "Total ", total);
tty->print_cr("%8s %5d", "Maximum", max_symbols); tty->print_cr("%8s %5d", "Maximum", max_symbols);
tty->print_cr("%8s %3.2f", "Average", tty->print_cr("%8s %3.2f", "Average",
@ -304,24 +398,43 @@ void SymbolTable::print_histogram() {
tty->print_cr("%6d %10d", i, results[i]); tty->print_cr("%6d %10d", i, results[i]);
} }
} }
int line_length = 70; if (Verbose) {
tty->print_cr("%s %30s", " Length", "Number chains that length"); int line_length = 70;
for (i = 0; i < results_length; i++) { tty->print_cr("%s %30s", " Length", "Number chains that length");
if (results[i] > 0) { for (i = 0; i < results_length; i++) {
tty->print("%4d", i); if (results[i] > 0) {
for (j = 0; (j < results[i]) && (j < line_length); j++) { tty->print("%4d", i);
tty->print("%1s", "*"); 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->cr();
} }
} }
tty->print_cr(" %s %d: %d\n", "Number chains longer than", tty->print_cr(" %s %d: %d\n", "Number chains longer than",
results_length, out_of_range); results_length, out_of_range);
} }
void SymbolTable::print() {
for (int i = 0; i < the_table()->table_size(); ++i) {
HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i);
HashtableEntry<Symbol*>* 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<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p);
}
tty->cr();
}
}
}
#endif // PRODUCT #endif // PRODUCT
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -396,7 +509,7 @@ StringTable* StringTable::_the_table = NULL;
oop StringTable::lookup(int index, jchar* name, oop StringTable::lookup(int index, jchar* name,
int len, unsigned int hash) { int len, unsigned int hash) {
for (HashtableEntry* l = bucket(index); l != NULL; l = l->next()) { for (HashtableEntry<oop>* l = bucket(index); l != NULL; l = l->next()) {
if (l->hash() == hash) { if (l->hash() == hash) {
if (java_lang_String::equals(l->literal(), name, len)) { if (java_lang_String::equals(l->literal(), name, len)) {
return l->literal(); return l->literal();
@ -436,13 +549,13 @@ oop StringTable::basic_add(int index, Handle string_or_null, jchar* name,
return test; return test;
} }
HashtableEntry* entry = new_entry(hashValue, string()); HashtableEntry<oop>* entry = new_entry(hashValue, string());
add_entry(index, entry); add_entry(index, entry);
return string(); return string();
} }
oop StringTable::lookup(symbolOop symbol) { oop StringTable::lookup(Symbol* symbol) {
ResourceMark rm; ResourceMark rm;
int length; int length;
jchar* chars = symbol->as_unicode(length); jchar* chars = symbol->as_unicode(length);
@ -466,7 +579,7 @@ oop StringTable::intern(Handle string_or_null, jchar* name,
hashValue, CHECK_NULL); hashValue, CHECK_NULL);
} }
oop StringTable::intern(symbolOop symbol, TRAPS) { oop StringTable::intern(Symbol* symbol, TRAPS) {
if (symbol == NULL) return NULL; if (symbol == NULL) return NULL;
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
int length; int length;
@ -500,9 +613,50 @@ oop StringTable::intern(const char* utf8_string, TRAPS) {
return result; 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<oop>** p = the_table()->bucket_addr(i); *p != NULL; ) {
HashtableEntry<oop>* 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<oop>** p = the_table()->bucket_addr(i);
HashtableEntry<oop>* 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<oop>*)HashtableEntry<oop>::make_ptr(*p);
}
}
}
void StringTable::verify() { void StringTable::verify() {
for (int i = 0; i < the_table()->table_size(); ++i) { for (int i = 0; i < the_table()->table_size(); ++i) {
HashtableEntry* p = the_table()->bucket(i); HashtableEntry<oop>* p = the_table()->bucket(i);
for ( ; p != NULL; p = p->next()) { for ( ; p != NULL; p = p->next()) {
oop s = p->literal(); oop s = p->literal();
guarantee(s != NULL, "interned string is NULL"); guarantee(s != NULL, "interned string is NULL");

View File

@ -26,11 +26,11 @@
#define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
#include "utilities/hashtable.hpp" #include "utilities/hashtable.hpp"
// The symbol table holds all symbolOops and corresponding interned strings. // The symbol table holds all Symbol*s and corresponding interned strings.
// symbolOops and literal strings should be canonicalized. // Symbol*s and literal strings should be canonicalized.
// //
// The interned strings are created lazily. // The interned strings are created lazily.
// //
@ -42,32 +42,76 @@
class BoolObjectClosure; 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<Symbol*> {
friend class VMStructs; friend class VMStructs;
friend class ClassFileParser;
private: private:
// The symbol table // The symbol table
static SymbolTable* _the_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 // Adding elements
symbolOop basic_add(int index, u1* name, int len, Symbol* basic_add(int index, u1* name, int len,
unsigned int hashValue, TRAPS); unsigned int hashValue, TRAPS);
bool basic_add(constantPoolHandle cp, int names_count, bool basic_add(constantPoolHandle cp, int names_count,
const char** names, int* lengths, int* cp_indices, const char** names, int* lengths, int* cp_indices,
unsigned int* hashValues, TRAPS); 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 // Table size
enum { enum {
symbol_table_size = 20011 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() SymbolTable()
: Hashtable(symbol_table_size, sizeof (HashtableEntry)) {} : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>)) {}
SymbolTable(HashtableBucket* t, int number_of_entries) SymbolTable(HashtableBucket* t, int number_of_entries)
: Hashtable(symbol_table_size, sizeof (HashtableEntry), t, : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>), t,
number_of_entries) {} number_of_entries) {}
@ -92,66 +136,76 @@ public:
_the_table = new SymbolTable(t, number_of_entries); _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. // 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. // 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 // jchar (utf16) version of lookups
static symbolOop lookup_unicode(const jchar* name, int len, TRAPS); static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
static symbolOop lookup_only_unicode(const jchar* name, int len, unsigned int& hash); static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
static void add(constantPoolHandle cp, int names_count, static void add(constantPoolHandle cp, int names_count,
const char** names, int* lengths, int* cp_indices, const char** names, int* lengths, int* cp_indices,
unsigned int* hashValues, TRAPS); unsigned int* hashValues, TRAPS);
// GC support // Release any dead symbols
// Delete pointers to otherwise-unreachable objects. static void unlink();
static void unlink(BoolObjectClosure* cl) {
the_table()->Hashtable::unlink(cl);
}
// Invoke "f->do_oop" on the locations of all oops in the table. // iterate over symbols
static void oops_do(OopClosure* f) { static void symbols_do(SymbolClosure *cl);
the_table()->Hashtable::oops_do(f);
// 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);
}
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 // 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. // Needed for preloading classes in signatures when compiling.
// Returns the symbol is already present in symbol table, otherwise // Returns the symbol is already present in symbol table, otherwise
// NULL. NO ALLOCATION IS GUARANTEED! // 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; unsigned int ignore_hash;
return lookup_only(name, len, 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; unsigned int ignore_hash;
return lookup_only_unicode(name, len, ignore_hash); return lookup_only_unicode(name, len, ignore_hash);
} }
// Histogram // Histogram
static void print_histogram() PRODUCT_RETURN; static void print_histogram() PRODUCT_RETURN;
static void print() PRODUCT_RETURN;
// Debugging // Debugging
static void verify(); static void verify();
// Sharing // Sharing
static void copy_buckets(char** top, char*end) { static void copy_buckets(char** top, char*end) {
the_table()->Hashtable::copy_buckets(top, end); the_table()->Hashtable<Symbol*>::copy_buckets(top, end);
} }
static void copy_table(char** top, char*end) { static void copy_table(char** top, char*end) {
the_table()->Hashtable::copy_table(top, end); the_table()->Hashtable<Symbol*>::copy_table(top, end);
} }
static void reverse(void* boundary = NULL) { static void reverse(void* boundary = NULL) {
((Hashtable*)the_table())->reverse(boundary); the_table()->Hashtable<Symbol*>::reverse(boundary);
} }
}; };
class StringTable : public Hashtable<oop> {
class StringTable : public Hashtable {
friend class VMStructs; friend class VMStructs;
private: private:
@ -169,10 +223,10 @@ private:
oop lookup(int index, jchar* chars, int length, unsigned int hashValue); oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
StringTable() : Hashtable(string_table_size, sizeof (HashtableEntry)) {} StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {}
StringTable(HashtableBucket* t, int number_of_entries) StringTable(HashtableBucket* t, int number_of_entries)
: Hashtable(string_table_size, sizeof (HashtableEntry), t, : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t,
number_of_entries) {} number_of_entries) {}
public: public:
@ -192,26 +246,20 @@ public:
_the_table = new StringTable(t, number_of_entries); _the_table = new StringTable(t, number_of_entries);
} }
static int hash_string(jchar* s, int len); static int hash_string(jchar* s, int len);
// GC support // GC support
// Delete pointers to otherwise-unreachable objects. // Delete pointers to otherwise-unreachable objects.
static void unlink(BoolObjectClosure* cl) { static void unlink(BoolObjectClosure* cl);
the_table()->Hashtable::unlink(cl);
}
// Invoke "f->do_oop" on the locations of all oops in the table. // Invoke "f->do_oop" on the locations of all oops in the table.
static void oops_do(OopClosure* f) { static void oops_do(OopClosure* f);
the_table()->Hashtable::oops_do(f);
}
// Probing // Probing
static oop lookup(symbolOop symbol); static oop lookup(Symbol* symbol);
// Interning // Interning
static oop intern(symbolOop symbol, TRAPS); static oop intern(Symbol* symbol, TRAPS);
static oop intern(oop string, TRAPS); static oop intern(oop string, TRAPS);
static oop intern(const char *utf8_string, TRAPS); static oop intern(const char *utf8_string, TRAPS);
@ -220,13 +268,13 @@ public:
// Sharing // Sharing
static void copy_buckets(char** top, char*end) { static void copy_buckets(char** top, char*end) {
the_table()->Hashtable::copy_buckets(top, end); the_table()->Hashtable<oop>::copy_buckets(top, end);
} }
static void copy_table(char** top, char*end) { static void copy_table(char** top, char*end) {
the_table()->Hashtable::copy_table(top, end); the_table()->Hashtable<oop>::copy_table(top, end);
} }
static void reverse() { static void reverse() {
((BasicHashtable*)the_table())->reverse(); the_table()->Hashtable<oop>::reverse();
} }
}; };

View File

@ -93,8 +93,8 @@ void SystemDictionary::compute_java_system_loader(TRAPS) {
JavaValue result(T_OBJECT); JavaValue result(T_OBJECT);
JavaCalls::call_static(&result, JavaCalls::call_static(&result,
KlassHandle(THREAD, WK_KLASS(ClassLoader_klass)), KlassHandle(THREAD, WK_KLASS(ClassLoader_klass)),
vmSymbolHandles::getSystemClassLoader_name(), vmSymbols::getSystemClassLoader_name(),
vmSymbolHandles::void_classloader_signature(), vmSymbols::void_classloader_signature(),
CHECK); CHECK);
_java_system_loader = (oop)result.get_jobject(); _java_system_loader = (oop)result.get_jobject();
@ -107,8 +107,8 @@ void SystemDictionary::compute_java_system_loader(TRAPS) {
#ifdef ASSERT #ifdef ASSERT
// return true if class_name contains no '.' (internal format is '/') // return true if class_name contains no '.' (internal format is '/')
bool SystemDictionary::is_internal_format(symbolHandle class_name) { bool SystemDictionary::is_internal_format(Symbol* class_name) {
if (class_name.not_null()) { if (class_name != NULL) {
ResourceMark rm; ResourceMark rm;
char* name = class_name->as_C_string(); char* name = class_name->as_C_string();
return strchr(name, '.') == NULL; return strchr(name, '.') == NULL;
@ -141,7 +141,7 @@ bool SystemDictionary::is_parallelDefine(Handle class_loader) {
// Forwards to resolve_or_null // 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); klassOop klass = resolve_or_null(class_name, class_loader, protection_domain, THREAD);
if (HAS_PENDING_EXCEPTION || klass == NULL) { if (HAS_PENDING_EXCEPTION || klass == NULL) {
KlassHandle k_h(THREAD, klass); KlassHandle k_h(THREAD, klass);
@ -151,7 +151,7 @@ klassOop SystemDictionary::resolve_or_fail(symbolHandle class_name, Handle class
return klass; 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 (HAS_PENDING_EXCEPTION) {
// If we have a pending exception we forward it to the caller, unless throw_error is true, // 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, // in which case we have to check whether the pending exception is a ClassNotFoundException,
@ -180,7 +180,7 @@ klassOop SystemDictionary::handle_resolution_exception(symbolHandle class_name,
} }
klassOop SystemDictionary::resolve_or_fail(symbolHandle class_name, klassOop SystemDictionary::resolve_or_fail(Symbol* class_name,
bool throw_error, TRAPS) bool throw_error, TRAPS)
{ {
return resolve_or_fail(class_name, Handle(), Handle(), throw_error, THREAD); return resolve_or_fail(class_name, Handle(), Handle(), throw_error, THREAD);
@ -189,48 +189,49 @@ klassOop SystemDictionary::resolve_or_fail(symbolHandle class_name,
// Forwards to resolve_instance_class_or_null // 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"); 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); 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 { } else {
return resolve_instance_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL); 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); return resolve_or_null(class_name, Handle(), Handle(), THREAD);
} }
// Forwards to resolve_instance_class_or_null // 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 class_loader,
Handle protection_domain, Handle protection_domain,
TRAPS) { TRAPS) {
assert(FieldType::is_array(class_name()), "must be array"); assert(FieldType::is_array(class_name), "must be array");
jint dimension;
symbolOop object_key;
klassOop k = NULL; klassOop k = NULL;
// dimension and object_key are assigned as a side-effect of this call FieldArrayInfo fd;
BasicType t = FieldType::get_array_info(class_name(), // dimension and object_key in FieldArrayInfo are assigned as a side-effect
&dimension, // of this call
&object_key, BasicType t = FieldType::get_array_info(class_name, fd, CHECK_NULL);
CHECK_NULL);
if (t == T_OBJECT) { if (t == T_OBJECT) {
symbolHandle h_key(THREAD, object_key);
// naked oop "k" is OK here -- we assign back into it // 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, class_loader,
protection_domain, protection_domain,
CHECK_NULL); CHECK_NULL);
if (k != NULL) { if (k != NULL) {
k = Klass::cast(k)->array_klass(dimension, CHECK_NULL); k = Klass::cast(k)->array_klass(fd.dimension(), CHECK_NULL);
} }
} else { } else {
k = Universe::typeArrayKlassObj(t); 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; return k;
} }
@ -271,8 +272,8 @@ klassOop SystemDictionary::resolve_array_class_or_null(symbolHandle class_name,
// Must be called, even if superclass is null, since this is // Must be called, even if superclass is null, since this is
// where the placeholder entry is created which claims this // where the placeholder entry is created which claims this
// thread is loading this class/classloader. // thread is loading this class/classloader.
klassOop SystemDictionary::resolve_super_or_fail(symbolHandle child_name, klassOop SystemDictionary::resolve_super_or_fail(Symbol* child_name,
symbolHandle class_name, Symbol* class_name,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
bool is_superclass, bool is_superclass,
@ -281,7 +282,7 @@ klassOop SystemDictionary::resolve_super_or_fail(symbolHandle child_name,
// Try to get one of the well-known klasses. // Try to get one of the well-known klasses.
// They are trusted, and do not participate in circularities. // They are trusted, and do not participate in circularities.
if (LinkWellKnownClasses) { if (LinkWellKnownClasses) {
klassOop k = find_well_known_klass(class_name()); klassOop k = find_well_known_klass(class_name);
if (k != NULL) { if (k != NULL) {
return k; return k;
} }
@ -323,7 +324,7 @@ klassOop SystemDictionary::resolve_super_or_fail(symbolHandle child_name,
if ((childk != NULL ) && (is_superclass) && if ((childk != NULL ) && (is_superclass) &&
((quicksuperk = instanceKlass::cast(childk)->super()) != NULL) && ((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()))) { (Klass::cast(quicksuperk)->class_loader() == class_loader()))) {
return quicksuperk; return quicksuperk;
} else { } else {
@ -342,7 +343,7 @@ klassOop SystemDictionary::resolve_super_or_fail(symbolHandle child_name,
} }
// java.lang.Object should have been found above // 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 // Resolve the super class or interface, check results on return
klassOop superk = NULL; klassOop superk = NULL;
superk = SystemDictionary::resolve_or_null(class_name, superk = SystemDictionary::resolve_or_null(class_name,
@ -392,8 +393,8 @@ void SystemDictionary::validate_protection_domain(instanceKlassHandle klass,
JavaCalls::call_special(&result, JavaCalls::call_special(&result,
class_loader, class_loader,
system_loader, system_loader,
vmSymbolHandles::checkPackageAccess_name(), vmSymbols::checkPackageAccess_name(),
vmSymbolHandles::class_protectiondomain_signature(), vmSymbols::class_protectiondomain_signature(),
Handle(THREAD, klass->java_mirror()), Handle(THREAD, klass->java_mirror()),
protection_domain, protection_domain,
THREAD); THREAD);
@ -414,7 +415,7 @@ void SystemDictionary::validate_protection_domain(instanceKlassHandle klass,
{ {
// We recalculate the entry here -- we've called out to java since // We recalculate the entry here -- we've called out to java since
// the last time it was calculated. // 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); unsigned int d_hash = dictionary()->compute_hash(kn, class_loader);
int d_index = dictionary()->hash_to_index(d_hash); int d_index = dictionary()->hash_to_index(d_hash);
@ -489,7 +490,7 @@ void SystemDictionary::double_lock_wait(Handle lockObject, TRAPS) {
// and we are done, // and we are done,
// If return null klassOop and no pending exception, the caller must load the class // If return null klassOop and no pending exception, the caller must load the class
instanceKlassHandle SystemDictionary::handle_parallel_super_load( 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) { Handle protection_domain, Handle lockObject, TRAPS) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle instanceKlassHandle nh = instanceKlassHandle(); // null Handle
@ -578,17 +579,9 @@ instanceKlassHandle SystemDictionary::handle_parallel_super_load(
} }
klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS) { klassOop SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle class_loader, Handle protection_domain, TRAPS) {
assert(class_name.not_null() && !FieldType::is_array(class_name()), "invalid class name"); assert(name != NULL && !FieldType::is_array(name) &&
// First check to see if we should remove wrapping L and ; !FieldType::is_obj(name), "invalid class name");
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;
}
// UseNewReflection // UseNewReflection
// Fix for 4474172; see evaluation for more details // Fix for 4474172; see evaluation for more details
@ -632,7 +625,7 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam
bool havesupername = false; bool havesupername = false;
instanceKlassHandle k; instanceKlassHandle k;
PlaceholderEntry* placeholder; PlaceholderEntry* placeholder;
symbolHandle superclassname; Symbol* superclassname = NULL;
{ {
MutexLocker mu(SystemDictionary_lock, THREAD); MutexLocker mu(SystemDictionary_lock, THREAD);
@ -646,7 +639,7 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam
if (placeholder && placeholder->super_load_in_progress()) { if (placeholder && placeholder->super_load_in_progress()) {
super_load_in_progress = true; super_load_in_progress = true;
if (placeholder->havesupername() == true) { if (placeholder->havesupername() == true) {
superclassname = symbolHandle(THREAD, placeholder->supername()); superclassname = placeholder->supername();
havesupername = true; havesupername = true;
} }
} }
@ -691,7 +684,6 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam
// No performance benefit and no deadlock issues. // No performance benefit and no deadlock issues.
// case 5. parallelCapable user level classloaders - without objectLocker // case 5. parallelCapable user level classloaders - without objectLocker
// Allow parallel classloading of a class/classloader pair // Allow parallel classloading of a class/classloader pair
symbolHandle nullsymbolHandle;
bool throw_circularity_error = false; bool throw_circularity_error = false;
{ {
MutexLocker mu(SystemDictionary_lock, THREAD); MutexLocker mu(SystemDictionary_lock, THREAD);
@ -733,7 +725,7 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam
// LOAD_INSTANCE in parallel // LOAD_INSTANCE in parallel
// add placeholder entry even if error - callers will remove on error // add placeholder entry even if error - callers will remove on error
if (!throw_circularity_error && !class_has_been_loaded) { 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, // For class loaders that do not acquire the classloader object lock,
// if they did not catch another thread holding LOAD_INSTANCE, // if they did not catch another thread holding LOAD_INSTANCE,
// need a check analogous to the acquire ObjectLocker/find_class // need a check analogous to the acquire ObjectLocker/find_class
@ -837,7 +829,7 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam
{ {
Handle loader (THREAD, k->class_loader()); Handle loader (THREAD, k->class_loader());
MutexLocker mu(SystemDictionary_lock, THREAD); 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"); assert(kk == k(), "should be present in dictionary");
} }
#endif #endif
@ -880,7 +872,7 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam
// _dictionary->bucket(index) is read here, so the caller will not see // _dictionary->bucket(index) is read here, so the caller will not see
// the new entry. // the new entry.
klassOop SystemDictionary::find(symbolHandle class_name, klassOop SystemDictionary::find(Symbol* class_name,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
TRAPS) { TRAPS) {
@ -910,37 +902,34 @@ klassOop SystemDictionary::find(symbolHandle class_name,
// Look for a loaded instance or array klass by name. Do not do any loading. // Look for a loaded instance or array klass by name. Do not do any loading.
// return NULL in case of error. // 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 class_loader,
Handle protection_domain, Handle protection_domain,
TRAPS) { TRAPS) {
klassOop k = NULL; 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. // Try to get one of the well-known klasses.
if (LinkWellKnownClasses) { if (LinkWellKnownClasses) {
k = find_well_known_klass(class_name()); k = find_well_known_klass(class_name);
if (k != NULL) { if (k != NULL) {
return k; return k;
} }
} }
if (FieldType::is_array(class_name())) { if (FieldType::is_array(class_name)) {
// The name refers to an array. Parse the name. // The name refers to an array. Parse the name.
jint dimension; // dimension and object_key in FieldArrayInfo are assigned as a
symbolOop object_key; // side-effect of this call
FieldArrayInfo fd;
// dimension and object_key are assigned as a side-effect of this call BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL));
BasicType t = FieldType::get_array_info(class_name(), &dimension,
&object_key, CHECK_(NULL));
if (t != T_OBJECT) { if (t != T_OBJECT) {
k = Universe::typeArrayKlassObj(t); k = Universe::typeArrayKlassObj(t);
} else { } else {
symbolHandle h_key(THREAD, object_key); k = SystemDictionary::find(fd.object_key(), class_loader, protection_domain, THREAD);
k = SystemDictionary::find(h_key, class_loader, protection_domain, THREAD);
} }
if (k != NULL) { if (k != NULL) {
k = Klass::cast(k)->array_klass_or_null(dimension); k = Klass::cast(k)->array_klass_or_null(fd.dimension());
} }
} else { } else {
k = find(class_name, class_loader, protection_domain, THREAD); k = find(class_name, class_loader, protection_domain, THREAD);
@ -949,7 +938,7 @@ klassOop SystemDictionary::find_instance_or_array_klass(symbolHandle class_name,
} }
// Quick range check for names of well-known classes: // 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 #ifndef PRODUCT
static int find_wkk_calls, find_wkk_probes, find_wkk_wins; static int find_wkk_calls, find_wkk_probes, find_wkk_wins;
@ -957,7 +946,7 @@ static int find_wkk_calls, find_wkk_probes, find_wkk_wins;
// => 60% hit after limit guard, 25% total win rate // => 60% hit after limit guard, 25% total win rate
#endif #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. // A bounds-check on class_name will quickly get a negative result.
NOT_PRODUCT(find_wkk_calls++); NOT_PRODUCT(find_wkk_calls++);
if (class_name >= wk_klass_name_limits[0] && if (class_name >= wk_klass_name_limits[0] &&
@ -983,14 +972,14 @@ klassOop SystemDictionary::find_well_known_klass(symbolOop class_name) {
// Note: this method is much like resolve_from_stream, but // Note: this method is much like resolve_from_stream, but
// updates no supplemental data structures. // updates no supplemental data structures.
// TODO consolidate the two methods with a helper routine? // 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 class_loader,
Handle protection_domain, Handle protection_domain,
ClassFileStream* st, ClassFileStream* st,
KlassHandle host_klass, KlassHandle host_klass,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
TRAPS) { TRAPS) {
symbolHandle parsed_name; TempNewSymbol parsed_name = NULL;
// Parse the stream. Note that we do this even though this klass might // Parse the stream. Note that we do this even though this klass might
// already be present in the SystemDictionary, otherwise we would not // already be present in the SystemDictionary, otherwise we would not
@ -1011,13 +1000,12 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
true, true,
THREAD); THREAD);
// We don't redefine the class, so we just need to clean up whether there // 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 // was an error or not (don't want to modify any system dictionary
// data structures). // data structures).
// Parsed name could be null if we threw an error before we got far // 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. // 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, unsigned int p_hash = placeholders()->compute_hash(parsed_name,
class_loader); class_loader);
int p_index = placeholders()->hash_to_index(p_hash); int p_index = placeholders()->hash_to_index(p_hash);
@ -1060,7 +1048,7 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
// Note: class_name can be NULL. In that case we do not know the name of // Note: class_name can be NULL. In that case we do not know the name of
// the class until we have parsed the stream. // 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 class_loader,
Handle protection_domain, Handle protection_domain,
ClassFileStream* st, ClassFileStream* st,
@ -1079,7 +1067,7 @@ klassOop SystemDictionary::resolve_from_stream(symbolHandle class_name,
check_loader_lock_contention(lockObject, THREAD); check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, DoObjectLock); 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 // Parse the stream. Note that we do this even though this klass might
// already be present in the SystemDictionary, otherwise we would not // already be present in the SystemDictionary, otherwise we would not
@ -1101,7 +1089,7 @@ klassOop SystemDictionary::resolve_from_stream(symbolHandle class_name,
const char* pkg = "java/"; const char* pkg = "java/";
if (!HAS_PENDING_EXCEPTION && if (!HAS_PENDING_EXCEPTION &&
!class_loader.is_null() && !class_loader.is_null() &&
!parsed_name.is_null() && parsed_name != NULL &&
!strncmp((const char*)parsed_name->bytes(), pkg, strlen(pkg))) { !strncmp((const char*)parsed_name->bytes(), pkg, strlen(pkg))) {
// It is illegal to define classes in the "java." package from // It is illegal to define classes in the "java." package from
// JVM_DefineClass or jni_DefineClass unless you're the bootclassloader // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader
@ -1121,9 +1109,8 @@ klassOop SystemDictionary::resolve_from_stream(symbolHandle class_name,
} }
if (!HAS_PENDING_EXCEPTION) { if (!HAS_PENDING_EXCEPTION) {
assert(!parsed_name.is_null(), "Sanity"); assert(parsed_name != NULL, "Sanity");
assert(class_name.is_null() || class_name() == parsed_name(), assert(class_name == NULL || class_name == parsed_name, "name mismatch");
"name mismatch");
// Verification prevents us from creating names with dots in them, this // Verification prevents us from creating names with dots in them, this
// asserts that that's the case. // asserts that that's the case.
assert(is_internal_format(parsed_name), assert(is_internal_format(parsed_name),
@ -1144,7 +1131,7 @@ klassOop SystemDictionary::resolve_from_stream(symbolHandle class_name,
// must make sure parsed_name is valid first (it won't be if we had // 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 // a format error before the class was parsed far enough to
// find the name). // 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, unsigned int p_hash = placeholders()->compute_hash(parsed_name,
class_loader); class_loader);
int p_index = placeholders()->hash_to_index(p_hash); int p_index = placeholders()->hash_to_index(p_hash);
@ -1160,16 +1147,16 @@ klassOop SystemDictionary::resolve_from_stream(symbolHandle class_name,
// SystemDictionary; this is only done on success // SystemDictionary; this is only done on success
debug_only( { debug_only( {
if (!HAS_PENDING_EXCEPTION) { if (!HAS_PENDING_EXCEPTION) {
assert(!parsed_name.is_null(), "parsed_name is still null?"); assert(parsed_name != NULL, "parsed_name is still null?");
symbolHandle h_name (THREAD, k->name()); Symbol* h_name = k->name();
Handle h_loader (THREAD, k->class_loader()); Handle h_loader (THREAD, k->class_loader());
MutexLocker mu(SystemDictionary_lock, THREAD); 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"); 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"); assert(check == check2, "name inconsistancy in SystemDictionary");
} }
} ); } );
@ -1189,7 +1176,7 @@ void SystemDictionary::set_shared_dictionary(HashtableBucket* t, int length,
// If there is a shared dictionary, then find the entry for the // If there is a shared dictionary, then find the entry for the
// given shared system class, if any. // 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) { if (shared_dictionary() != NULL) {
unsigned int d_hash = dictionary()->compute_hash(class_name, Handle()); unsigned int d_hash = dictionary()->compute_hash(class_name, Handle());
int d_index = dictionary()->hash_to_index(d_hash); int d_index = dictionary()->hash_to_index(d_hash);
@ -1207,7 +1194,7 @@ klassOop SystemDictionary::find_shared_class(symbolHandle class_name) {
// object hierarchy until loaded.] // object hierarchy until loaded.]
instanceKlassHandle SystemDictionary::load_shared_class( 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)); instanceKlassHandle ik (THREAD, find_shared_class(class_name));
return load_shared_class(ik, class_loader, THREAD); return load_shared_class(ik, class_loader, THREAD);
} }
@ -1222,14 +1209,14 @@ instanceKlassHandle SystemDictionary::load_shared_class(
assert(class_loader.is_null(), "non-null classloader for shared class?"); assert(class_loader.is_null(), "non-null classloader for shared class?");
if (ik.not_null()) { if (ik.not_null()) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle 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 // Found the class, now load the superclass and interfaces. If they
// are shared, add them to the main system dictionary and reset // are shared, add them to the main system dictionary and reset
// their hierarchy references (supers, subs, and interfaces). // their hierarchy references (supers, subs, and interfaces).
if (ik->super() != NULL) { 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, resolve_super_or_fail(class_name, cn,
class_loader, Handle(), true, CHECK_(nh)); class_loader, Handle(), true, CHECK_(nh));
} }
@ -1243,7 +1230,7 @@ instanceKlassHandle SystemDictionary::load_shared_class(
// interfaces' instanceKlass's C++ vtbls haven't been // interfaces' instanceKlass's C++ vtbls haven't been
// reinitialized yet (they will be once the interface classes // reinitialized yet (they will be once the interface classes
// are loaded) // 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)); resolve_super_or_fail(class_name, name, class_loader, Handle(), false, CHECK_(nh));
} }
@ -1290,7 +1277,7 @@ instanceKlassHandle SystemDictionary::load_shared_class(
// Note that with delegation class loaders all classes in another loader will // Note that with delegation class loaders all classes in another loader will
// first try to call this so it'd better be fast!! // first try to call this so it'd better be fast!!
static instanceKlassHandle download_and_retry_class_load( static instanceKlassHandle download_and_retry_class_load(
symbolHandle class_name, Symbol* class_name,
TRAPS) { TRAPS) {
klassOop dlm = SystemDictionary::sun_jkernel_DownloadManager_klass(); klassOop dlm = SystemDictionary::sun_jkernel_DownloadManager_klass();
@ -1313,8 +1300,8 @@ static instanceKlassHandle download_and_retry_class_load(
// public static String getBootClassPathEntryForClass(String className); // public static String getBootClassPathEntryForClass(String className);
JavaCalls::call_static(&result, JavaCalls::call_static(&result,
KlassHandle(THREAD, dlm), KlassHandle(THREAD, dlm),
vmSymbolHandles::getBootClassPathEntryForClass_name(), vmSymbols::getBootClassPathEntryForClass_name(),
vmSymbolHandles::string_string_signature(), vmSymbols::string_string_signature(),
class_string, class_string,
CHECK_(nk)); CHECK_(nk));
@ -1344,7 +1331,7 @@ static instanceKlassHandle download_and_retry_class_load(
#endif // KERNEL #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 instanceKlassHandle nh = instanceKlassHandle(); // null Handle
if (class_loader.is_null()) { if (class_loader.is_null()) {
@ -1419,16 +1406,16 @@ instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_nam
JavaCalls::call_special(&result, JavaCalls::call_special(&result,
class_loader, class_loader,
spec_klass, spec_klass,
vmSymbolHandles::loadClassInternal_name(), vmSymbols::loadClassInternal_name(),
vmSymbolHandles::string_class_signature(), vmSymbols::string_class_signature(),
string, string,
CHECK_(nh)); CHECK_(nh));
} else { } else {
JavaCalls::call_virtual(&result, JavaCalls::call_virtual(&result,
class_loader, class_loader,
spec_klass, spec_klass,
vmSymbolHandles::loadClass_name(), vmSymbols::loadClass_name(),
vmSymbolHandles::string_class_signature(), vmSymbols::string_class_signature(),
string, string,
CHECK_(nh)); CHECK_(nh));
} }
@ -1444,7 +1431,7 @@ instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_nam
// For user defined Java class loaders, check that the name returned is // For user defined Java class loaders, check that the name returned is
// the same as that requested. This check is done for the bootstrap // the same as that requested. This check is done for the bootstrap
// loader when parsing the class file. // loader when parsing the class file.
if (class_name() == k->name()) { if (class_name == k->name()) {
return k; return k;
} }
} }
@ -1477,7 +1464,7 @@ void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) {
// classloader lock held // classloader lock held
// Parallel classloaders will call find_or_define_instance_class // Parallel classloaders will call find_or_define_instance_class
// which will require a token to perform the define 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); unsigned int d_hash = dictionary()->compute_hash(name_h, class_loader_h);
int d_index = dictionary()->hash_to_index(d_hash); int d_index = dictionary()->hash_to_index(d_hash);
check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK); check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK);
@ -1536,10 +1523,10 @@ void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) {
// findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they // findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they
// potentially waste time reading and parsing the bytestream. // potentially waste time reading and parsing the bytestream.
// Note: VM callers should ensure consistency of k/class_name,class_loader // 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 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); unsigned int d_hash = dictionary()->compute_hash(name_h, class_loader);
int d_index = dictionary()->hash_to_index(d_hash); int d_index = dictionary()->hash_to_index(d_hash);
@ -1560,8 +1547,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle
} }
// Acquire define token for this class/classloader // 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, NULL, THREAD);
probe = placeholders()->find_and_add(p_index, p_hash, name_h, class_loader, PlaceholderTable::DEFINE_CLASS, nullsymbolHandle, THREAD);
// Wait if another thread defining in parallel // Wait if another thread defining in parallel
// All threads wait - even those that will throw duplicate class: otherwise // All threads wait - even those that will throw duplicate class: otherwise
// caller is surprised by LinkageError: duplicate, but findLoadedClass fails // caller is surprised by LinkageError: duplicate, but findLoadedClass fails
@ -1653,7 +1639,7 @@ void SystemDictionary::check_loader_lock_contention(Handle loader_lock, TRAPS) {
// Lookup // Lookup
klassOop SystemDictionary::find_class(int index, unsigned int hash, klassOop SystemDictionary::find_class(int index, unsigned int hash,
symbolHandle class_name, Symbol* class_name,
Handle class_loader) { Handle class_loader) {
assert_locked_or_safepoint(SystemDictionary_lock); assert_locked_or_safepoint(SystemDictionary_lock);
assert (index == dictionary()->index_for(class_name, class_loader), assert (index == dictionary()->index_for(class_name, class_loader),
@ -1665,18 +1651,17 @@ klassOop SystemDictionary::find_class(int index, unsigned int hash,
// Basic find on classes in the midst of being loaded // Basic find on classes in the midst of being loaded
symbolOop SystemDictionary::find_placeholder(int index, unsigned int hash, Symbol* SystemDictionary::find_placeholder(Symbol* class_name,
symbolHandle class_name, Handle class_loader) {
Handle class_loader) {
assert_locked_or_safepoint(SystemDictionary_lock); assert_locked_or_safepoint(SystemDictionary_lock);
unsigned int p_hash = placeholders()->compute_hash(class_name, class_loader);
return placeholders()->find_entry(index, 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 // Used for assertions and verification only
oop SystemDictionary::find_class_or_placeholder(symbolHandle class_name, klassOop SystemDictionary::find_class(Symbol* class_name, Handle class_loader) {
Handle class_loader) {
#ifndef ASSERT #ifndef ASSERT
guarantee(VerifyBeforeGC || guarantee(VerifyBeforeGC ||
VerifyDuringGC || VerifyDuringGC ||
@ -1684,22 +1669,11 @@ oop SystemDictionary::find_class_or_placeholder(symbolHandle class_name,
VerifyAfterGC, "too expensive"); VerifyAfterGC, "too expensive");
#endif #endif
assert_locked_or_safepoint(SystemDictionary_lock); assert_locked_or_safepoint(SystemDictionary_lock);
symbolOop class_name_ = class_name();
oop class_loader_ = class_loader();
// First look in the loaded class array // First look in the loaded class array
unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader); unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader);
int d_index = dictionary()->hash_to_index(d_hash); int d_index = dictionary()->hash_to_index(d_hash);
oop lookup = find_class(d_index, d_hash, class_name, class_loader); return 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;
} }
@ -1757,12 +1731,6 @@ void SystemDictionary::always_strong_classes_do(OopClosure* blk) {
// Visit extra methods // Visit extra methods
invoke_method_table()->oops_do(blk); 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::oops_do(OopClosure* f) {
void SystemDictionary::preloaded_oops_do(OopClosure* f) { 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++) { for (int k = (int)FIRST_WKID; k < (int)WKID_LIMIT; k++) {
f->do_oop((oop*) &_well_known_klasses[k]); f->do_oop((oop*) &_well_known_klasses[k]);
} }
@ -1862,7 +1827,7 @@ void SystemDictionary::classes_do(void f(klassOop, oop, TRAPS), TRAPS) {
dictionary()->classes_do(f, CHECK); 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); placeholders()->entries_do(f);
} }
@ -1882,7 +1847,7 @@ void SystemDictionary::load_abstract_ownable_synchronizer_klass(TRAPS) {
// class is loaded. // class is loaded.
klassOop aos = _abstract_ownable_synchronizer_klass; klassOop aos = _abstract_ownable_synchronizer_klass;
if (aos == NULL) { 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 // Force a fence to prevent any read before the write completes
OrderAccess::fence(); OrderAccess::fence();
_abstract_ownable_synchronizer_klass = k; _abstract_ownable_synchronizer_klass = k;
@ -1924,7 +1889,7 @@ bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) {
assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob"); assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
int info = wk_init_info[id - FIRST_WKID]; int info = wk_init_info[id - FIRST_WKID];
int sid = (info >> CEIL_LG_OPTION_LIMIT); 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]; klassOop* klassp = &_well_known_klasses[id];
bool must_load = (init_opt < SystemDictionary::Opt); bool must_load = (init_opt < SystemDictionary::Opt);
bool try_load = true; bool try_load = true;
@ -1954,7 +1919,7 @@ void SystemDictionary::initialize_wk_klasses_until(WKID limit_id, WKID &start_id
initialize_wk_klass((WKID)id, opt, CHECK); initialize_wk_klass((WKID)id, opt, CHECK);
// Update limits, so find_well_known_klass can be very fast: // 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) { if (wk_klass_name_limits[1] == NULL) {
wk_klass_name_limits[0] = wk_klass_name_limits[1] = s; wk_klass_name_limits[0] = wk_klass_name_limits[1] = s;
} else if (wk_klass_name_limits[1] < s) { } else if (wk_klass_name_limits[1] < s) {
@ -2081,7 +2046,7 @@ void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
TRAPS) { TRAPS) {
const char *linkage_error = NULL; const char *linkage_error = NULL;
{ {
symbolHandle name (THREAD, k->name()); Symbol* name = k->name();
MutexLocker mu(SystemDictionary_lock, THREAD); MutexLocker mu(SystemDictionary_lock, THREAD);
klassOop check = find_class(d_index, d_hash, name, class_loader); klassOop check = find_class(d_index, d_hash, name, class_loader);
@ -2102,10 +2067,8 @@ void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
} }
#ifdef ASSERT #ifdef ASSERT
unsigned int p_hash = placeholders()->compute_hash(name, class_loader); Symbol* ph_check = find_placeholder(name, class_loader);
int p_index = placeholders()->hash_to_index(p_hash); assert(ph_check == NULL || ph_check == name, "invalid symbol");
symbolOop ph_check = find_placeholder(p_index, p_hash, name, class_loader);
assert(ph_check == NULL || ph_check == name(), "invalid symbol");
#endif #endif
if (linkage_error == NULL) { if (linkage_error == NULL) {
@ -2141,7 +2104,7 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
TRAPS) { TRAPS) {
// Compile_lock prevents systemDictionary updates during compilations // Compile_lock prevents systemDictionary updates during compilations
assert_locked_or_safepoint(Compile_lock); assert_locked_or_safepoint(Compile_lock);
symbolHandle name (THREAD, k->name()); Symbol* name = k->name();
{ {
MutexLocker mu1(SystemDictionary_lock, THREAD); MutexLocker mu1(SystemDictionary_lock, THREAD);
@ -2181,7 +2144,7 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
// while only one thread can define a class at one time, multiple // while only one thread can define a class at one time, multiple
// classes can resolve the superclass for a class at one time, // classes can resolve the superclass for a class at one time,
// and the placeholder is used to track that // 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"); // assert (ph_check == NULL, "should not have a placeholder entry");
#endif #endif
SystemDictionary_lock->notify_all(); SystemDictionary_lock->notify_all();
@ -2190,7 +2153,7 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
klassOop SystemDictionary::find_constrained_instance_or_array_klass( 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. // First see if it has been loaded directly.
// Force the protection domain to be null. (This removes protection checks.) // Force the protection domain to be null. (This removes protection checks.)
@ -2203,23 +2166,20 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass(
// Now look to see if it has been loaded elsewhere, and is subject to // 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 // a loader constraint that would require this loader to return the
// klass that is already loaded. // 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 // For array classes, their klassOops are not kept in the
// constraint table. The element klassOops are. // constraint table. The element klassOops are.
jint dimension; FieldArrayInfo fd;
symbolOop object_key; BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL));
BasicType t = FieldType::get_array_info(class_name(), &dimension,
&object_key, CHECK_(NULL));
if (t != T_OBJECT) { if (t != T_OBJECT) {
klass = Universe::typeArrayKlassObj(t); klass = Universe::typeArrayKlassObj(t);
} else { } else {
symbolHandle elem_name(THREAD, object_key);
MutexLocker mu(SystemDictionary_lock, THREAD); 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 element class already loaded, allocate array klass
if (klass != NULL) { if (klass != NULL) {
klass = Klass::cast(klass)->array_klass_or_null(dimension); klass = Klass::cast(klass)->array_klass_or_null(fd.dimension());
} }
} else { } else {
MutexLocker mu(SystemDictionary_lock, THREAD); MutexLocker mu(SystemDictionary_lock, THREAD);
@ -2231,25 +2191,23 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass(
} }
bool SystemDictionary::add_loader_constraint(symbolHandle class_name, bool SystemDictionary::add_loader_constraint(Symbol* class_name,
Handle class_loader1, Handle class_loader1,
Handle class_loader2, Handle class_loader2,
Thread* THREAD) { Thread* THREAD) {
symbolHandle constraint_name; Symbol* constraint_name = NULL;
if (!FieldType::is_array(class_name())) { if (!FieldType::is_array(class_name)) {
constraint_name = class_name; constraint_name = class_name;
} else { } else {
// For array classes, their klassOops are not kept in the // For array classes, their klassOops are not kept in the
// constraint table. The element classes are. // constraint table. The element classes are.
jint dimension; FieldArrayInfo fd;
symbolOop object_key; BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(false));
BasicType t = FieldType::get_array_info(class_name(), &dimension,
&object_key, CHECK_(false));
// primitive types always pass // primitive types always pass
if (t != T_OBJECT) { if (t != T_OBJECT) {
return true; return true;
} else { } else {
constraint_name = symbolHandle(THREAD, object_key); constraint_name = fd.object_key();
} }
} }
unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1); unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1);
@ -2272,7 +2230,7 @@ bool SystemDictionary::add_loader_constraint(symbolHandle class_name,
// Add entry to resolution error table to record the error when the first // Add entry to resolution error table to record the error when the first
// attempt to resolve a reference to a class has failed. // 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); unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash); int index = resolution_errors()->hash_to_index(hash);
{ {
@ -2282,13 +2240,13 @@ void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which,
} }
// Lookup resolution error table. Returns error if found, otherwise NULL. // 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); unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash); int index = resolution_errors()->hash_to_index(hash);
{ {
MutexLocker ml(SystemDictionary_lock, Thread::current()); MutexLocker ml(SystemDictionary_lock, Thread::current());
ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which); 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 @@ symbolOop SystemDictionary::find_resolution_error(constantPoolHandle pool, int w
// NULL if no constraint failed. The returned C string needs cleaning up // NULL if no constraint failed. The returned C string needs cleaning up
// with a ResourceMark in the caller. No exception except OOME is thrown. // with a ResourceMark in the caller. No exception except OOME is thrown.
// Arrays are not added to the loader constraint table, their elements are. // 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, Handle loader1, Handle loader2,
bool is_method, TRAPS) { bool is_method, TRAPS) {
// Nothing to do if loaders are the same. // Nothing to do if loaders are the same.
@ -2352,13 +2310,14 @@ char* SystemDictionary::check_signature_loaders(symbolHandle signature,
return NULL; return NULL;
} }
ResourceMark rm(THREAD);
SignatureStream sig_strm(signature, is_method); SignatureStream sig_strm(signature, is_method);
while (!sig_strm.is_done()) { while (!sig_strm.is_done()) {
if (sig_strm.is_object()) { if (sig_strm.is_object()) {
symbolOop s = sig_strm.as_symbol(CHECK_NULL); Symbol* s = sig_strm.as_symbol(CHECK_NULL);
symbolHandle sig (THREAD, s); Symbol* sig = s;
if (!add_loader_constraint(sig, loader1, loader2, THREAD)) { if (!add_loader_constraint(sig, loader1, loader2, THREAD)) {
return sig()->as_C_string(); return sig->as_C_string();
} }
} }
sig_strm.next(); sig_strm.next();
@ -2367,12 +2326,12 @@ char* SystemDictionary::check_signature_loaders(symbolHandle signature,
} }
methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name, methodOop SystemDictionary::find_method_handle_invoke(Symbol* name,
symbolHandle signature, Symbol* signature,
KlassHandle accessing_klass, KlassHandle accessing_klass,
TRAPS) { TRAPS) {
if (!EnableMethodHandles) return NULL; 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"); assert(name_id != vmSymbols::NO_SID, "must be a known name");
unsigned int hash = invoke_method_table()->compute_hash(signature, name_id); unsigned int hash = invoke_method_table()->compute_hash(signature, name_id);
int index = invoke_method_table()->hash_to_index(hash); int index = invoke_method_table()->hash_to_index(hash);
@ -2385,7 +2344,7 @@ methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
return NULL; // do not attempt from within compiler return NULL; // do not attempt from within compiler
bool for_invokeGeneric = (name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name)); bool for_invokeGeneric = (name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name));
bool found_on_bcp = false; 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, for_invokeGeneric,
found_on_bcp, CHECK_NULL); found_on_bcp, CHECK_NULL);
KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass(); KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass();
@ -2416,7 +2375,7 @@ methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
// signature, as interpreted relative to the given class loader. // signature, as interpreted relative to the given class loader.
// Because of class loader constraints, all method handle usage must be // Because of class loader constraints, all method handle usage must be
// consistent with this loader. // consistent with this loader.
Handle SystemDictionary::find_method_handle_type(symbolHandle signature, Handle SystemDictionary::find_method_handle_type(Symbol* signature,
KlassHandle accessing_klass, KlassHandle accessing_klass,
bool for_invokeGeneric, bool for_invokeGeneric,
bool& return_bcp_flag, bool& return_bcp_flag,
@ -2424,11 +2383,12 @@ Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
Handle class_loader, protection_domain; Handle class_loader, protection_domain;
bool is_on_bcp = true; // keep this true as long as we can materialize from the boot classloader bool is_on_bcp = true; // keep this true as long as we can materialize from the boot classloader
Handle empty; Handle empty;
int npts = ArgumentCount(signature()).size(); int npts = ArgumentCount(signature).size();
objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty)); objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
int arg = 0; int arg = 0;
Handle rt; // the return type from the signature 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; oop mirror = NULL;
if (is_on_bcp) { if (is_on_bcp) {
mirror = ss.as_java_mirror(class_loader, protection_domain, mirror = ss.as_java_mirror(class_loader, protection_domain,
@ -2500,17 +2460,18 @@ Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
Handle SystemDictionary::link_method_handle_constant(KlassHandle caller, Handle SystemDictionary::link_method_handle_constant(KlassHandle caller,
int ref_kind, //e.g., JVM_REF_invokeVirtual int ref_kind, //e.g., JVM_REF_invokeVirtual
KlassHandle callee, KlassHandle callee,
symbolHandle name_sym, Symbol* name_sym,
symbolHandle signature, Symbol* signature,
TRAPS) { TRAPS) {
Handle empty; 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; Handle type;
if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') { if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') {
bool ignore_is_on_bcp = false; bool ignore_is_on_bcp = false;
type = find_method_handle_type(signature, caller, false, ignore_is_on_bcp, CHECK_(empty)); type = find_method_handle_type(signature, caller, false, ignore_is_on_bcp, CHECK_(empty));
} else { } else {
SignatureStream ss(signature(), false); ResourceMark rm(THREAD);
SignatureStream ss(signature, false);
if (!ss.is_done()) { if (!ss.is_done()) {
oop mirror = ss.as_java_mirror(caller->class_loader(), caller->protection_domain(), oop mirror = ss.as_java_mirror(caller->class_loader(), caller->protection_domain(),
SignatureStream::NCDFError, CHECK_(empty)); SignatureStream::NCDFError, CHECK_(empty));
@ -2542,7 +2503,7 @@ Handle SystemDictionary::link_method_handle_constant(KlassHandle caller,
// Ask Java code to find or construct a java.dyn.CallSite for the given // 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. // name and signature, as interpreted relative to the given class loader.
Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method, Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method,
symbolHandle name, Symbol* name,
methodHandle signature_invoker, methodHandle signature_invoker,
Handle info, Handle info,
methodHandle caller_method, methodHandle caller_method,
@ -2557,7 +2518,7 @@ Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method,
MethodHandles::init_MemberName(caller_mname(), caller_method()); MethodHandles::init_MemberName(caller_mname(), caller_method());
// call sun.dyn.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos) // 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())); JavaCallArguments args(Handle(THREAD, bootstrap_method()));
args.push_oop(name_str_oop); args.push_oop(name_str_oop);
args.push_oop(signature_invoker->method_handle_type()); args.push_oop(signature_invoker->method_handle_type());
@ -2740,16 +2701,20 @@ void SystemDictionary::verify() {
void SystemDictionary::verify_obj_klass_present(Handle obj, void SystemDictionary::verify_obj_klass_present(Handle obj,
symbolHandle class_name, Symbol* class_name,
Handle class_loader) { Handle class_loader) {
GCMutexLocker mu(SystemDictionary_lock); 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) { if (probe == NULL) {
probe = SystemDictionary::find_shared_class(class_name); probe = SystemDictionary::find_shared_class(class_name);
if (probe == NULL) {
name = find_placeholder(class_name, class_loader);
}
} }
guarantee(probe != NULL && guarantee(probe != NULL || name != NULL,
(!probe->is_klass() || probe == obj()), "Loaded klasses should be in SystemDictionary");
"Loaded klasses should be in SystemDictionary");
} }
#ifndef PRODUCT #ifndef PRODUCT

View File

@ -28,14 +28,14 @@
#include "classfile/classFileStream.hpp" #include "classfile/classFileStream.hpp"
#include "classfile/classLoader.hpp" #include "classfile/classLoader.hpp"
#include "oops/objArrayOop.hpp" #include "oops/objArrayOop.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
#include "runtime/reflectionUtils.hpp" #include "runtime/reflectionUtils.hpp"
#include "utilities/hashtable.hpp" #include "utilities/hashtable.hpp"
// The system dictionary stores all loaded classes and maps: // 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 // Classes are loaded lazily. The default VM class loader is
// represented as NULL. // represented as NULL.
@ -226,26 +226,26 @@ class SystemDictionary : AllStatic {
// throw_error flag. For most uses the throw_error argument should be set // throw_error flag. For most uses the throw_error argument should be set
// to true. // 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. // 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: private:
// handle error translation for resolve_or_null results // 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: public:
// Returns a class with a given class name and class loader. // Returns a class with a given class name and class loader.
// Loads the class if needed. If not found NULL is returned. // 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 // 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, // Resolve a superclass or superinterface. Called from ClassFileParser,
// parse_interfaces, resolve_instance_class_or_null, load_shared_class // parse_interfaces, resolve_instance_class_or_null, load_shared_class
// "child_name" is the class whose super class or interface is being resolved. // "child_name" is the class whose super class or interface is being resolved.
static klassOop resolve_super_or_fail(symbolHandle child_name, static klassOop resolve_super_or_fail(Symbol* child_name,
symbolHandle class_name, Symbol* class_name,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
bool is_superclass, bool is_superclass,
@ -253,7 +253,7 @@ public:
// Parse new stream. This won't update the system dictionary or // Parse new stream. This won't update the system dictionary or
// class hierarchy, simply parse the stream. Used by JVMTI RedefineClasses. // 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 class_loader,
Handle protection_domain, Handle protection_domain,
ClassFileStream* st, ClassFileStream* st,
@ -261,7 +261,7 @@ public:
KlassHandle nullHandle; KlassHandle nullHandle;
return parse_stream(class_name, class_loader, protection_domain, st, nullHandle, NULL, THREAD); 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 class_loader,
Handle protection_domain, Handle protection_domain,
ClassFileStream* st, ClassFileStream* st,
@ -270,23 +270,23 @@ public:
TRAPS); TRAPS);
// Resolve from stream (called by jni_DefineClass and JVM_DefineClass) // 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, Handle protection_domain,
ClassFileStream* st, bool verify, TRAPS); ClassFileStream* st, bool verify, TRAPS);
// Lookup an already loaded class. If not found NULL is returned. // 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. // Lookup an already loaded instance or array class.
// Do not make any queries to class loaders; consult only the cache. // Do not make any queries to class loaders; consult only the cache.
// If not found NULL is returned. // 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 class_loader,
Handle protection_domain, Handle protection_domain,
TRAPS); TRAPS);
// If the given name is known to vmSymbols, return the well-know klass: // 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 // Lookup an instance or array class that has already been loaded
// either into the given class loader, or else into another class // either into the given class loader, or else into another class
@ -309,7 +309,7 @@ public:
// satisfied, and it is safe for classes in the given class loader // satisfied, and it is safe for classes in the given class loader
// to manipulate strongly-typed values of the found class, subject // to manipulate strongly-typed values of the found class, subject
// to local linkage and access checks. // 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, Handle class_loader,
TRAPS); TRAPS);
@ -324,7 +324,7 @@ public:
// (added for helpers that use HandleMarks and ResourceMarks) // (added for helpers that use HandleMarks and ResourceMarks)
static void classes_do(void f(klassOop, oop, TRAPS), TRAPS); static void classes_do(void f(klassOop, oop, TRAPS), TRAPS);
// All entries in the placeholder table and their class loaders // 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 // Iterate over all methods in all klasses in dictionary
static void methods_do(void f(methodOop)); static void methods_do(void f(methodOop));
@ -383,12 +383,12 @@ public:
static void verify(); static void verify();
#ifdef ASSERT #ifdef ASSERT
static bool is_internal_format(symbolHandle class_name); static bool is_internal_format(Symbol* class_name);
#endif #endif
// Verify class is in dictionary // Verify class is in dictionary
static void verify_obj_klass_present(Handle obj, static void verify_obj_klass_present(Handle obj,
symbolHandle class_name, Symbol* class_name,
Handle class_loader); Handle class_loader);
// Initialization // Initialization
@ -469,19 +469,19 @@ public:
// Note: java_lang_Class::primitive_type is the inverse of java_mirror // Note: java_lang_Class::primitive_type is the inverse of java_mirror
// Check class loader constraints // 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); 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); Handle loader2, bool is_method, TRAPS);
// JSR 292 // JSR 292
// find the java.dyn.MethodHandles::invoke method for a given signature // find the java.dyn.MethodHandles::invoke method for a given signature
static methodOop find_method_handle_invoke(symbolHandle name, static methodOop find_method_handle_invoke(Symbol* name,
symbolHandle signature, Symbol* signature,
KlassHandle accessing_klass, KlassHandle accessing_klass,
TRAPS); TRAPS);
// ask Java to compute a java.dyn.MethodType object for a given signature // 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, KlassHandle accessing_klass,
bool for_invokeGeneric, bool for_invokeGeneric,
bool& return_bcp_flag, bool& return_bcp_flag,
@ -490,13 +490,13 @@ public:
static Handle link_method_handle_constant(KlassHandle caller, static Handle link_method_handle_constant(KlassHandle caller,
int ref_kind, //e.g., JVM_REF_invokeVirtual int ref_kind, //e.g., JVM_REF_invokeVirtual
KlassHandle callee, KlassHandle callee,
symbolHandle name, Symbol* name,
symbolHandle signature, Symbol* signature,
TRAPS); TRAPS);
// ask Java to create a dynamic call site, while linking an invokedynamic op // ask Java to create a dynamic call site, while linking an invokedynamic op
static Handle make_dynamic_call_site(Handle bootstrap_method, static Handle make_dynamic_call_site(Handle bootstrap_method,
// Callee information: // Callee information:
symbolHandle name, Symbol* name,
methodHandle signature_invoker, methodHandle signature_invoker,
Handle info, Handle info,
// Caller information: // Caller information:
@ -519,8 +519,8 @@ public:
// Record the error when the first attempt to resolve a reference from a constant // Record the error when the first attempt to resolve a reference from a constant
// pool entry to a class fails. // pool entry to a class fails.
static void add_resolution_error(constantPoolHandle pool, int which, symbolHandle error); static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error);
static symbolOop find_resolution_error(constantPoolHandle pool, int which); static Symbol* find_resolution_error(constantPoolHandle pool, int which);
private: private:
@ -580,29 +580,29 @@ private:
static SymbolPropertyTable* invoke_method_table() { return _invoke_method_table; } static SymbolPropertyTable* invoke_method_table() { return _invoke_method_table; }
// Basic loading operations // Basic loading operations
static klassOop resolve_instance_class_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, 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(symbolHandle 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(symbolHandle class_name, symbolHandle supername, Handle class_loader, Handle protection_domain, Handle lockObject, 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 // Wait on SystemDictionary_lock; unlocks lockObject before
// waiting; relocks lockObject with correct recursion count // waiting; relocks lockObject with correct recursion count
// after waiting, but before reentering SystemDictionary_lock // after waiting, but before reentering SystemDictionary_lock
// to preserve lock order semantics. // to preserve lock order semantics.
static void double_lock_wait(Handle lockObject, TRAPS); static void double_lock_wait(Handle lockObject, TRAPS);
static void define_instance_class(instanceKlassHandle k, 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, Handle class_loader,
instanceKlassHandle k, TRAPS); instanceKlassHandle k, TRAPS);
static instanceKlassHandle load_shared_class(symbolHandle class_name, static instanceKlassHandle load_shared_class(Symbol* class_name,
Handle class_loader, TRAPS); Handle class_loader, TRAPS);
static instanceKlassHandle load_shared_class(instanceKlassHandle ik, static instanceKlassHandle load_shared_class(instanceKlassHandle ik,
Handle class_loader, TRAPS); 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 Handle compute_loader_lock_object(Handle class_loader, TRAPS);
static void check_loader_lock_contention(Handle loader_lock, TRAPS); static void check_loader_lock_contention(Handle loader_lock, TRAPS);
static bool is_parallelCapable(Handle class_loader); static bool is_parallelCapable(Handle class_loader);
static bool is_parallelDefine(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 // Setup link to hierarchy
static void add_to_hierarchy(instanceKlassHandle k, TRAPS); static void add_to_hierarchy(instanceKlassHandle k, TRAPS);
@ -613,34 +613,29 @@ private:
// Basic find on loaded classes // Basic find on loaded classes
static klassOop find_class(int index, unsigned int hash, 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 // Basic find on classes in the midst of being loaded
static symbolOop find_placeholder(int index, unsigned int hash, static Symbol* find_placeholder(Symbol* name, Handle loader);
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);
// Updating entry in dictionary // Updating entry in dictionary
// Add a completely loaded class // 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); Handle class_loader, KlassHandle obj);
// Add a placeholder for a class being loaded // Add a placeholder for a class being loaded
static void add_placeholder(int index, static void add_placeholder(int index,
symbolHandle class_name, Symbol* class_name,
Handle class_loader); Handle class_loader);
static void remove_placeholder(int index, static void remove_placeholder(int index,
symbolHandle class_name, Symbol* class_name,
Handle class_loader); Handle class_loader);
// Performs cleanups after resolve_super_or_fail. This typically needs // Performs cleanups after resolve_super_or_fail. This typically needs
// to be called on failure. // to be called on failure.
// Won't throw, but can block. // Won't throw, but can block.
static void resolution_cleanups(symbolHandle class_name, static void resolution_cleanups(Symbol* class_name,
Handle class_loader, Handle class_loader,
TRAPS); TRAPS);
@ -670,7 +665,6 @@ private:
static bool _has_checkPackageAccess; static bool _has_checkPackageAccess;
}; };
// Cf. vmSymbols vs. vmSymbolHandles
class SystemDictionaryHandles : AllStatic { class SystemDictionaryHandles : AllStatic {
public: public:
#define WK_KLASS_HANDLE_DECLARE(name, ignore_symbol, option) \ #define WK_KLASS_HANDLE_DECLARE(name, ignore_symbol, option) \

View File

@ -25,6 +25,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "classfile/symbolTable.hpp" #include "classfile/symbolTable.hpp"
#include "classfile/verificationType.hpp" #include "classfile/verificationType.hpp"
#include "classfile/verifier.hpp"
VerificationType VerificationType::from_tag(u1 tag) { VerificationType VerificationType::from_tag(u1 tag) {
switch (tag) { switch (tag) {
@ -41,7 +42,8 @@ VerificationType VerificationType::from_tag(u1 tag) {
} }
bool VerificationType::is_reference_assignable_from( 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()) { if (from.is_null()) {
// null is assignable to any reference // null is assignable to any reference
return true; return true;
@ -56,8 +58,8 @@ bool VerificationType::is_reference_assignable_from(
return true; return true;
} }
klassOop obj = SystemDictionary::resolve_or_fail( klassOop obj = SystemDictionary::resolve_or_fail(
name_handle(), Handle(THREAD, context->class_loader()), name(), Handle(THREAD, klass->class_loader()),
Handle(THREAD, context->protection_domain()), true, CHECK_false); Handle(THREAD, klass->protection_domain()), true, CHECK_false);
KlassHandle this_class(THREAD, obj); KlassHandle this_class(THREAD, obj);
if (this_class->is_interface()) { if (this_class->is_interface()) {
@ -66,13 +68,13 @@ bool VerificationType::is_reference_assignable_from(
return true; return true;
} else if (from.is_object()) { } else if (from.is_object()) {
klassOop from_class = SystemDictionary::resolve_or_fail( klassOop from_class = SystemDictionary::resolve_or_fail(
from.name_handle(), Handle(THREAD, context->class_loader()), from.name(), Handle(THREAD, klass->class_loader()),
Handle(THREAD, context->protection_domain()), true, CHECK_false); Handle(THREAD, klass->protection_domain()), true, CHECK_false);
return instanceKlass::cast(from_class)->is_subclass_of(this_class()); return instanceKlass::cast(from_class)->is_subclass_of(this_class());
} }
} else if (is_array() && from.is_array()) { } else if (is_array() && from.is_array()) {
VerificationType comp_this = get_component(CHECK_false); VerificationType comp_this = get_component(context, CHECK_false);
VerificationType comp_from = from.get_component(CHECK_false); VerificationType comp_from = from.get_component(context, CHECK_false);
if (!comp_this.is_bogus() && !comp_from.is_bogus()) { if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
return comp_this.is_assignable_from(comp_from, context, CHECK_false); return comp_this.is_assignable_from(comp_from, context, CHECK_false);
} }
@ -80,9 +82,9 @@ bool VerificationType::is_reference_assignable_from(
return false; 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"); assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
symbolOop component; Symbol* component;
switch (name()->byte_at(1)) { switch (name()->byte_at(1)) {
case 'Z': return VerificationType(Boolean); case 'Z': return VerificationType(Boolean);
case 'B': return VerificationType(Byte); case 'B': return VerificationType(Byte);
@ -93,12 +95,12 @@ VerificationType VerificationType::get_component(TRAPS) const {
case 'F': return VerificationType(Float); case 'F': return VerificationType(Float);
case 'D': return VerificationType(Double); case 'D': return VerificationType(Double);
case '[': case '[':
component = SymbolTable::lookup( component = context->create_temporary_symbol(
name(), 1, name()->utf8_length(), name(), 1, name()->utf8_length(),
CHECK_(VerificationType::bogus_type())); CHECK_(VerificationType::bogus_type()));
return VerificationType::reference_type(component); return VerificationType::reference_type(component);
case 'L': case 'L':
component = SymbolTable::lookup( component = context->create_temporary_symbol(
name(), 2, name()->utf8_length() - 1, name(), 2, name()->utf8_length() - 1,
CHECK_(VerificationType::bogus_type())); CHECK_(VerificationType::bogus_type()));
return VerificationType::reference_type(component); return VerificationType::reference_type(component);

View File

@ -29,7 +29,7 @@
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "oops/instanceKlass.hpp" #include "oops/instanceKlass.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "oops/symbolOop.hpp" #include "oops/symbol.hpp"
#include "runtime/handles.hpp" #include "runtime/handles.hpp"
#include "runtime/signature.hpp" #include "runtime/signature.hpp"
@ -47,6 +47,8 @@ enum {
ITEM_Bogus = (uint)-1 ITEM_Bogus = (uint)-1
}; };
class ClassVerifier;
class VerificationType VALUE_OBJ_CLASS_SPEC { class VerificationType VALUE_OBJ_CLASS_SPEC {
private: private:
// Least significant bits of _handle are always 0, so we use these as // Least significant bits of _handle are always 0, so we use these as
@ -56,7 +58,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
// will catch this and we'll have to add a descriminator tag to this // will catch this and we'll have to add a descriminator tag to this
// structure. // structure.
union { union {
symbolOop* _handle; Symbol* _sym;
uintptr_t _data; uintptr_t _data;
} _u; } _u;
@ -73,7 +75,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
TypeMask = 0x00000003, TypeMask = 0x00000003,
// Topmost types encoding // Topmost types encoding
Reference = 0x0, // _handle contains the name Reference = 0x0, // _sym contains the name
Primitive = 0x1, // see below for primitive list Primitive = 0x1, // see below for primitive list
Uninitialized = 0x2, // 0x00ffff00 contains bci Uninitialized = 0x2, // 0x00ffff00 contains bci
TypeQuery = 0x3, // Meta-types used for category testing TypeQuery = 0x3, // Meta-types used for category testing
@ -85,7 +87,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
Category2_2ndFlag = 0x04, // Second word of a two-word value Category2_2ndFlag = 0x04, // Second word of a two-word value
// special reference values // 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) // Primitives categories (the second byte determines the category)
Category1 = (Category1Flag << 1 * BitsPerByte) | Primitive, Category1 = (Category1Flag << 1 * BitsPerByte) | Primitive,
@ -152,17 +154,14 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
static VerificationType category2_2nd_check() static VerificationType category2_2nd_check()
{ return VerificationType(Category2_2ndQuery); } { return VerificationType(Category2_2ndQuery); }
// For reference types, store the actual oop* handle // For reference types, store the actual Symbol
static VerificationType reference_type(symbolHandle sh) { static VerificationType reference_type(Symbol* sh) {
assert(((uintptr_t)sh.raw_value() & 0x3) == 0, "Oops must be aligned"); assert(((uintptr_t)sh & 0x3) == 0, "Oops must be aligned");
// If the above assert fails in the future because oop* isn't 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 // then this type encoding system will have to change to have a tag value
// to descriminate between oops and primitives. // 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) static VerificationType uninitialized_type(u2 bci)
{ return VerificationType(bci << 1 * BitsPerByte | Uninitialized); } { return VerificationType(bci << 1 * BitsPerByte | Uninitialized); }
static VerificationType uninitialized_this_type() static VerificationType uninitialized_this_type()
@ -242,13 +241,9 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
return ((_u._data & BciMask) >> 1 * BitsPerByte); return ((_u._data & BciMask) >> 1 * BitsPerByte);
} }
symbolHandle name_handle() const { Symbol* name() const {
assert(is_reference() && !is_null(), "Must be a non-null reference"); assert(is_reference() && !is_null(), "Must be a non-null reference");
return symbolHandle(_u._handle, true); return _u._sym;
}
symbolOop name() const {
assert(is_reference() && !is_null(), "Must be a non-null reference");
return *(_u._handle);
} }
bool equals(const VerificationType& t) const { bool equals(const VerificationType& t) const {
@ -269,7 +264,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
// is assignable to another. Returns true if one can assign 'from' to // is assignable to another. Returns true if one can assign 'from' to
// this. // this.
bool is_assignable_from( bool is_assignable_from(
const VerificationType& from, instanceKlassHandle context, TRAPS) const { const VerificationType& from, ClassVerifier* context, TRAPS) const {
if (equals(from) || is_bogus()) { if (equals(from) || is_bogus()) {
return true; return true;
} else { } else {
@ -298,7 +293,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
} }
} }
VerificationType get_component(TRAPS) const; VerificationType get_component(ClassVerifier* context, TRAPS) const;
int dimensions() const { int dimensions() const {
assert(is_array(), "Must be an array"); assert(is_array(), "Must be an array");
@ -312,7 +307,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
private: private:
bool is_reference_assignable_from( bool is_reference_assignable_from(
const VerificationType&, instanceKlassHandle, TRAPS) const; const VerificationType&, ClassVerifier*, TRAPS) const;
}; };
#endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP #endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP

View File

@ -98,10 +98,10 @@ bool Verifier::relax_verify_for(oop loader) {
} }
bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) { bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm; HandleMark hm;
ResourceMark rm(THREAD);
symbolHandle exception_name; Symbol* exception_name = NULL;
const size_t message_buffer_len = klass->name()->utf8_length() + 1024; const size_t message_buffer_len = klass->name()->utf8_length() + 1024;
char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len); char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
@ -141,7 +141,7 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool shoul
tty->print("Verification for %s has", klassName); tty->print("Verification for %s has", klassName);
tty->print_cr(" exception pending %s ", tty->print_cr(" exception pending %s ",
instanceKlass::cast(PENDING_EXCEPTION->klass())->external_name()); 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("Verification for %s failed", klassName);
} }
tty->print_cr("End class verification for: %s", klassName); tty->print_cr("End class verification for: %s", klassName);
@ -150,7 +150,7 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool shoul
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
return false; // use the existing exception return false; // use the existing exception
} else if (exception_name.is_null()) { } else if (exception_name == NULL) {
return true; // verifcation succeeded return true; // verifcation succeeded
} else { // VerifyError or ClassFormatError to be created and thrown } else { // VerifyError or ClassFormatError to be created and thrown
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
@ -172,7 +172,7 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool shoul
} }
bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { 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(); klassOop refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass();
return (should_verify_for(klass->class_loader(), should_verify_class) && return (should_verify_for(klass->class_loader(), should_verify_class) &&
@ -202,7 +202,7 @@ bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool shou
); );
} }
symbolHandle Verifier::inference_verify( Symbol* Verifier::inference_verify(
instanceKlassHandle klass, char* message, size_t message_len, TRAPS) { instanceKlassHandle klass, char* message, size_t message_len, TRAPS) {
JavaThread* thread = (JavaThread*)THREAD; JavaThread* thread = (JavaThread*)THREAD;
JNIEnv *env = thread->jni_environment(); JNIEnv *env = thread->jni_environment();
@ -245,18 +245,17 @@ symbolHandle Verifier::inference_verify(
// These numbers are chosen so that VerifyClassCodes interface doesn't need // These numbers are chosen so that VerifyClassCodes interface doesn't need
// to be changed (still return jboolean (unsigned char)), and result is // to be changed (still return jboolean (unsigned char)), and result is
// 1 when verification is passed. // 1 when verification is passed.
symbolHandle nh(NULL);
if (result == 0) { if (result == 0) {
return vmSymbols::java_lang_VerifyError(); return vmSymbols::java_lang_VerifyError();
} else if (result == 1) { } else if (result == 1) {
return nh; // verified. return NULL; // verified.
} else if (result == 2) { } else if (result == 2) {
THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, nh); THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, NULL);
} else if (result == 3) { } else if (result == 3) {
return vmSymbols::java_lang_ClassFormatError(); return vmSymbols::java_lang_ClassFormatError();
} else { } else {
ShouldNotReachHere(); ShouldNotReachHere();
return nh; return NULL;
} }
} }
@ -266,12 +265,19 @@ bool ClassVerifier::_verify_verbose = false;
ClassVerifier::ClassVerifier( ClassVerifier::ClassVerifier(
instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS) 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) { _message_buffer_len(msg_len), _klass(klass) {
_this_type = VerificationType::reference_type(klass->name()); _this_type = VerificationType::reference_type(klass->name());
// Create list to hold symbols in reference area.
_symbols = new GrowableArray<Symbol*>(100, 0, NULL);
} }
ClassVerifier::~ClassVerifier() { 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 { VerificationType ClassVerifier::object_type() const {
@ -308,7 +314,6 @@ void ClassVerifier::verify_class(TRAPS) {
} }
void ClassVerifier::verify_method(methodHandle m, TRAPS) { void ClassVerifier::verify_method(methodHandle m, TRAPS) {
ResourceMark rm(THREAD);
_method = m; // initialize _method _method = m; // initialize _method
if (_verify_verbose) { if (_verify_verbose) {
tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string()); tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string());
@ -615,7 +620,7 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) {
VerificationType::null_type(), CHECK_VERIFY(this)); VerificationType::null_type(), CHECK_VERIFY(this));
} else { } else {
VerificationType component = VerificationType component =
atype.get_component(CHECK_VERIFY(this)); atype.get_component(this, CHECK_VERIFY(this));
current_frame.push_stack(component, CHECK_VERIFY(this)); current_frame.push_stack(component, CHECK_VERIFY(this));
} }
no_control_flow = false; break; no_control_flow = false; break;
@ -1386,7 +1391,7 @@ void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_da
VerificationType throwable = VerificationType throwable =
VerificationType::reference_type(vmSymbols::java_lang_Throwable()); VerificationType::reference_type(vmSymbols::java_lang_Throwable());
bool is_subclass = throwable.is_assignable_from( bool is_subclass = throwable.is_assignable_from(
catch_type, current_class(), CHECK_VERIFY(this)); catch_type, this, CHECK_VERIFY(this));
if (!is_subclass) { if (!is_subclass) {
// 4286534: should throw VerifyError according to recent spec change // 4286534: should throw VerifyError according to recent spec change
verify_error( verify_error(
@ -1473,8 +1478,6 @@ void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, S
if(bci >= start_pc && bci < end_pc) { if(bci >= start_pc && bci < end_pc) {
u1 flags = current_frame->flags(); u1 flags = current_frame->flags();
if (this_uninit) { flags |= FLAG_THIS_UNINIT; } if (this_uninit) { flags |= FLAG_THIS_UNINIT; }
ResourceMark rm(THREAD);
StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
if (catch_type_index != 0) { if (catch_type_index != 0) {
// We know that this index refers to a subclass of Throwable // We know that this index refers to a subclass of Throwable
@ -1575,7 +1578,7 @@ void ClassVerifier::class_format_error(const char* msg, ...) {
va_end(va); va_end(va);
} }
klassOop ClassVerifier::load_class(symbolHandle name, TRAPS) { klassOop ClassVerifier::load_class(Symbol* name, TRAPS) {
// Get current loader and protection domain first. // Get current loader and protection domain first.
oop loader = current_class()->class_loader(); oop loader = current_class()->class_loader();
oop protection_domain = current_class()->protection_domain(); oop protection_domain = current_class()->protection_domain();
@ -1587,8 +1590,8 @@ klassOop ClassVerifier::load_class(symbolHandle name, TRAPS) {
bool ClassVerifier::is_protected_access(instanceKlassHandle this_class, bool ClassVerifier::is_protected_access(instanceKlassHandle this_class,
klassOop target_class, klassOop target_class,
symbolOop field_name, Symbol* field_name,
symbolOop field_sig, Symbol* field_sig,
bool is_method) { bool is_method) {
No_Safepoint_Verifier nosafepoint; No_Safepoint_Verifier nosafepoint;
@ -1736,7 +1739,7 @@ void ClassVerifier::verify_switch(
} }
bool ClassVerifier::name_in_supers( bool ClassVerifier::name_in_supers(
symbolOop ref_name, instanceKlassHandle current) { Symbol* ref_name, instanceKlassHandle current) {
klassOop super = current->super(); klassOop super = current->super();
while (super != NULL) { while (super != NULL) {
if (super->klass_part()->name() == ref_name) { if (super->klass_part()->name() == ref_name) {
@ -1755,8 +1758,8 @@ void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this)); verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this));
// Get field name and signature // Get field name and signature
symbolHandle field_name = symbolHandle(THREAD, cp->name_ref_at(index)); Symbol* field_name = cp->name_ref_at(index);
symbolHandle field_sig = symbolHandle(THREAD, cp->signature_ref_at(index)); Symbol* field_sig = cp->signature_ref_at(index);
if (!SignatureVerifier::is_valid_type_signature(field_sig)) { if (!SignatureVerifier::is_valid_type_signature(field_sig)) {
class_format_error( class_format_error(
@ -1823,11 +1826,11 @@ void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
fieldDescriptor fd; fieldDescriptor fd;
if (stack_object_type == VerificationType::uninitialized_this_type() && if (stack_object_type == VerificationType::uninitialized_this_type() &&
target_class_type.equals(current_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(); stack_object_type = current_type();
} }
is_assignable = target_class_type.is_assignable_from( 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) { if (!is_assignable) {
verify_error(bci, "Bad type on operand stack in putfield"); verify_error(bci, "Bad type on operand stack in putfield");
return; return;
@ -1836,9 +1839,9 @@ void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
check_protected: { check_protected: {
if (_this_type == stack_object_type) if (_this_type == stack_object_type)
break; // stack_object_type must be assignable to _current_class_type break; // stack_object_type must be assignable to _current_class_type
symbolHandle ref_class_name = symbolHandle(THREAD, Symbol* ref_class_name =
cp->klass_name_at(cp->klass_ref_index_at(index))); cp->klass_name_at(cp->klass_ref_index_at(index));
if (!name_in_supers(ref_class_name(), current_class())) if (!name_in_supers(ref_class_name, current_class()))
// stack_object_type must be assignable to _current_class_type since: // stack_object_type must be assignable to _current_class_type since:
// 1. stack_object_type must be assignable to ref_class. // 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 // 2. ref_class must be _current_class or a subclass of it. It can't
@ -1846,12 +1849,12 @@ void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
break; break;
klassOop ref_class_oop = load_class(ref_class_name, CHECK); klassOop ref_class_oop = load_class(ref_class_name, CHECK);
if (is_protected_access(current_class(), ref_class_oop, field_name(), if (is_protected_access(current_class(), ref_class_oop, field_name,
field_sig(), false)) { field_sig, false)) {
// It's protected access, check if stack object is assignable to // It's protected access, check if stack object is assignable to
// current class. // current class.
is_assignable = current_type().is_assignable_from( 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 (!is_assignable) {
verify_error(bci, "Bad access to protected data in getfield"); verify_error(bci, "Bad access to protected data in getfield");
return; return;
@ -1911,7 +1914,7 @@ void ClassVerifier::verify_invoke_init(
instanceKlassHandle mh(THREAD, m->method_holder()); instanceKlassHandle mh(THREAD, m->method_holder());
if (m->is_protected() && !mh->is_same_class_package(_klass())) { if (m->is_protected() && !mh->is_same_class_package(_klass())) {
bool assignable = current_type().is_assignable_from( bool assignable = current_type().is_assignable_from(
objectref_type, current_class(), CHECK_VERIFY(this)); objectref_type, this, CHECK_VERIFY(this));
if (!assignable) { if (!assignable) {
verify_error(bci, "Bad access to protected <init> method"); verify_error(bci, "Bad access to protected <init> method");
return; return;
@ -1941,8 +1944,8 @@ void ClassVerifier::verify_invoke_instructions(
verify_cp_type(index, cp, types, CHECK_VERIFY(this)); verify_cp_type(index, cp, types, CHECK_VERIFY(this));
// Get method name and signature // Get method name and signature
symbolHandle method_name(THREAD, cp->name_ref_at(index)); Symbol* method_name = cp->name_ref_at(index);
symbolHandle method_sig(THREAD, cp->signature_ref_at(index)); Symbol* method_sig = cp->signature_ref_at(index);
if (!SignatureVerifier::is_valid_method_signature(method_sig)) { if (!SignatureVerifier::is_valid_method_signature(method_sig)) {
class_format_error( class_format_error(
@ -2035,7 +2038,7 @@ void ClassVerifier::verify_invoke_instructions(
if (method_name->byte_at(0) == '<') { if (method_name->byte_at(0) == '<') {
// Make sure <init> can only be invoked by invokespecial // Make sure <init> can only be invoked by invokespecial
if (opcode != Bytecodes::_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"); verify_error(bci, "Illegal call to internal method");
return; return;
} }
@ -2044,7 +2047,7 @@ void ClassVerifier::verify_invoke_instructions(
&& !ref_class_type.equals(VerificationType::reference_type( && !ref_class_type.equals(VerificationType::reference_type(
current_class()->super()->klass_part()->name()))) { current_class()->super()->klass_part()->name()))) {
bool subtype = ref_class_type.is_assignable_from( bool subtype = ref_class_type.is_assignable_from(
current_type(), current_class(), CHECK_VERIFY(this)); current_type(), this, CHECK_VERIFY(this));
if (!subtype) { if (!subtype) {
verify_error(bci, "Bad invokespecial instruction: " verify_error(bci, "Bad invokespecial instruction: "
"current class isn't assignable to reference class."); "current class isn't assignable to reference class.");
@ -2058,7 +2061,7 @@ void ClassVerifier::verify_invoke_instructions(
// Check objectref on operand stack // Check objectref on operand stack
if (opcode != Bytecodes::_invokestatic && if (opcode != Bytecodes::_invokestatic &&
opcode != Bytecodes::_invokedynamic) { opcode != Bytecodes::_invokedynamic) {
if (method_name() == vmSymbols::object_initializer_name()) { // <init> method if (method_name == vmSymbols::object_initializer_name()) { // <init> method
verify_invoke_init(bcs, ref_class_type, current_frame, verify_invoke_init(bcs, ref_class_type, current_frame,
code_length, this_uninit, cp, CHECK_VERIFY(this)); code_length, this_uninit, cp, CHECK_VERIFY(this));
} else { // other methods } else { // other methods
@ -2070,22 +2073,22 @@ void ClassVerifier::verify_invoke_instructions(
current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this)); current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));
if (current_type() != stack_object_type) { if (current_type() != stack_object_type) {
assert(cp->cache() == NULL, "not rewritten yet"); assert(cp->cache() == NULL, "not rewritten yet");
symbolHandle ref_class_name = symbolHandle(THREAD, Symbol* ref_class_name =
cp->klass_name_at(cp->klass_ref_index_at(index))); cp->klass_name_at(cp->klass_ref_index_at(index));
// See the comments in verify_field_instructions() for // See the comments in verify_field_instructions() for
// the rationale behind this. // 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); klassOop ref_class = load_class(ref_class_name, CHECK);
if (is_protected_access( 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 // It's protected access, check if stack object is
// assignable to current class. // assignable to current class.
bool is_assignable = current_type().is_assignable_from( 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 (!is_assignable) {
if (ref_class_type.name() == vmSymbols::java_lang_Object() if (ref_class_type.name() == vmSymbols::java_lang_Object()
&& stack_object_type.is_array() && stack_object_type.is_array()
&& method_name() == vmSymbols::clone_name()) { && method_name == vmSymbols::clone_name()) {
// Special case: arrays pretend to implement public Object // Special case: arrays pretend to implement public Object
// clone(). // clone().
} else { } else {
@ -2105,7 +2108,7 @@ void ClassVerifier::verify_invoke_instructions(
} }
// Push the result type. // Push the result type.
if (sig_stream.type() != T_VOID) { if (sig_stream.type() != T_VOID) {
if (method_name() == vmSymbols::object_initializer_name()) { if (method_name == vmSymbols::object_initializer_name()) {
// <init> method must have a void return type // <init> method must have a void return type
verify_error(bci, "Return type must be void in <init> method"); verify_error(bci, "Return type must be void in <init> method");
return; return;
@ -2130,7 +2133,7 @@ VerificationType ClassVerifier::get_newarray_type(
} }
// from_bt[index] contains the array signature which has a length of 2 // 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())); from_bt[index], 2, CHECK_(VerificationType::bogus_type()));
return VerificationType::reference_type(sig); return VerificationType::reference_type(sig);
} }
@ -2143,7 +2146,6 @@ void ClassVerifier::verify_anewarray(
VerificationType component_type = VerificationType component_type =
cp_index_to_type(index, cp, CHECK_VERIFY(this)); cp_index_to_type(index, cp, CHECK_VERIFY(this));
ResourceMark rm(THREAD);
int length; int length;
char* arr_sig_str; char* arr_sig_str;
if (component_type.is_array()) { // it's an array if (component_type.is_array()) { // it's an array
@ -2163,7 +2165,7 @@ void ClassVerifier::verify_anewarray(
strncpy(&arr_sig_str[2], component_name, length - 2); strncpy(&arr_sig_str[2], component_name, length - 2);
arr_sig_str[length - 1] = ';'; 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)); arr_sig_str, length, CHECK_VERIFY(this));
VerificationType new_array_type = VerificationType::reference_type(arr_sig); VerificationType new_array_type = VerificationType::reference_type(arr_sig);
current_frame->push_stack(new_array_type, CHECK_VERIFY(this)); current_frame->push_stack(new_array_type, CHECK_VERIFY(this));
@ -2256,9 +2258,25 @@ void ClassVerifier::verify_return_value(
verify_error(bci, "Method expects a return value"); verify_error(bci, "Method expects a return value");
return; 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) { if (!match) {
verify_error(bci, "Bad return type"); verify_error(bci, "Bad return type");
return; 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;
}

View File

@ -59,7 +59,7 @@ class Verifier : AllStatic {
private: private:
static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class); 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); instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
}; };
@ -69,8 +69,8 @@ class StackMapTable;
// Summary of verifier's memory usage: // Summary of verifier's memory usage:
// StackMapTable is stack allocated. // StackMapTable is stack allocated.
// StackMapFrame are resource allocated. There is one ResourceMark // StackMapFrame are resource allocated. There is only one ResourceMark
// for each method. // for each class verification, which is created at the top level.
// There is one mutable StackMapFrame (current_frame) which is updated // There is one mutable StackMapFrame (current_frame) which is updated
// by abstract bytecode interpretation. frame_in_exception_handler() returns // by abstract bytecode interpretation. frame_in_exception_handler() returns
// a frame that has a mutable one-item stack (ready for pushing the // a frame that has a mutable one-item stack (ready for pushing the
@ -80,8 +80,6 @@ class StackMapTable;
// locals/stack arrays in StackMapFrame are resource allocated. // locals/stack arrays in StackMapFrame are resource allocated.
// locals/stack arrays can be shared between StackMapFrame's, except // locals/stack arrays can be shared between StackMapFrame's, except
// the mutable StackMapFrame (current_frame). // 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 // These macros are used similarly to CHECK macros but also check
// the status of the verifier and return if that has an error. // the status of the verifier and return if that has an error.
@ -94,9 +92,10 @@ class StackMapTable;
class ClassVerifier : public StackObj { class ClassVerifier : public StackObj {
private: private:
Thread* _thread; Thread* _thread;
symbolHandle _exception_type; Symbol* _exception_type;
char* _message; char* _message;
size_t _message_buffer_len; size_t _message_buffer_len;
GrowableArray<Symbol*>* _symbols; // keep a list of symbols created
void verify_method(methodHandle method, TRAPS); void verify_method(methodHandle method, TRAPS);
char* generate_code_data(methodHandle m, u4 code_length, TRAPS); char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
@ -110,7 +109,7 @@ class ClassVerifier : public StackObj {
bool is_protected_access( bool is_protected_access(
instanceKlassHandle this_class, klassOop target_class, 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_index(constantPoolHandle cp, int index, TRAPS);
void verify_cp_type( void verify_cp_type(
@ -165,7 +164,7 @@ class ClassVerifier : public StackObj {
void verify_astore(u2 index, StackMapFrame* current_frame, TRAPS); void verify_astore(u2 index, StackMapFrame* current_frame, TRAPS);
void verify_iinc (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; VerificationType object_type() const;
@ -206,8 +205,8 @@ class ClassVerifier : public StackObj {
void verify_class(TRAPS); void verify_class(TRAPS);
// Return status modes // Return status modes
symbolHandle result() const { return _exception_type; } Symbol* result() const { return _exception_type; }
bool has_error() const { return !(result().is_null()); } bool has_error() const { return result() != NULL; }
// Called when verify or class format errors are encountered. // Called when verify or class format errors are encountered.
// May throw an exception based upon the mode. // May throw an exception based upon the mode.
@ -216,16 +215,22 @@ class ClassVerifier : public StackObj {
void class_format_error(const char* fmt, ...); void class_format_error(const char* fmt, ...);
void format_error_message(const char* fmt, int offset, va_list args); 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( int change_sig_to_verificationType(
SignatureStream* sig_type, VerificationType* inference_type, TRAPS); SignatureStream* sig_type, VerificationType* inference_type, TRAPS);
VerificationType cp_index_to_type(int index, constantPoolHandle cp, TRAPS) { VerificationType cp_index_to_type(int index, constantPoolHandle cp, TRAPS) {
return VerificationType::reference_type( return VerificationType::reference_type(cp->klass_name_at(index));
symbolHandle(THREAD, 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 static bool _verify_verbose; // for debugging
}; };
@ -236,9 +241,14 @@ inline int ClassVerifier::change_sig_to_verificationType(
case T_OBJECT: case T_OBJECT:
case T_ARRAY: 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 = *inference_type =
VerificationType::reference_type(symbolHandle(THREAD, name)); VerificationType::reference_type(name_copy);
return 1; return 1;
} }
case T_LONG: case T_LONG:

View File

@ -30,11 +30,11 @@
#include "utilities/xmlstream.hpp" #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; if (a == b) return 0;
// follow the natural address order: // follow the natural address order:
return (address)a > (address)b ? +1 : -1; return (address)a > (address)b ? +1 : -1;
@ -43,8 +43,8 @@ inline int compare_symbol(symbolOop a, symbolOop b) {
static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT]; static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT];
extern "C" { extern "C" {
static int compare_vmsymbol_sid(const void* void_a, const void* void_b) { static int compare_vmsymbol_sid(const void* void_a, const void* void_b) {
symbolOop a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a)); Symbol* a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a));
symbolOop b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b)); Symbol* b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b));
return compare_symbol(a, b); return compare_symbol(a, b);
} }
} }
@ -79,7 +79,7 @@ void vmSymbols::initialize(TRAPS) {
if (!UseSharedSpaces) { if (!UseSharedSpaces) {
const char* string = &vm_symbol_bodies[0]; const char* string = &vm_symbol_bodies[0];
for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { 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; _symbols[index] = sym;
string += strlen(string); // skip string body string += strlen(string); // skip string body
string += 1; // skip trailing null string += 1; // skip trailing null
@ -100,7 +100,7 @@ void vmSymbols::initialize(TRAPS) {
#ifdef ASSERT #ifdef ASSERT
// Check for duplicates: // Check for duplicates:
for (int i1 = (int)FIRST_SID; i1 < (int)SID_LIMIT; i1++) { 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++) { for (int i2 = (int)FIRST_SID; i2 < i1; i2++) {
if (symbol_at((SID)i2) == sym) { if (symbol_at((SID)i2) == sym) {
tty->print("*** Duplicate VM symbol SIDs %s(%d) and %s(%d): \"", tty->print("*** Duplicate VM symbol SIDs %s(%d) and %s(%d): \"",
@ -128,16 +128,16 @@ void vmSymbols::initialize(TRAPS) {
// Spot-check correspondence between strings, symbols, and enums: // Spot-check correspondence between strings, symbols, and enums:
assert(_symbols[NO_SID] == NULL, "must be"); assert(_symbols[NO_SID] == NULL, "must be");
const char* str = "java/lang/Object"; const char* str = "java/lang/Object";
symbolOop sym = oopFactory::new_symbol(str, CHECK); TempNewSymbol jlo = SymbolTable::new_symbol(str, CHECK);
assert(strcmp(str, (char*)sym->base()) == 0, ""); assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, "");
assert(sym == java_lang_Object(), ""); assert(jlo == java_lang_Object(), "");
SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object); SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object);
assert(find_sid(sym) == sid, ""); assert(find_sid(jlo) == sid, "");
assert(symbol_at(sid) == sym, ""); assert(symbol_at(sid) == jlo, "");
// Make sure find_sid produces the right answer in each case. // Make sure find_sid produces the right answer in each case.
for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { 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); sid = find_sid(sym);
assert(sid == (SID)index, "symbol index works"); assert(sid == (SID)index, "symbol index works");
// Note: If there are duplicates, this assert will fail. // Note: If there are duplicates, this assert will fail.
@ -147,8 +147,8 @@ void vmSymbols::initialize(TRAPS) {
// The string "format" happens (at the moment) not to be a vmSymbol, // The string "format" happens (at the moment) not to be a vmSymbol,
// though it is a method name in java.lang.String. // though it is a method name in java.lang.String.
str = "format"; str = "format";
sym = oopFactory::new_symbol(str, CHECK); TempNewSymbol fmt = SymbolTable::new_symbol(str, CHECK);
sid = find_sid(sym); sid = find_sid(fmt);
assert(sid == NO_SID, "symbol index works (negative test)"); assert(sid == NO_SID, "symbol index works (negative test)");
} }
#endif #endif
@ -172,22 +172,23 @@ const char* vmSymbols::name_for(vmSymbols::SID sid) {
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++) { 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++) { for (int i = 0; i < T_VOID+1; i++) {
if (_type_signatures[i] != NULL) { f->do_symbol(&_type_signatures[i]);
assert(i >= T_BOOLEAN, "checking");
f->do_oop((oop*)&_type_signatures[i]);
} else if (do_all) {
f->do_oop((oop*)&_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"); assert(s != NULL, "checking");
for (int i = T_BOOLEAN; i < T_VOID+1; i++) { for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
if (s == _type_signatures[i]) { if (s == _type_signatures[i]) {
@ -205,7 +206,7 @@ static int find_sid_calls, find_sid_probes;
// (Typical counts are calls=7000 and probes=17000.) // (Typical counts are calls=7000 and probes=17000.)
#endif #endif
vmSymbols::SID vmSymbols::find_sid(symbolOop symbol) { vmSymbols::SID vmSymbols::find_sid(Symbol* symbol) {
// Handle the majority of misses by a bounds check. // Handle the majority of misses by a bounds check.
// Then, use a binary search over the index. // Then, use a binary search over the index.
// Expected trip count is less than log2_SID_LIMIT, about eight. // Expected trip count is less than log2_SID_LIMIT, about eight.
@ -260,7 +261,7 @@ vmSymbols::SID vmSymbols::find_sid(symbolOop symbol) {
// (We have already proven that there are no duplicates in the list.) // (We have already proven that there are no duplicates in the list.)
SID sid2 = NO_SID; SID sid2 = NO_SID;
for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { 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) { if (sym2 == symbol) {
sid2 = (SID)index; sid2 = (SID)index;
break; break;
@ -319,9 +320,9 @@ vmIntrinsics::ID vmIntrinsics::for_raw_conversion(BasicType src, BasicType dest)
methodOop vmIntrinsics::method_for(vmIntrinsics::ID id) { methodOop vmIntrinsics::method_for(vmIntrinsics::ID id) {
if (id == _none) return NULL; if (id == _none) return NULL;
symbolOop cname = vmSymbols::symbol_at(class_for(id)); Symbol* cname = vmSymbols::symbol_at(class_for(id));
symbolOop mname = vmSymbols::symbol_at(name_for(id)); Symbol* mname = vmSymbols::symbol_at(name_for(id));
symbolOop msig = vmSymbols::symbol_at(signature_for(id)); Symbol* msig = vmSymbols::symbol_at(signature_for(id));
if (cname == NULL || mname == NULL || msig == NULL) return NULL; if (cname == NULL || mname == NULL || msig == NULL) return NULL;
klassOop k = SystemDictionary::find_well_known_klass(cname); klassOop k = SystemDictionary::find_well_known_klass(cname);
if (k == NULL) return NULL; if (k == NULL) return NULL;
@ -490,17 +491,17 @@ vmIntrinsics::Flags vmIntrinsics::flags_for(vmIntrinsics::ID id) {
#ifndef PRODUCT #ifndef PRODUCT
// verify_method performs an extra check on a matched intrinsic method // 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 && return (m->name() == n &&
m->signature() == s); 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) \ #define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \
{ symbolOop k = vmSymbols::klassname(); \ { Symbol* k = vmSymbols::klassname(); \
if (mk == k) { \ if (mk == k) { \
symbolOop n = vmSymbols::namepart(); \ Symbol* n = vmSymbols::namepart(); \
symbolOop s = vmSymbols::sigpart(); \ Symbol* s = vmSymbols::sigpart(); \
if (match_method(m, n, s)) \ if (match_method(m, n, s)) \
return vmIntrinsics::id; \ return vmIntrinsics::id; \
} } } }
@ -511,7 +512,7 @@ static vmIntrinsics::ID match_method_with_klass(methodOop m, symbolOop mk) {
} }
void vmIntrinsics::verify_method(ID actual_id, methodOop m) { 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); ID declared_id = match_method_with_klass(m, mk);
if (declared_id == actual_id) return; // success if (declared_id == actual_id) return; // success

Some files were not shown because too many files have changed in this diff Show More