6990754: Use native memory and reference counting to implement SymbolTable
Move symbols from permgen into C heap and reference count them Reviewed-by: never, acorn, jmasa, stefank
This commit is contained in:
parent
950858350d
commit
7b4f8073f0
@ -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()) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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() {
|
||||||
|
@ -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 :-(
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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()) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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';
|
||||||
|
@ -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;
|
||||||
|
@ -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; \
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
|
@ -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) {
|
||||||
|
@ -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) == '[' ||
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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; }
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
@ -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"
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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; }
|
||||||
|
@ -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() {
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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(); )
|
||||||
|
@ -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) {
|
||||||
|
@ -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");
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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) \
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -25,17 +25,15 @@
|
|||||||
#ifndef SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
|
#ifndef SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
|
||||||
#define SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
|
#define SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
|
||||||
|
|
||||||
#include "oops/symbolOop.hpp"
|
#include "oops/symbol.hpp"
|
||||||
|
#include "memory/iterator.hpp"
|
||||||
|
|
||||||
// The classes vmSymbols and vmSymbolHandles are a name spaces for fast lookup of
|
// The class vmSymbols is a name space for fast lookup of
|
||||||
// symbols commonly used in the VM. The first class return a symbolOop, while the
|
// symbols commonly used in the VM.
|
||||||
// second class returns a SymbolHandle. The underlying data structure is shared
|
|
||||||
// between the two classes.
|
|
||||||
//
|
//
|
||||||
// Sample usage:
|
// Sample usage:
|
||||||
//
|
//
|
||||||
// symbolOop obj = vmSymbols::java_lang_Object()();
|
// Symbol* obj = vmSymbols::java_lang_Object();
|
||||||
// SymbolHandle handle = vmSymbolHandles::java_lang_Object();
|
|
||||||
|
|
||||||
|
|
||||||
// Useful sub-macros exported by this header file:
|
// Useful sub-macros exported by this header file:
|
||||||
@ -459,7 +457,7 @@
|
|||||||
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, do_alias) \
|
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, do_alias) \
|
||||||
\
|
\
|
||||||
/* returned by the C1 compiler in case there's not enough memory to allocate a new symbol*/ \
|
/* returned by the C1 compiler in case there's not enough memory to allocate a new symbol*/ \
|
||||||
template(dummy_symbol_oop, "illegal symbol") \
|
template(dummy_symbol, "illegal symbol") \
|
||||||
\
|
\
|
||||||
/* used by ClassFormatError when class name is not known yet */ \
|
/* used by ClassFormatError when class name is not known yet */ \
|
||||||
template(unknown_class_name, "<Unknown>") \
|
template(unknown_class_name, "<Unknown>") \
|
||||||
@ -938,10 +936,9 @@
|
|||||||
// Class vmSymbols
|
// Class vmSymbols
|
||||||
|
|
||||||
class vmSymbols: AllStatic {
|
class vmSymbols: AllStatic {
|
||||||
friend class vmSymbolHandles;
|
|
||||||
friend class vmIntrinsics;
|
friend class vmIntrinsics;
|
||||||
public:
|
public:
|
||||||
// enum for figuring positions and size of array holding symbolOops
|
// enum for figuring positions and size of array holding Symbol*s
|
||||||
enum SID {
|
enum SID {
|
||||||
NO_SID = 0,
|
NO_SID = 0,
|
||||||
|
|
||||||
@ -963,39 +960,42 @@ class vmSymbols: AllStatic {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// The symbol array
|
// The symbol array
|
||||||
static symbolOop _symbols[];
|
static Symbol* _symbols[];
|
||||||
|
|
||||||
// Field signatures indexed by BasicType.
|
// Field signatures indexed by BasicType.
|
||||||
static symbolOop _type_signatures[T_VOID+1];
|
static Symbol* _type_signatures[T_VOID+1];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Initialization
|
// Initialization
|
||||||
static void initialize(TRAPS);
|
static void initialize(TRAPS);
|
||||||
// Accessing
|
// Accessing
|
||||||
#define VM_SYMBOL_DECLARE(name, ignore) \
|
#define VM_SYMBOL_DECLARE(name, ignore) \
|
||||||
static symbolOop name() { return _symbols[VM_SYMBOL_ENUM_NAME(name)]; }
|
static Symbol* name() { \
|
||||||
|
return _symbols[VM_SYMBOL_ENUM_NAME(name)]; \
|
||||||
|
}
|
||||||
VM_SYMBOLS_DO(VM_SYMBOL_DECLARE, VM_SYMBOL_DECLARE)
|
VM_SYMBOLS_DO(VM_SYMBOL_DECLARE, VM_SYMBOL_DECLARE)
|
||||||
#undef VM_SYMBOL_DECLARE
|
#undef VM_SYMBOL_DECLARE
|
||||||
|
|
||||||
// GC support
|
// Sharing support
|
||||||
static void oops_do(OopClosure* f, bool do_all = false);
|
static void symbols_do(SymbolClosure* f);
|
||||||
|
static void serialize(SerializeOopClosure* soc);
|
||||||
|
|
||||||
static symbolOop type_signature(BasicType t) {
|
static Symbol* type_signature(BasicType t) {
|
||||||
assert((uint)t < T_VOID+1, "range check");
|
assert((uint)t < T_VOID+1, "range check");
|
||||||
assert(_type_signatures[t] != NULL, "domain check");
|
assert(_type_signatures[t] != NULL, "domain check");
|
||||||
return _type_signatures[t];
|
return _type_signatures[t];
|
||||||
}
|
}
|
||||||
// inverse of type_signature; returns T_OBJECT if s is not recognized
|
// inverse of type_signature; returns T_OBJECT if s is not recognized
|
||||||
static BasicType signature_type(symbolOop s);
|
static BasicType signature_type(Symbol* s);
|
||||||
|
|
||||||
static symbolOop symbol_at(SID id) {
|
static Symbol* symbol_at(SID id) {
|
||||||
assert(id >= FIRST_SID && id < SID_LIMIT, "oob");
|
assert(id >= FIRST_SID && id < SID_LIMIT, "oob");
|
||||||
assert(_symbols[id] != NULL, "init");
|
assert(_symbols[id] != NULL, "init");
|
||||||
return _symbols[id];
|
return _symbols[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns symbol's SID if one is assigned, else NO_SID.
|
// Returns symbol's SID if one is assigned, else NO_SID.
|
||||||
static SID find_sid(symbolOop symbol);
|
static SID find_sid(Symbol* symbol);
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
// No need for this in the product:
|
// No need for this in the product:
|
||||||
@ -1003,34 +1003,6 @@ class vmSymbols: AllStatic {
|
|||||||
#endif //PRODUCT
|
#endif //PRODUCT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Class vmSymbolHandles
|
|
||||||
|
|
||||||
class vmSymbolHandles: AllStatic {
|
|
||||||
friend class vmIntrinsics;
|
|
||||||
friend class ciObjectFactory;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Accessing
|
|
||||||
#define VM_SYMBOL_HANDLE_DECLARE(name, ignore) \
|
|
||||||
static symbolHandle name() { return symbol_handle_at(vmSymbols::VM_SYMBOL_ENUM_NAME(name)); }
|
|
||||||
VM_SYMBOLS_DO(VM_SYMBOL_HANDLE_DECLARE, VM_SYMBOL_HANDLE_DECLARE)
|
|
||||||
#undef VM_SYMBOL_HANDLE_DECLARE
|
|
||||||
|
|
||||||
static symbolHandle symbol_handle_at(vmSymbols::SID id) {
|
|
||||||
return symbolHandle(&vmSymbols::_symbols[(int)id], false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static symbolHandle type_signature(BasicType t) {
|
|
||||||
assert(vmSymbols::type_signature(t) != NULL, "domain check");
|
|
||||||
return symbolHandle(&vmSymbols::_type_signatures[t], false);
|
|
||||||
}
|
|
||||||
// inverse of type_signature; returns T_OBJECT if s is not recognized
|
|
||||||
static BasicType signature_type(symbolHandle s) {
|
|
||||||
return vmSymbols::signature_type(s());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// VM Intrinsic ID's uniquely identify some very special methods
|
// VM Intrinsic ID's uniquely identify some very special methods
|
||||||
class vmIntrinsics: AllStatic {
|
class vmIntrinsics: AllStatic {
|
||||||
friend class vmSymbols;
|
friend class vmSymbols;
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "memory/oopFactory.hpp"
|
#include "memory/oopFactory.hpp"
|
||||||
#include "oops/methodOop.hpp"
|
#include "oops/methodOop.hpp"
|
||||||
#include "oops/oop.inline.hpp"
|
#include "oops/oop.inline.hpp"
|
||||||
#include "oops/symbolOop.hpp"
|
#include "oops/symbol.hpp"
|
||||||
#include "runtime/icache.hpp"
|
#include "runtime/icache.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
|
@ -628,8 +628,8 @@ class ClassHierarchyWalker {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// optional method descriptor to check for:
|
// optional method descriptor to check for:
|
||||||
symbolOop _name;
|
Symbol* _name;
|
||||||
symbolOop _signature;
|
Symbol* _signature;
|
||||||
|
|
||||||
// special classes which are not allowed to be witnesses:
|
// special classes which are not allowed to be witnesses:
|
||||||
klassOop _participants[PARTICIPANT_LIMIT+1];
|
klassOop _participants[PARTICIPANT_LIMIT+1];
|
||||||
|
@ -57,9 +57,9 @@ HS_DTRACE_PROBE_DECL6(hotspot, compiled__method__unload,
|
|||||||
{ \
|
{ \
|
||||||
methodOop m = (method); \
|
methodOop m = (method); \
|
||||||
if (m != NULL) { \
|
if (m != NULL) { \
|
||||||
symbolOop klass_name = m->klass_name(); \
|
Symbol* klass_name = m->klass_name(); \
|
||||||
symbolOop name = m->name(); \
|
Symbol* name = m->name(); \
|
||||||
symbolOop signature = m->signature(); \
|
Symbol* signature = m->signature(); \
|
||||||
HS_DTRACE_PROBE6(hotspot, compiled__method__unload, \
|
HS_DTRACE_PROBE6(hotspot, compiled__method__unload, \
|
||||||
klass_name->bytes(), klass_name->utf8_length(), \
|
klass_name->bytes(), klass_name->utf8_length(), \
|
||||||
name->bytes(), name->utf8_length(), \
|
name->bytes(), name->utf8_length(), \
|
||||||
@ -1865,7 +1865,7 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map
|
|||||||
SimpleScopeDesc ssd(this, fr.pc());
|
SimpleScopeDesc ssd(this, fr.pc());
|
||||||
Bytecode_invoke call(ssd.method(), ssd.bci());
|
Bytecode_invoke call(ssd.method(), ssd.bci());
|
||||||
bool has_receiver = call.has_receiver();
|
bool has_receiver = call.has_receiver();
|
||||||
symbolOop signature = call.signature();
|
Symbol* signature = call.signature();
|
||||||
fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
|
fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
|
||||||
}
|
}
|
||||||
#endif // !SHARK
|
#endif // !SHARK
|
||||||
@ -2636,7 +2636,7 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) {
|
|||||||
} else {
|
} else {
|
||||||
bool did_name = false;
|
bool did_name = false;
|
||||||
if (!at_this && ss.is_object()) {
|
if (!at_this && ss.is_object()) {
|
||||||
symbolOop name = ss.as_symbol_or_null();
|
Symbol* name = ss.as_symbol_or_null();
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
name->print_value_on(stream);
|
name->print_value_on(stream);
|
||||||
did_name = true;
|
did_name = true;
|
||||||
|
@ -66,9 +66,9 @@ HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end,
|
|||||||
#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method) \
|
#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method) \
|
||||||
{ \
|
{ \
|
||||||
char* comp_name = (char*)(compiler)->name(); \
|
char* comp_name = (char*)(compiler)->name(); \
|
||||||
symbolOop klass_name = (method)->klass_name(); \
|
Symbol* klass_name = (method)->klass_name(); \
|
||||||
symbolOop name = (method)->name(); \
|
Symbol* name = (method)->name(); \
|
||||||
symbolOop signature = (method)->signature(); \
|
Symbol* signature = (method)->signature(); \
|
||||||
HS_DTRACE_PROBE8(hotspot, method__compile__begin, \
|
HS_DTRACE_PROBE8(hotspot, method__compile__begin, \
|
||||||
comp_name, strlen(comp_name), \
|
comp_name, strlen(comp_name), \
|
||||||
klass_name->bytes(), klass_name->utf8_length(), \
|
klass_name->bytes(), klass_name->utf8_length(), \
|
||||||
@ -79,9 +79,9 @@ HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end,
|
|||||||
#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success) \
|
#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success) \
|
||||||
{ \
|
{ \
|
||||||
char* comp_name = (char*)(compiler)->name(); \
|
char* comp_name = (char*)(compiler)->name(); \
|
||||||
symbolOop klass_name = (method)->klass_name(); \
|
Symbol* klass_name = (method)->klass_name(); \
|
||||||
symbolOop name = (method)->name(); \
|
Symbol* name = (method)->name(); \
|
||||||
symbolOop signature = (method)->signature(); \
|
Symbol* signature = (method)->signature(); \
|
||||||
HS_DTRACE_PROBE9(hotspot, method__compile__end, \
|
HS_DTRACE_PROBE9(hotspot, method__compile__end, \
|
||||||
comp_name, strlen(comp_name), \
|
comp_name, strlen(comp_name), \
|
||||||
klass_name->bytes(), klass_name->utf8_length(), \
|
klass_name->bytes(), klass_name->utf8_length(), \
|
||||||
@ -689,7 +689,7 @@ CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQue
|
|||||||
CompilerThread* compiler_thread = NULL;
|
CompilerThread* compiler_thread = NULL;
|
||||||
|
|
||||||
klassOop k =
|
klassOop k =
|
||||||
SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(),
|
SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
|
||||||
true, CHECK_0);
|
true, CHECK_0);
|
||||||
instanceKlassHandle klass (THREAD, k);
|
instanceKlassHandle klass (THREAD, k);
|
||||||
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0);
|
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0);
|
||||||
@ -700,8 +700,8 @@ CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQue
|
|||||||
JavaValue result(T_VOID);
|
JavaValue result(T_VOID);
|
||||||
JavaCalls::call_special(&result, thread_oop,
|
JavaCalls::call_special(&result, thread_oop,
|
||||||
klass,
|
klass,
|
||||||
vmSymbolHandles::object_initializer_name(),
|
vmSymbols::object_initializer_name(),
|
||||||
vmSymbolHandles::threadgroup_string_void_signature(),
|
vmSymbols::threadgroup_string_void_signature(),
|
||||||
thread_group,
|
thread_group,
|
||||||
string,
|
string,
|
||||||
CHECK_0);
|
CHECK_0);
|
||||||
|
@ -63,7 +63,7 @@ class CompileLog : public xmlStream {
|
|||||||
stringStream* context() { return &_context; }
|
stringStream* context() { return &_context; }
|
||||||
|
|
||||||
void name(ciSymbol* s); // name='s'
|
void name(ciSymbol* s); // name='s'
|
||||||
void name(symbolHandle s) { xmlStream::name(s); }
|
void name(Symbol* s) { xmlStream::name(s); }
|
||||||
|
|
||||||
// Output an object description, return obj->ident().
|
// Output an object description, return obj->ident().
|
||||||
int identify(ciObject* obj);
|
int identify(ciObject* obj);
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "oops/klass.hpp"
|
#include "oops/klass.hpp"
|
||||||
#include "oops/methodOop.hpp"
|
#include "oops/methodOop.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 "runtime/jniHandles.hpp"
|
#include "runtime/jniHandles.hpp"
|
||||||
|
|
||||||
@ -46,33 +46,33 @@ class MethodMatcher : public CHeapObj {
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
jobject _class_name;
|
Symbol* _class_name;
|
||||||
|
Symbol* _method_name;
|
||||||
|
Symbol* _signature;
|
||||||
Mode _class_mode;
|
Mode _class_mode;
|
||||||
jobject _method_name;
|
|
||||||
Mode _method_mode;
|
Mode _method_mode;
|
||||||
jobject _signature;
|
|
||||||
MethodMatcher* _next;
|
MethodMatcher* _next;
|
||||||
|
|
||||||
static bool match(symbolHandle candidate, symbolHandle match, Mode match_mode);
|
static bool match(Symbol* candidate, Symbol* match, Mode match_mode);
|
||||||
|
|
||||||
symbolHandle class_name() const { return (symbolOop)JNIHandles::resolve_non_null(_class_name); }
|
Symbol* class_name() const { return _class_name; }
|
||||||
symbolHandle method_name() const { return (symbolOop)JNIHandles::resolve_non_null(_method_name); }
|
Symbol* method_name() const { return _method_name; }
|
||||||
symbolHandle signature() const { return (symbolOop)JNIHandles::resolve(_signature); }
|
Symbol* signature() const { return _signature; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MethodMatcher(symbolHandle class_name, Mode class_mode,
|
MethodMatcher(Symbol* class_name, Mode class_mode,
|
||||||
symbolHandle method_name, Mode method_mode,
|
Symbol* method_name, Mode method_mode,
|
||||||
symbolHandle signature, MethodMatcher* next);
|
Symbol* signature, MethodMatcher* next);
|
||||||
MethodMatcher(symbolHandle class_name, symbolHandle method_name, MethodMatcher* next);
|
MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next);
|
||||||
|
|
||||||
// utility method
|
// utility method
|
||||||
MethodMatcher* find(methodHandle method) {
|
MethodMatcher* find(methodHandle method) {
|
||||||
symbolHandle class_name = Klass::cast(method->method_holder())->name();
|
Symbol* class_name = Klass::cast(method->method_holder())->name();
|
||||||
symbolHandle method_name = method->name();
|
Symbol* method_name = method->name();
|
||||||
for (MethodMatcher* current = this; current != NULL; current = current->_next) {
|
for (MethodMatcher* current = this; current != NULL; current = current->_next) {
|
||||||
if (match(class_name, current->class_name(), current->_class_mode) &&
|
if (match(class_name, current->class_name(), current->_class_mode) &&
|
||||||
match(method_name, current->method_name(), current->_method_mode) &&
|
match(method_name, current->method_name(), current->_method_mode) &&
|
||||||
(current->signature().is_null() || current->signature()() == method->signature())) {
|
(current->signature() == NULL || current->signature() == method->signature())) {
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,14 +85,14 @@ class MethodMatcher : public CHeapObj {
|
|||||||
|
|
||||||
MethodMatcher* next() const { return _next; }
|
MethodMatcher* next() const { return _next; }
|
||||||
|
|
||||||
static void print_symbol(symbolHandle h, Mode mode) {
|
static void print_symbol(Symbol* h, Mode mode) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
if (mode == Suffix || mode == Substring || mode == Any) {
|
if (mode == Suffix || mode == Substring || mode == Any) {
|
||||||
tty->print("*");
|
tty->print("*");
|
||||||
}
|
}
|
||||||
if (mode != Any) {
|
if (mode != Any) {
|
||||||
h()->print_symbol_on(tty);
|
h->print_symbol_on(tty);
|
||||||
}
|
}
|
||||||
if (mode == Prefix || mode == Substring) {
|
if (mode == Prefix || mode == Substring) {
|
||||||
tty->print("*");
|
tty->print("*");
|
||||||
@ -103,7 +103,7 @@ class MethodMatcher : public CHeapObj {
|
|||||||
print_symbol(class_name(), _class_mode);
|
print_symbol(class_name(), _class_mode);
|
||||||
tty->print(".");
|
tty->print(".");
|
||||||
print_symbol(method_name(), _method_mode);
|
print_symbol(method_name(), _method_mode);
|
||||||
if (!signature().is_null()) {
|
if (signature() != NULL) {
|
||||||
tty->print(" ");
|
tty->print(" ");
|
||||||
signature()->print_symbol_on(tty);
|
signature()->print_symbol_on(tty);
|
||||||
}
|
}
|
||||||
@ -115,9 +115,9 @@ class MethodMatcher : public CHeapObj {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MethodMatcher::MethodMatcher(symbolHandle class_name, symbolHandle method_name, MethodMatcher* next) {
|
MethodMatcher::MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next) {
|
||||||
_class_name = JNIHandles::make_global(class_name);
|
_class_name = class_name;
|
||||||
_method_name = JNIHandles::make_global(method_name);
|
_method_name = method_name;
|
||||||
_next = next;
|
_next = next;
|
||||||
_class_mode = MethodMatcher::Exact;
|
_class_mode = MethodMatcher::Exact;
|
||||||
_method_mode = MethodMatcher::Exact;
|
_method_mode = MethodMatcher::Exact;
|
||||||
@ -125,24 +125,24 @@ MethodMatcher::MethodMatcher(symbolHandle class_name, symbolHandle method_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MethodMatcher::MethodMatcher(symbolHandle class_name, Mode class_mode,
|
MethodMatcher::MethodMatcher(Symbol* class_name, Mode class_mode,
|
||||||
symbolHandle method_name, Mode method_mode,
|
Symbol* method_name, Mode method_mode,
|
||||||
symbolHandle signature, MethodMatcher* next):
|
Symbol* signature, MethodMatcher* next):
|
||||||
_class_mode(class_mode)
|
_class_mode(class_mode)
|
||||||
, _method_mode(method_mode)
|
, _method_mode(method_mode)
|
||||||
, _next(next)
|
, _next(next)
|
||||||
, _class_name(JNIHandles::make_global(class_name()))
|
, _class_name(class_name)
|
||||||
, _method_name(JNIHandles::make_global(method_name()))
|
, _method_name(method_name)
|
||||||
, _signature(JNIHandles::make_global(signature())) {
|
, _signature(signature) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MethodMatcher::match(symbolHandle candidate, symbolHandle match, Mode match_mode) {
|
bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) {
|
||||||
if (match_mode == Any) {
|
if (match_mode == Any) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match_mode == Exact) {
|
if (match_mode == Exact) {
|
||||||
return candidate() == match();
|
return candidate == match;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
@ -171,9 +171,9 @@ bool MethodMatcher::match(symbolHandle candidate, symbolHandle match, Mode match
|
|||||||
class MethodOptionMatcher: public MethodMatcher {
|
class MethodOptionMatcher: public MethodMatcher {
|
||||||
const char * option;
|
const char * option;
|
||||||
public:
|
public:
|
||||||
MethodOptionMatcher(symbolHandle class_name, Mode class_mode,
|
MethodOptionMatcher(Symbol* class_name, Mode class_mode,
|
||||||
symbolHandle method_name, Mode method_mode,
|
Symbol* method_name, Mode method_mode,
|
||||||
symbolHandle signature, const char * opt, MethodMatcher* next):
|
Symbol* signature, const char * opt, MethodMatcher* next):
|
||||||
MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) {
|
MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) {
|
||||||
option = opt;
|
option = opt;
|
||||||
}
|
}
|
||||||
@ -256,9 +256,9 @@ static bool check_predicate(OracleCommand command, methodHandle method) {
|
|||||||
|
|
||||||
|
|
||||||
static MethodMatcher* add_predicate(OracleCommand command,
|
static MethodMatcher* add_predicate(OracleCommand command,
|
||||||
symbolHandle class_name, MethodMatcher::Mode c_mode,
|
Symbol* class_name, MethodMatcher::Mode c_mode,
|
||||||
symbolHandle method_name, MethodMatcher::Mode m_mode,
|
Symbol* method_name, MethodMatcher::Mode m_mode,
|
||||||
symbolHandle signature) {
|
Symbol* signature) {
|
||||||
assert(command != OptionCommand, "must use add_option_string");
|
assert(command != OptionCommand, "must use add_option_string");
|
||||||
if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL)
|
if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL)
|
||||||
tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged.");
|
tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged.");
|
||||||
@ -268,9 +268,9 @@ static MethodMatcher* add_predicate(OracleCommand command,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static MethodMatcher* add_option_string(symbolHandle class_name, MethodMatcher::Mode c_mode,
|
static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode,
|
||||||
symbolHandle method_name, MethodMatcher::Mode m_mode,
|
Symbol* method_name, MethodMatcher::Mode m_mode,
|
||||||
symbolHandle signature,
|
Symbol* signature,
|
||||||
const char* option) {
|
const char* option) {
|
||||||
lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode,
|
lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode,
|
||||||
signature, option, lists[OptionCommand]);
|
signature, option, lists[OptionCommand]);
|
||||||
@ -497,9 +497,9 @@ void CompilerOracle::parse_from_line(char* line) {
|
|||||||
|
|
||||||
if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) {
|
if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
symbolHandle c_name = oopFactory::new_symbol_handle(class_name, CHECK);
|
Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK);
|
||||||
symbolHandle m_name = oopFactory::new_symbol_handle(method_name, CHECK);
|
Symbol* m_name = SymbolTable::new_symbol(method_name, CHECK);
|
||||||
symbolHandle signature;
|
Symbol* signature = NULL;
|
||||||
|
|
||||||
line += bytes_read;
|
line += bytes_read;
|
||||||
// there might be a signature following the method.
|
// there might be a signature following the method.
|
||||||
@ -507,7 +507,7 @@ void CompilerOracle::parse_from_line(char* line) {
|
|||||||
if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
|
if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
|
||||||
sig[0] = '(';
|
sig[0] = '(';
|
||||||
line += bytes_read;
|
line += bytes_read;
|
||||||
signature = oopFactory::new_symbol_handle(sig, CHECK);
|
signature = SymbolTable::new_symbol(sig, CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == OptionCommand) {
|
if (command == OptionCommand) {
|
||||||
@ -714,9 +714,9 @@ void CompilerOracle::parse_compile_only(char * line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
symbolHandle c_name = oopFactory::new_symbol_handle(className, CHECK);
|
Symbol* c_name = SymbolTable::new_symbol(className, CHECK);
|
||||||
symbolHandle m_name = oopFactory::new_symbol_handle(methodName, CHECK);
|
Symbol* m_name = SymbolTable::new_symbol(methodName, CHECK);
|
||||||
symbolHandle signature;
|
Symbol* signature = NULL;
|
||||||
|
|
||||||
add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature);
|
add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature);
|
||||||
if (PrintVMOptions) {
|
if (PrintVMOptions) {
|
||||||
|
@ -31,8 +31,6 @@
|
|||||||
// CompilerOracle is an interface for turning on and off compilation
|
// CompilerOracle is an interface for turning on and off compilation
|
||||||
// for some methods
|
// for some methods
|
||||||
|
|
||||||
class symbolHandle;
|
|
||||||
|
|
||||||
class CompilerOracle : AllStatic {
|
class CompilerOracle : AllStatic {
|
||||||
private:
|
private:
|
||||||
static bool _quiet;
|
static bool _quiet;
|
||||||
|
@ -5921,9 +5921,10 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
|
TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
|
||||||
// Now clean up stale oops in SymbolTable and StringTable
|
// Now clean up stale oops in StringTable
|
||||||
SymbolTable::unlink(&_is_alive_closure);
|
|
||||||
StringTable::unlink(&_is_alive_closure);
|
StringTable::unlink(&_is_alive_closure);
|
||||||
|
// Clean up unreferenced symbols in symbol table.
|
||||||
|
SymbolTable::unlink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2191,9 +2191,10 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
|
|||||||
rp->verify_no_references_recorded();
|
rp->verify_no_references_recorded();
|
||||||
assert(!rp->discovery_enabled(), "should have been disabled");
|
assert(!rp->discovery_enabled(), "should have been disabled");
|
||||||
|
|
||||||
// Now clean up stale oops in SymbolTable and StringTable
|
// Now clean up stale oops in StringTable
|
||||||
SymbolTable::unlink(&g1_is_alive);
|
|
||||||
StringTable::unlink(&g1_is_alive);
|
StringTable::unlink(&g1_is_alive);
|
||||||
|
// Clean up unreferenced symbols in symbol table.
|
||||||
|
SymbolTable::unlink();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentMark::swapMarkBitMaps() {
|
void ConcurrentMark::swapMarkBitMaps() {
|
||||||
|
@ -172,9 +172,10 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
|
|||||||
assert(GenMarkSweep::_marking_stack.is_empty(), "just drained");
|
assert(GenMarkSweep::_marking_stack.is_empty(), "just drained");
|
||||||
|
|
||||||
|
|
||||||
// Visit symbol and interned string tables and delete unmarked oops
|
// Visit interned string tables and delete unmarked oops
|
||||||
SymbolTable::unlink(&GenMarkSweep::is_alive);
|
|
||||||
StringTable::unlink(&GenMarkSweep::is_alive);
|
StringTable::unlink(&GenMarkSweep::is_alive);
|
||||||
|
// Clean up unreferenced symbols in symbol table.
|
||||||
|
SymbolTable::unlink();
|
||||||
|
|
||||||
assert(GenMarkSweep::_marking_stack.is_empty(),
|
assert(GenMarkSweep::_marking_stack.is_empty(),
|
||||||
"stack should be empty by now");
|
"stack should be empty by now");
|
||||||
|
@ -116,10 +116,6 @@ void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
|
|||||||
SystemDictionary::always_strong_oops_do(&mark_and_push_closure);
|
SystemDictionary::always_strong_oops_do(&mark_and_push_closure);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vm_symbols:
|
|
||||||
vmSymbols::oops_do(&mark_and_push_closure);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case code_cache:
|
case code_cache:
|
||||||
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
|
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
|
||||||
//CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure));
|
//CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure));
|
||||||
|
@ -98,9 +98,8 @@ class MarkFromRootsTask : public GCTask {
|
|||||||
management = 6,
|
management = 6,
|
||||||
jvmti = 7,
|
jvmti = 7,
|
||||||
system_dictionary = 8,
|
system_dictionary = 8,
|
||||||
vm_symbols = 9,
|
reference_processing = 9,
|
||||||
reference_processing = 10,
|
code_cache = 10
|
||||||
code_cache = 11
|
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
RootType _root_type;
|
RootType _root_type;
|
||||||
|
@ -527,7 +527,6 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
|||||||
Management::oops_do(mark_and_push_closure());
|
Management::oops_do(mark_and_push_closure());
|
||||||
JvmtiExport::oops_do(mark_and_push_closure());
|
JvmtiExport::oops_do(mark_and_push_closure());
|
||||||
SystemDictionary::always_strong_oops_do(mark_and_push_closure());
|
SystemDictionary::always_strong_oops_do(mark_and_push_closure());
|
||||||
vmSymbols::oops_do(mark_and_push_closure());
|
|
||||||
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
|
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
|
||||||
//CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
|
//CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
|
||||||
}
|
}
|
||||||
@ -558,9 +557,10 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
|||||||
follow_mdo_weak_refs();
|
follow_mdo_weak_refs();
|
||||||
assert(_marking_stack.is_empty(), "just drained");
|
assert(_marking_stack.is_empty(), "just drained");
|
||||||
|
|
||||||
// Visit symbol and interned string tables and delete unmarked oops
|
// Visit interned string tables and delete unmarked oops
|
||||||
SymbolTable::unlink(is_alive_closure());
|
|
||||||
StringTable::unlink(is_alive_closure());
|
StringTable::unlink(is_alive_closure());
|
||||||
|
// Clean up unreferenced symbols in symbol table.
|
||||||
|
SymbolTable::unlink();
|
||||||
|
|
||||||
assert(_marking_stack.is_empty(), "stack should be empty by now");
|
assert(_marking_stack.is_empty(), "stack should be empty by now");
|
||||||
}
|
}
|
||||||
@ -634,7 +634,6 @@ void PSMarkSweep::mark_sweep_phase3() {
|
|||||||
JvmtiExport::oops_do(adjust_root_pointer_closure());
|
JvmtiExport::oops_do(adjust_root_pointer_closure());
|
||||||
// SO_AllClasses
|
// SO_AllClasses
|
||||||
SystemDictionary::oops_do(adjust_root_pointer_closure());
|
SystemDictionary::oops_do(adjust_root_pointer_closure());
|
||||||
vmSymbols::oops_do(adjust_root_pointer_closure());
|
|
||||||
//CodeCache::scavenge_root_nmethods_oops_do(adjust_root_pointer_closure());
|
//CodeCache::scavenge_root_nmethods_oops_do(adjust_root_pointer_closure());
|
||||||
|
|
||||||
// Now adjust pointers in remaining weak roots. (All of which should
|
// Now adjust pointers in remaining weak roots. (All of which should
|
||||||
@ -643,7 +642,6 @@ void PSMarkSweep::mark_sweep_phase3() {
|
|||||||
JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure());
|
JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure());
|
||||||
|
|
||||||
CodeCache::oops_do(adjust_pointer_closure());
|
CodeCache::oops_do(adjust_pointer_closure());
|
||||||
SymbolTable::oops_do(adjust_root_pointer_closure());
|
|
||||||
StringTable::oops_do(adjust_root_pointer_closure());
|
StringTable::oops_do(adjust_root_pointer_closure());
|
||||||
ref_processor()->weak_oops_do(adjust_root_pointer_closure());
|
ref_processor()->weak_oops_do(adjust_root_pointer_closure());
|
||||||
PSScavenge::reference_processor()->weak_oops_do(adjust_root_pointer_closure());
|
PSScavenge::reference_processor()->weak_oops_do(adjust_root_pointer_closure());
|
||||||
|
@ -2375,7 +2375,6 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
|
|||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
|
||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
|
||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
|
||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::vm_symbols));
|
|
||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
|
||||||
|
|
||||||
if (parallel_gc_threads > 1) {
|
if (parallel_gc_threads > 1) {
|
||||||
@ -2425,9 +2424,10 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
|
|||||||
// Revisit memoized MDO's and clear any unmarked weak refs
|
// Revisit memoized MDO's and clear any unmarked weak refs
|
||||||
follow_mdo_weak_refs();
|
follow_mdo_weak_refs();
|
||||||
|
|
||||||
// Visit symbol and interned string tables and delete unmarked oops
|
// Visit interned string tables and delete unmarked oops
|
||||||
SymbolTable::unlink(is_alive_closure());
|
|
||||||
StringTable::unlink(is_alive_closure());
|
StringTable::unlink(is_alive_closure());
|
||||||
|
// Clean up unreferenced symbols in symbol table.
|
||||||
|
SymbolTable::unlink();
|
||||||
|
|
||||||
assert(cm->marking_stacks_empty(), "marking stacks should be empty");
|
assert(cm->marking_stacks_empty(), "marking stacks should be empty");
|
||||||
}
|
}
|
||||||
@ -2456,7 +2456,6 @@ void PSParallelCompact::adjust_roots() {
|
|||||||
JvmtiExport::oops_do(adjust_root_pointer_closure());
|
JvmtiExport::oops_do(adjust_root_pointer_closure());
|
||||||
// SO_AllClasses
|
// SO_AllClasses
|
||||||
SystemDictionary::oops_do(adjust_root_pointer_closure());
|
SystemDictionary::oops_do(adjust_root_pointer_closure());
|
||||||
vmSymbols::oops_do(adjust_root_pointer_closure());
|
|
||||||
|
|
||||||
// Now adjust pointers in remaining weak roots. (All of which should
|
// Now adjust pointers in remaining weak roots. (All of which should
|
||||||
// have been cleared if they pointed to non-surviving objects.)
|
// have been cleared if they pointed to non-surviving objects.)
|
||||||
@ -2464,7 +2463,6 @@ void PSParallelCompact::adjust_roots() {
|
|||||||
JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure());
|
JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure());
|
||||||
|
|
||||||
CodeCache::oops_do(adjust_pointer_closure());
|
CodeCache::oops_do(adjust_pointer_closure());
|
||||||
SymbolTable::oops_do(adjust_root_pointer_closure());
|
|
||||||
StringTable::oops_do(adjust_root_pointer_closure());
|
StringTable::oops_do(adjust_root_pointer_closure());
|
||||||
ref_processor()->weak_oops_do(adjust_root_pointer_closure());
|
ref_processor()->weak_oops_do(adjust_root_pointer_closure());
|
||||||
// Roots were visited so references into the young gen in roots
|
// Roots were visited so references into the young gen in roots
|
||||||
|
@ -187,7 +187,7 @@ SurrogateLockerThread::SurrogateLockerThread() :
|
|||||||
|
|
||||||
SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
|
SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
|
||||||
klassOop k =
|
klassOop k =
|
||||||
SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(),
|
SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
|
||||||
true, CHECK_NULL);
|
true, CHECK_NULL);
|
||||||
instanceKlassHandle klass (THREAD, k);
|
instanceKlassHandle klass (THREAD, k);
|
||||||
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
|
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
|
||||||
@ -200,8 +200,8 @@ SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
|
|||||||
JavaValue result(T_VOID);
|
JavaValue result(T_VOID);
|
||||||
JavaCalls::call_special(&result, thread_oop,
|
JavaCalls::call_special(&result, thread_oop,
|
||||||
klass,
|
klass,
|
||||||
vmSymbolHandles::object_initializer_name(),
|
vmSymbols::object_initializer_name(),
|
||||||
vmSymbolHandles::threadgroup_string_void_signature(),
|
vmSymbols::threadgroup_string_void_signature(),
|
||||||
thread_group,
|
thread_group,
|
||||||
string,
|
string,
|
||||||
CHECK_NULL);
|
CHECK_NULL);
|
||||||
|
@ -111,7 +111,7 @@ void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
|
|||||||
|
|
||||||
MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure;
|
MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure;
|
||||||
|
|
||||||
void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); }
|
void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { assert(*p == NULL || (*p)->is_oop(), ""); mark_and_push(p); }
|
||||||
void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
|
void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
|
||||||
|
|
||||||
void MarkSweep::follow_stack() {
|
void MarkSweep::follow_stack() {
|
||||||
|
@ -124,21 +124,20 @@ void Bytecode_invoke::verify() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
symbolOop Bytecode_member_ref::signature() const {
|
Symbol* Bytecode_member_ref::signature() const {
|
||||||
constantPoolOop constants = method()->constants();
|
constantPoolOop constants = method()->constants();
|
||||||
return constants->signature_ref_at(index());
|
return constants->signature_ref_at(index());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
symbolOop Bytecode_member_ref::name() const {
|
Symbol* Bytecode_member_ref::name() const {
|
||||||
constantPoolOop constants = method()->constants();
|
constantPoolOop constants = method()->constants();
|
||||||
return constants->name_ref_at(index());
|
return constants->name_ref_at(index());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BasicType Bytecode_member_ref::result_type(Thread *thread) const {
|
BasicType Bytecode_member_ref::result_type() const {
|
||||||
symbolHandle sh(thread, signature());
|
ResultTypeFinder rts(signature());
|
||||||
ResultTypeFinder rts(sh);
|
|
||||||
rts.iterate();
|
rts.iterate();
|
||||||
return rts.type();
|
return rts.type();
|
||||||
}
|
}
|
||||||
|
@ -193,10 +193,10 @@ class Bytecode_member_ref: public Bytecode {
|
|||||||
public:
|
public:
|
||||||
int index() const; // cache index (loaded from instruction)
|
int index() const; // cache index (loaded from instruction)
|
||||||
int pool_index() const; // constant pool index
|
int pool_index() const; // constant pool index
|
||||||
symbolOop name() const; // returns the name of the method or field
|
Symbol* name() const; // returns the name of the method or field
|
||||||
symbolOop signature() const; // returns the signature of the method or field
|
Symbol* signature() const; // returns the signature of the method or field
|
||||||
|
|
||||||
BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke
|
BasicType result_type() const; // returns the result type of the getfield or invoke
|
||||||
};
|
};
|
||||||
|
|
||||||
// Abstraction for invoke_{virtual, static, interface, special}
|
// Abstraction for invoke_{virtual, static, interface, special}
|
||||||
|
@ -188,7 +188,7 @@ void BytecodeTracer::trace(methodHandle method, address bcp, outputStream* st) {
|
|||||||
_closure->trace(method, bcp, st);
|
_closure->trace(method, bcp, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_symbol(symbolOop sym, outputStream* st) {
|
void print_symbol(Symbol* sym, outputStream* st) {
|
||||||
char buf[40];
|
char buf[40];
|
||||||
int len = sym->utf8_length();
|
int len = sym->utf8_length();
|
||||||
if (len >= (int)sizeof(buf)) {
|
if (len >= (int)sizeof(buf)) {
|
||||||
@ -205,10 +205,9 @@ void print_oop(oop value, outputStream* st) {
|
|||||||
} else if (java_lang_String::is_instance(value)) {
|
} else if (java_lang_String::is_instance(value)) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
Handle h_value (THREAD, value);
|
Handle h_value (THREAD, value);
|
||||||
symbolHandle sym = java_lang_String::as_symbol(h_value, CATCH);
|
Symbol* sym = java_lang_String::as_symbol(h_value, CATCH);
|
||||||
print_symbol(sym(), st);
|
print_symbol(sym, st);
|
||||||
} else if (value->is_symbol()) {
|
sym->decrement_refcount();
|
||||||
print_symbol(symbolOop(value), st);
|
|
||||||
} else {
|
} else {
|
||||||
st->print_cr(" " PTR_FORMAT, (intptr_t) value);
|
st->print_cr(" " PTR_FORMAT, (intptr_t) value);
|
||||||
}
|
}
|
||||||
@ -316,7 +315,7 @@ void BytecodePrinter::print_constant(int i, outputStream* st) {
|
|||||||
} else if (tag.is_method_type()) {
|
} else if (tag.is_method_type()) {
|
||||||
int i2 = constants->method_type_index_at(i);
|
int i2 = constants->method_type_index_at(i);
|
||||||
st->print(" <MethodType> %d", i2);
|
st->print(" <MethodType> %d", i2);
|
||||||
print_oop(constants->symbol_at(i2), st);
|
print_symbol(constants->symbol_at(i2), st);
|
||||||
} else if (tag.is_method_handle()) {
|
} else if (tag.is_method_handle()) {
|
||||||
int kind = constants->method_handle_ref_kind_at(i);
|
int kind = constants->method_handle_ref_kind_at(i);
|
||||||
int i2 = constants->method_handle_index_at(i);
|
int i2 = constants->method_handle_index_at(i);
|
||||||
@ -354,11 +353,11 @@ void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
symbolOop name = constants->uncached_name_ref_at(i);
|
Symbol* name = constants->uncached_name_ref_at(i);
|
||||||
symbolOop signature = constants->uncached_signature_ref_at(i);
|
Symbol* signature = constants->uncached_signature_ref_at(i);
|
||||||
const char* sep = (tag.is_field() ? "/" : "");
|
const char* sep = (tag.is_field() ? "/" : "");
|
||||||
if (has_klass) {
|
if (has_klass) {
|
||||||
symbolOop klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i));
|
Symbol* klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i));
|
||||||
st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string());
|
st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string());
|
||||||
} else {
|
} else {
|
||||||
if (tag.is_invoke_dynamic()) {
|
if (tag.is_invoke_dynamic()) {
|
||||||
@ -438,7 +437,7 @@ void BytecodePrinter::print_attributes(int bci, outputStream* st) {
|
|||||||
case Bytecodes::_anewarray: {
|
case Bytecodes::_anewarray: {
|
||||||
int klass_index = get_index_u2();
|
int klass_index = get_index_u2();
|
||||||
constantPoolOop constants = method()->constants();
|
constantPoolOop constants = method()->constants();
|
||||||
symbolOop name = constants->klass_name_at(klass_index);
|
Symbol* name = constants->klass_name_at(klass_index);
|
||||||
st->print_cr(" %s ", name->as_C_string());
|
st->print_cr(" %s ", name->as_C_string());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -446,7 +445,7 @@ void BytecodePrinter::print_attributes(int bci, outputStream* st) {
|
|||||||
int klass_index = get_index_u2();
|
int klass_index = get_index_u2();
|
||||||
int nof_dims = get_index_u1();
|
int nof_dims = get_index_u1();
|
||||||
constantPoolOop constants = method()->constants();
|
constantPoolOop constants = method()->constants();
|
||||||
symbolOop name = constants->klass_name_at(klass_index);
|
Symbol* name = constants->klass_name_at(klass_index);
|
||||||
st->print_cr(" %s %d", name->as_C_string(), nof_dims);
|
st->print_cr(" %s %d", name->as_C_string(), nof_dims);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -552,7 +551,7 @@ void BytecodePrinter::print_attributes(int bci, outputStream* st) {
|
|||||||
case Bytecodes::_instanceof:
|
case Bytecodes::_instanceof:
|
||||||
{ int i = get_index_u2();
|
{ int i = get_index_u2();
|
||||||
constantPoolOop constants = method()->constants();
|
constantPoolOop constants = method()->constants();
|
||||||
symbolOop name = constants->klass_name_at(i);
|
Symbol* name = constants->klass_name_at(i);
|
||||||
st->print_cr(" %d <%s>", i, name->as_C_string());
|
st->print_cr(" %d <%s>", i, name->as_C_string());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -302,7 +302,7 @@ address AbstractInterpreter::deopt_continue_after_entry(methodOop method, addres
|
|||||||
Thread *thread = Thread::current();
|
Thread *thread = Thread::current();
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
methodHandle mh(thread, method);
|
methodHandle mh(thread, method);
|
||||||
type = Bytecode_invoke(mh, bci).result_type(thread);
|
type = Bytecode_invoke(mh, bci).result_type();
|
||||||
// since the cache entry might not be initialized:
|
// since the cache entry might not be initialized:
|
||||||
// (NOT needed for the old calling convension)
|
// (NOT needed for the old calling convension)
|
||||||
if (!is_top_frame) {
|
if (!is_top_frame) {
|
||||||
@ -316,7 +316,7 @@ address AbstractInterpreter::deopt_continue_after_entry(methodOop method, addres
|
|||||||
Thread *thread = Thread::current();
|
Thread *thread = Thread::current();
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
methodHandle mh(thread, method);
|
methodHandle mh(thread, method);
|
||||||
type = Bytecode_invoke(mh, bci).result_type(thread);
|
type = Bytecode_invoke(mh, bci).result_type();
|
||||||
// since the cache entry might not be initialized:
|
// since the cache entry might not be initialized:
|
||||||
// (NOT needed for the old calling convension)
|
// (NOT needed for the old calling convension)
|
||||||
if (!is_top_frame) {
|
if (!is_top_frame) {
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include "oops/methodDataOop.hpp"
|
#include "oops/methodDataOop.hpp"
|
||||||
#include "oops/objArrayKlass.hpp"
|
#include "oops/objArrayKlass.hpp"
|
||||||
#include "oops/oop.inline.hpp"
|
#include "oops/oop.inline.hpp"
|
||||||
#include "oops/symbolOop.hpp"
|
#include "oops/symbol.hpp"
|
||||||
#include "prims/jvmtiExport.hpp"
|
#include "prims/jvmtiExport.hpp"
|
||||||
#include "prims/nativeLookup.hpp"
|
#include "prims/nativeLookup.hpp"
|
||||||
#include "runtime/biasedLocking.hpp"
|
#include "runtime/biasedLocking.hpp"
|
||||||
@ -295,7 +295,7 @@ IRT_END
|
|||||||
|
|
||||||
IRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message))
|
IRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message))
|
||||||
// lookup exception klass
|
// lookup exception klass
|
||||||
symbolHandle s = oopFactory::new_symbol_handle(name, CHECK);
|
TempNewSymbol s = SymbolTable::new_symbol(name, CHECK);
|
||||||
if (ProfileTraps) {
|
if (ProfileTraps) {
|
||||||
if (s == vmSymbols::java_lang_ArithmeticException()) {
|
if (s == vmSymbols::java_lang_ArithmeticException()) {
|
||||||
note_trap(thread, Deoptimization::Reason_div0_check, CHECK);
|
note_trap(thread, Deoptimization::Reason_div0_check, CHECK);
|
||||||
@ -304,7 +304,7 @@ IRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// create exception
|
// create exception
|
||||||
Handle exception = Exceptions::new_exception(thread, s(), message);
|
Handle exception = Exceptions::new_exception(thread, s, message);
|
||||||
thread->set_vm_result(exception());
|
thread->set_vm_result(exception());
|
||||||
IRT_END
|
IRT_END
|
||||||
|
|
||||||
@ -313,12 +313,12 @@ IRT_ENTRY(void, InterpreterRuntime::create_klass_exception(JavaThread* thread, c
|
|||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
const char* klass_name = Klass::cast(obj->klass())->external_name();
|
const char* klass_name = Klass::cast(obj->klass())->external_name();
|
||||||
// lookup exception klass
|
// lookup exception klass
|
||||||
symbolHandle s = oopFactory::new_symbol_handle(name, CHECK);
|
TempNewSymbol s = SymbolTable::new_symbol(name, CHECK);
|
||||||
if (ProfileTraps) {
|
if (ProfileTraps) {
|
||||||
note_trap(thread, Deoptimization::Reason_class_check, CHECK);
|
note_trap(thread, Deoptimization::Reason_class_check, CHECK);
|
||||||
}
|
}
|
||||||
// create exception, with klass name as detail message
|
// create exception, with klass name as detail message
|
||||||
Handle exception = Exceptions::new_exception(thread, s(), klass_name);
|
Handle exception = Exceptions::new_exception(thread, s, klass_name);
|
||||||
thread->set_vm_result(exception());
|
thread->set_vm_result(exception());
|
||||||
IRT_END
|
IRT_END
|
||||||
|
|
||||||
@ -326,13 +326,13 @@ IRT_END
|
|||||||
IRT_ENTRY(void, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index))
|
IRT_ENTRY(void, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index))
|
||||||
char message[jintAsStringSize];
|
char message[jintAsStringSize];
|
||||||
// lookup exception klass
|
// lookup exception klass
|
||||||
symbolHandle s = oopFactory::new_symbol_handle(name, CHECK);
|
TempNewSymbol s = SymbolTable::new_symbol(name, CHECK);
|
||||||
if (ProfileTraps) {
|
if (ProfileTraps) {
|
||||||
note_trap(thread, Deoptimization::Reason_range_check, CHECK);
|
note_trap(thread, Deoptimization::Reason_range_check, CHECK);
|
||||||
}
|
}
|
||||||
// create exception
|
// create exception
|
||||||
sprintf(message, "%d", index);
|
sprintf(message, "%d", index);
|
||||||
THROW_MSG(s(), message);
|
THROW_MSG(s, message);
|
||||||
IRT_END
|
IRT_END
|
||||||
|
|
||||||
IRT_ENTRY(void, InterpreterRuntime::throw_ClassCastException(
|
IRT_ENTRY(void, InterpreterRuntime::throw_ClassCastException(
|
||||||
@ -673,7 +673,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
|
|||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
methodHandle m (thread, method(thread));
|
methodHandle m (thread, method(thread));
|
||||||
Bytecode_invoke call(m, bci(thread));
|
Bytecode_invoke call(m, bci(thread));
|
||||||
symbolHandle signature (thread, call.signature());
|
Symbol* signature = call.signature();
|
||||||
receiver = Handle(thread,
|
receiver = Handle(thread,
|
||||||
thread->last_frame().interpreter_callee_receiver(signature));
|
thread->last_frame().interpreter_callee_receiver(signature));
|
||||||
assert(Universe::heap()->is_in_reserved_or_null(receiver()),
|
assert(Universe::heap()->is_in_reserved_or_null(receiver()),
|
||||||
@ -797,7 +797,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
|
|||||||
if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null())
|
if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
symbolHandle call_site_name(THREAD, pool->name_ref_at(site_index));
|
Symbol* call_site_name = pool->name_ref_at(site_index);
|
||||||
|
|
||||||
Handle call_site
|
Handle call_site
|
||||||
= SystemDictionary::make_dynamic_call_site(bootm,
|
= SystemDictionary::make_dynamic_call_site(bootm,
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
//------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------
|
||||||
// Implementation of FieldAccessInfo
|
// Implementation of FieldAccessInfo
|
||||||
|
|
||||||
void FieldAccessInfo::set(KlassHandle klass, symbolHandle name, int field_index, int field_offset,
|
void FieldAccessInfo::set(KlassHandle klass, Symbol* name, int field_index, int field_offset,
|
||||||
BasicType field_type, AccessFlags access_flags) {
|
BasicType field_type, AccessFlags access_flags) {
|
||||||
_klass = klass;
|
_klass = klass;
|
||||||
_name = name;
|
_name = name;
|
||||||
@ -148,7 +148,7 @@ void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
Exceptions::fthrow(
|
Exceptions::fthrow(
|
||||||
THREAD_AND_LOCATION,
|
THREAD_AND_LOCATION,
|
||||||
vmSymbolHandles::java_lang_IllegalAccessError(),
|
vmSymbols::java_lang_IllegalAccessError(),
|
||||||
"tried to access class %s from class %s",
|
"tried to access class %s from class %s",
|
||||||
sel_klass->external_name(),
|
sel_klass->external_name(),
|
||||||
ref_klass->external_name()
|
ref_klass->external_name()
|
||||||
@ -174,8 +174,8 @@ void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHand
|
|||||||
//
|
//
|
||||||
// According to JVM spec. $5.4.3c & $5.4.3d
|
// According to JVM spec. $5.4.3c & $5.4.3d
|
||||||
|
|
||||||
void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
|
void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
|
||||||
methodOop result_oop = klass->uncached_lookup_method(name(), signature());
|
methodOop result_oop = klass->uncached_lookup_method(name, signature);
|
||||||
if (EnableMethodHandles && result_oop != NULL) {
|
if (EnableMethodHandles && result_oop != NULL) {
|
||||||
switch (result_oop->intrinsic_id()) {
|
switch (result_oop->intrinsic_id()) {
|
||||||
case vmIntrinsics::_invokeExact:
|
case vmIntrinsics::_invokeExact:
|
||||||
@ -189,39 +189,39 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns first instance method
|
// returns first instance method
|
||||||
void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
|
void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
|
||||||
methodOop result_oop = klass->uncached_lookup_method(name(), signature());
|
methodOop result_oop = klass->uncached_lookup_method(name, signature);
|
||||||
result = methodHandle(THREAD, result_oop);
|
result = methodHandle(THREAD, result_oop);
|
||||||
while (!result.is_null() && result->is_static()) {
|
while (!result.is_null() && result->is_static()) {
|
||||||
klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super());
|
klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super());
|
||||||
result = methodHandle(THREAD, klass->uncached_lookup_method(name(), signature()));
|
result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
|
int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
klassVtable *vt = instanceKlass::cast(klass())->vtable();
|
klassVtable *vt = instanceKlass::cast(klass())->vtable();
|
||||||
return vt->index_of_miranda(name(), signature());
|
return vt->index_of_miranda(name, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
|
void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
|
||||||
instanceKlass *ik = instanceKlass::cast(klass());
|
instanceKlass *ik = instanceKlass::cast(klass());
|
||||||
result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name(), signature()));
|
result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkResolver::lookup_implicit_method(methodHandle& result,
|
void LinkResolver::lookup_implicit_method(methodHandle& result,
|
||||||
KlassHandle klass, symbolHandle name, symbolHandle signature,
|
KlassHandle klass, Symbol* name, Symbol* signature,
|
||||||
KlassHandle current_klass,
|
KlassHandle current_klass,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
if (EnableMethodHandles &&
|
if (EnableMethodHandles &&
|
||||||
klass() == SystemDictionary::MethodHandle_klass() &&
|
klass() == SystemDictionary::MethodHandle_klass() &&
|
||||||
methodOopDesc::is_method_handle_invoke_name(name())) {
|
methodOopDesc::is_method_handle_invoke_name(name)) {
|
||||||
if (!MethodHandles::enabled()) {
|
if (!MethodHandles::enabled()) {
|
||||||
// Make sure the Java part of the runtime has been booted up.
|
// Make sure the Java part of the runtime has been booted up.
|
||||||
klassOop natives = SystemDictionary::MethodHandleNatives_klass();
|
klassOop natives = SystemDictionary::MethodHandleNatives_klass();
|
||||||
if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
|
if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
|
||||||
SystemDictionary::resolve_or_fail(vmSymbolHandles::sun_dyn_MethodHandleNatives(),
|
SystemDictionary::resolve_or_fail(vmSymbols::sun_dyn_MethodHandleNatives(),
|
||||||
Handle(),
|
Handle(),
|
||||||
Handle(),
|
Handle(),
|
||||||
true,
|
true,
|
||||||
@ -233,7 +233,7 @@ void LinkResolver::lookup_implicit_method(methodHandle& result,
|
|||||||
current_klass,
|
current_klass,
|
||||||
CHECK);
|
CHECK);
|
||||||
if (result_oop != NULL) {
|
if (result_oop != NULL) {
|
||||||
assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature(), "consistent");
|
assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature, "consistent");
|
||||||
result = methodHandle(THREAD, result_oop);
|
result = methodHandle(THREAD, result_oop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,7 +273,7 @@ void LinkResolver::check_method_accessability(KlassHandle ref_klass,
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
Exceptions::fthrow(
|
Exceptions::fthrow(
|
||||||
THREAD_AND_LOCATION,
|
THREAD_AND_LOCATION,
|
||||||
vmSymbolHandles::java_lang_IllegalAccessError(),
|
vmSymbols::java_lang_IllegalAccessError(),
|
||||||
"tried to access method %s.%s%s from class %s",
|
"tried to access method %s.%s%s from class %s",
|
||||||
sel_klass->external_name(),
|
sel_klass->external_name(),
|
||||||
sel_method->name()->as_C_string(),
|
sel_method->name()->as_C_string(),
|
||||||
@ -290,8 +290,8 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle& re
|
|||||||
// resolve klass
|
// resolve klass
|
||||||
resolve_klass(resolved_klass, pool, index, CHECK);
|
resolve_klass(resolved_klass, pool, index, CHECK);
|
||||||
|
|
||||||
symbolHandle method_name (THREAD, pool->name_ref_at(index));
|
Symbol* method_name = pool->name_ref_at(index);
|
||||||
symbolHandle method_signature (THREAD, pool->signature_ref_at(index));
|
Symbol* method_signature = pool->signature_ref_at(index);
|
||||||
KlassHandle current_klass(THREAD, pool->pool_holder());
|
KlassHandle current_klass(THREAD, pool->pool_holder());
|
||||||
|
|
||||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
||||||
@ -301,9 +301,9 @@ void LinkResolver::resolve_dynamic_method(methodHandle& resolved_method, KlassHa
|
|||||||
// The class is java.dyn.MethodHandle
|
// The class is java.dyn.MethodHandle
|
||||||
resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
|
resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
|
||||||
|
|
||||||
symbolHandle method_name = vmSymbolHandles::invokeExact_name();
|
Symbol* method_name = vmSymbols::invokeExact_name();
|
||||||
|
|
||||||
symbolHandle method_signature(THREAD, pool->signature_ref_at(index));
|
Symbol* method_signature = pool->signature_ref_at(index);
|
||||||
KlassHandle current_klass (THREAD, pool->pool_holder());
|
KlassHandle current_klass (THREAD, pool->pool_holder());
|
||||||
|
|
||||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
||||||
@ -313,8 +313,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method, Klass
|
|||||||
|
|
||||||
// resolve klass
|
// resolve klass
|
||||||
resolve_klass(resolved_klass, pool, index, CHECK);
|
resolve_klass(resolved_klass, pool, index, CHECK);
|
||||||
symbolHandle method_name (THREAD, pool->name_ref_at(index));
|
Symbol* method_name = pool->name_ref_at(index);
|
||||||
symbolHandle method_signature (THREAD, pool->signature_ref_at(index));
|
Symbol* method_signature = pool->signature_ref_at(index);
|
||||||
KlassHandle current_klass(THREAD, pool->pool_holder());
|
KlassHandle current_klass(THREAD, pool->pool_holder());
|
||||||
|
|
||||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
||||||
@ -322,7 +322,7 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method, Klass
|
|||||||
|
|
||||||
|
|
||||||
void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
|
void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
|
||||||
symbolHandle method_name, symbolHandle method_signature,
|
Symbol* method_name, Symbol* method_signature,
|
||||||
KlassHandle current_klass, bool check_access, TRAPS) {
|
KlassHandle current_klass, bool check_access, TRAPS) {
|
||||||
|
|
||||||
// 1. check if klass is not interface
|
// 1. check if klass is not interface
|
||||||
@ -349,8 +349,8 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
|
THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
|
||||||
methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
|
methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
|
||||||
method_name(),
|
method_name,
|
||||||
method_signature()));
|
method_signature));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,8 +359,8 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
|
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
|
||||||
methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
|
methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
|
||||||
method_name(),
|
method_name,
|
||||||
method_signature()));
|
method_signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. access checks, access checking may be turned off when calling from within the VM.
|
// 6. access checks, access checking may be turned off when calling from within the VM.
|
||||||
@ -387,7 +387,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
|
|||||||
" \"%s\" the class loader (instance of %s) of the current class, %s,"
|
" \"%s\" the class loader (instance of %s) of the current class, %s,"
|
||||||
" and the class loader (instance of %s) for resolved class, %s, have"
|
" and the class loader (instance of %s) for resolved class, %s, have"
|
||||||
" different Class objects for the type %s used in the signature";
|
" different Class objects for the type %s used in the signature";
|
||||||
char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name(),method_signature());
|
char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature);
|
||||||
const char* loader1 = SystemDictionary::loader_name(loader());
|
const char* loader1 = SystemDictionary::loader_name(loader());
|
||||||
char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
|
char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
|
||||||
const char* loader2 = SystemDictionary::loader_name(class_loader());
|
const char* loader2 = SystemDictionary::loader_name(class_loader());
|
||||||
@ -406,8 +406,8 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
|
|||||||
|
|
||||||
void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
||||||
KlassHandle resolved_klass,
|
KlassHandle resolved_klass,
|
||||||
symbolHandle method_name,
|
Symbol* method_name,
|
||||||
symbolHandle method_signature,
|
Symbol* method_signature,
|
||||||
KlassHandle current_klass,
|
KlassHandle current_klass,
|
||||||
bool check_access, TRAPS) {
|
bool check_access, TRAPS) {
|
||||||
|
|
||||||
@ -429,8 +429,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
|
THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
|
||||||
methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
|
methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
|
||||||
method_name(),
|
method_name,
|
||||||
method_signature()));
|
method_signature));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,7 +449,7 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
|||||||
"current class, %s, and the class loader (instance of %s) for "
|
"current class, %s, and the class loader (instance of %s) for "
|
||||||
"resolved class, %s, have different Class objects for the type %s "
|
"resolved class, %s, have different Class objects for the type %s "
|
||||||
"used in the signature";
|
"used in the signature";
|
||||||
char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name(),method_signature());
|
char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature);
|
||||||
const char* loader1 = SystemDictionary::loader_name(loader());
|
const char* loader1 = SystemDictionary::loader_name(loader());
|
||||||
char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
|
char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
|
||||||
const char* loader2 = SystemDictionary::loader_name(class_loader());
|
const char* loader2 = SystemDictionary::loader_name(class_loader());
|
||||||
@ -482,7 +482,7 @@ void LinkResolver::check_field_accessability(KlassHandle ref_klass,
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
Exceptions::fthrow(
|
Exceptions::fthrow(
|
||||||
THREAD_AND_LOCATION,
|
THREAD_AND_LOCATION,
|
||||||
vmSymbolHandles::java_lang_IllegalAccessError(),
|
vmSymbols::java_lang_IllegalAccessError(),
|
||||||
"tried to access field %s.%s from class %s",
|
"tried to access field %s.%s from class %s",
|
||||||
sel_klass->external_name(),
|
sel_klass->external_name(),
|
||||||
fd.name()->as_C_string(),
|
fd.name()->as_C_string(),
|
||||||
@ -511,9 +511,8 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
|
|||||||
resolve_klass_no_update(resolved_klass, pool, index, CHECK);
|
resolve_klass_no_update(resolved_klass, pool, index, CHECK);
|
||||||
}
|
}
|
||||||
// Load these early in case the resolve of the containing klass fails
|
// Load these early in case the resolve of the containing klass fails
|
||||||
symbolOop field = pool->name_ref_at(index);
|
Symbol* field = pool->name_ref_at(index);
|
||||||
symbolHandle field_h (THREAD, field); // preserve in case we need the name
|
Symbol* sig = pool->signature_ref_at(index);
|
||||||
symbolOop sig = pool->signature_ref_at(index);
|
|
||||||
// Check if there's a resolved klass containing the field
|
// Check if there's a resolved klass containing the field
|
||||||
if( resolved_klass.is_null() ) {
|
if( resolved_klass.is_null() ) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
@ -559,7 +558,7 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
|
|||||||
HandleMark hm(THREAD);
|
HandleMark hm(THREAD);
|
||||||
Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader());
|
Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader());
|
||||||
Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader());
|
Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader());
|
||||||
symbolHandle signature_ref (THREAD, pool->signature_ref_at(index));
|
Symbol* signature_ref = pool->signature_ref_at(index);
|
||||||
{
|
{
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
char* failed_type_name =
|
char* failed_type_name =
|
||||||
@ -572,7 +571,7 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
|
|||||||
" \"%s\" the class loader (instance of %s) of the referring class, "
|
" \"%s\" the class loader (instance of %s) of the referring class, "
|
||||||
"%s, and the class loader (instance of %s) for the field's resolved "
|
"%s, and the class loader (instance of %s) for the field's resolved "
|
||||||
"type, %s, have different Class objects for that type";
|
"type, %s, have different Class objects for that type";
|
||||||
char* field_name = field_h()->as_C_string();
|
char* field_name = field->as_C_string();
|
||||||
const char* loader1 = SystemDictionary::loader_name(ref_loader());
|
const char* loader1 = SystemDictionary::loader_name(ref_loader());
|
||||||
char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string();
|
char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string();
|
||||||
const char* loader2 = SystemDictionary::loader_name(sel_loader());
|
const char* loader2 = SystemDictionary::loader_name(sel_loader());
|
||||||
@ -589,7 +588,7 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
|
|||||||
// return information. note that the klass is set to the actual klass containing the
|
// return information. note that the klass is set to the actual klass containing the
|
||||||
// field, otherwise access of static fields in superclasses will not work.
|
// field, otherwise access of static fields in superclasses will not work.
|
||||||
KlassHandle holder (THREAD, fd.field_holder());
|
KlassHandle holder (THREAD, fd.field_holder());
|
||||||
symbolHandle name (THREAD, fd.name());
|
Symbol* name = fd.name();
|
||||||
result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags());
|
result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,8 +604,8 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
|
|||||||
// recv_klass the receiver klass
|
// recv_klass the receiver klass
|
||||||
|
|
||||||
|
|
||||||
void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, symbolHandle method_name,
|
void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name,
|
||||||
symbolHandle method_signature, KlassHandle current_klass,
|
Symbol* method_signature, KlassHandle current_klass,
|
||||||
bool check_access, bool initialize_class, TRAPS) {
|
bool check_access, bool initialize_class, TRAPS) {
|
||||||
methodHandle resolved_method;
|
methodHandle resolved_method;
|
||||||
linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
@ -624,7 +623,7 @@ void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_k
|
|||||||
|
|
||||||
// throws linktime exceptions
|
// throws linktime exceptions
|
||||||
void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
|
void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
|
||||||
symbolHandle method_name, symbolHandle method_signature,
|
Symbol* method_name, Symbol* method_signature,
|
||||||
KlassHandle current_klass, bool check_access, TRAPS) {
|
KlassHandle current_klass, bool check_access, TRAPS) {
|
||||||
|
|
||||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
@ -641,8 +640,8 @@ void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, symbolHandle method_name,
|
void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name,
|
||||||
symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
|
Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
|
||||||
methodHandle resolved_method;
|
methodHandle resolved_method;
|
||||||
linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK);
|
runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK);
|
||||||
@ -650,7 +649,7 @@ void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_k
|
|||||||
|
|
||||||
// throws linktime exceptions
|
// throws linktime exceptions
|
||||||
void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
|
void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
|
||||||
symbolHandle method_name, symbolHandle method_signature,
|
Symbol* method_name, Symbol* method_signature,
|
||||||
KlassHandle current_klass, bool check_access, TRAPS) {
|
KlassHandle current_klass, bool check_access, TRAPS) {
|
||||||
|
|
||||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
@ -661,7 +660,7 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
Exceptions::fthrow(
|
Exceptions::fthrow(
|
||||||
THREAD_AND_LOCATION,
|
THREAD_AND_LOCATION,
|
||||||
vmSymbolHandles::java_lang_NoSuchMethodError(),
|
vmSymbols::java_lang_NoSuchMethodError(),
|
||||||
"%s: method %s%s not found",
|
"%s: method %s%s not found",
|
||||||
resolved_klass->external_name(),
|
resolved_klass->external_name(),
|
||||||
resolved_method->name()->as_C_string(),
|
resolved_method->name()->as_C_string(),
|
||||||
@ -703,8 +702,8 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle
|
|||||||
// Lookup super method
|
// Lookup super method
|
||||||
KlassHandle super_klass(THREAD, current_klass->super());
|
KlassHandle super_klass(THREAD, current_klass->super());
|
||||||
lookup_instance_method_in_klasses(sel_method, super_klass,
|
lookup_instance_method_in_klasses(sel_method, super_klass,
|
||||||
symbolHandle(THREAD, resolved_method->name()),
|
resolved_method->name(),
|
||||||
symbolHandle(THREAD, resolved_method->signature()), CHECK);
|
resolved_method->signature(), CHECK);
|
||||||
// check if found
|
// check if found
|
||||||
if (sel_method.is_null()) {
|
if (sel_method.is_null()) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
@ -739,7 +738,7 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass,
|
void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass,
|
||||||
symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass,
|
Symbol* method_name, Symbol* method_signature, KlassHandle current_klass,
|
||||||
bool check_access, bool check_null_and_abstract, TRAPS) {
|
bool check_access, bool check_null_and_abstract, TRAPS) {
|
||||||
methodHandle resolved_method;
|
methodHandle resolved_method;
|
||||||
linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
@ -748,7 +747,7 @@ void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHand
|
|||||||
|
|
||||||
// throws linktime exceptions
|
// throws linktime exceptions
|
||||||
void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass,
|
void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass,
|
||||||
symbolHandle method_name, symbolHandle method_signature,
|
Symbol* method_name, Symbol* method_signature,
|
||||||
KlassHandle current_klass, bool check_access, TRAPS) {
|
KlassHandle current_klass, bool check_access, TRAPS) {
|
||||||
// normal method resolution
|
// normal method resolution
|
||||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
@ -798,8 +797,8 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
|
|||||||
// do lookup based on receiver klass using the vtable index
|
// do lookup based on receiver klass using the vtable index
|
||||||
if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method
|
if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method
|
||||||
vtable_index = vtable_index_of_miranda_method(resolved_klass,
|
vtable_index = vtable_index_of_miranda_method(resolved_klass,
|
||||||
symbolHandle(THREAD, resolved_method->name()),
|
resolved_method->name(),
|
||||||
symbolHandle(THREAD, resolved_method->signature()), CHECK);
|
resolved_method->signature(), CHECK);
|
||||||
assert(vtable_index >= 0 , "we should have valid vtable index at this point");
|
assert(vtable_index >= 0 , "we should have valid vtable index at this point");
|
||||||
|
|
||||||
instanceKlass* inst = instanceKlass::cast(recv_klass());
|
instanceKlass* inst = instanceKlass::cast(recv_klass());
|
||||||
@ -847,7 +846,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass,
|
void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass,
|
||||||
symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass,
|
Symbol* method_name, Symbol* method_signature, KlassHandle current_klass,
|
||||||
bool check_access, bool check_null_and_abstract, TRAPS) {
|
bool check_access, bool check_null_and_abstract, TRAPS) {
|
||||||
methodHandle resolved_method;
|
methodHandle resolved_method;
|
||||||
linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
@ -855,8 +854,8 @@ void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// throws linktime exceptions
|
// throws linktime exceptions
|
||||||
void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name,
|
void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name,
|
||||||
symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
|
Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
|
||||||
// normal interface method resolution
|
// normal interface method resolution
|
||||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||||
|
|
||||||
@ -883,8 +882,8 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
|||||||
// do lookup based on receiver klass
|
// do lookup based on receiver klass
|
||||||
methodHandle sel_method;
|
methodHandle sel_method;
|
||||||
lookup_instance_method_in_klasses(sel_method, recv_klass,
|
lookup_instance_method_in_klasses(sel_method, recv_klass,
|
||||||
symbolHandle(THREAD, resolved_method->name()),
|
resolved_method->name(),
|
||||||
symbolHandle(THREAD, resolved_method->signature()), CHECK);
|
resolved_method->signature(), CHECK);
|
||||||
// check if method exists
|
// check if method exists
|
||||||
if (sel_method.is_null()) {
|
if (sel_method.is_null()) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
@ -916,8 +915,8 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
|||||||
|
|
||||||
methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
|
methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
|
||||||
KlassHandle resolved_klass,
|
KlassHandle resolved_klass,
|
||||||
symbolHandle method_name,
|
Symbol* method_name,
|
||||||
symbolHandle method_signature,
|
Symbol* method_signature,
|
||||||
KlassHandle current_klass,
|
KlassHandle current_klass,
|
||||||
bool check_access) {
|
bool check_access) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
@ -933,8 +932,8 @@ methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
|
|||||||
|
|
||||||
methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
|
methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
|
||||||
KlassHandle resolved_klass,
|
KlassHandle resolved_klass,
|
||||||
symbolHandle method_name,
|
Symbol* method_name,
|
||||||
symbolHandle method_signature,
|
Symbol* method_signature,
|
||||||
KlassHandle current_klass,
|
KlassHandle current_klass,
|
||||||
bool check_access) {
|
bool check_access) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
@ -951,8 +950,8 @@ methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
|
|||||||
methodHandle LinkResolver::resolve_virtual_call_or_null(
|
methodHandle LinkResolver::resolve_virtual_call_or_null(
|
||||||
KlassHandle receiver_klass,
|
KlassHandle receiver_klass,
|
||||||
KlassHandle resolved_klass,
|
KlassHandle resolved_klass,
|
||||||
symbolHandle name,
|
Symbol* name,
|
||||||
symbolHandle signature,
|
Symbol* signature,
|
||||||
KlassHandle current_klass) {
|
KlassHandle current_klass) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
CallInfo info;
|
CallInfo info;
|
||||||
@ -967,8 +966,8 @@ methodHandle LinkResolver::resolve_virtual_call_or_null(
|
|||||||
methodHandle LinkResolver::resolve_interface_call_or_null(
|
methodHandle LinkResolver::resolve_interface_call_or_null(
|
||||||
KlassHandle receiver_klass,
|
KlassHandle receiver_klass,
|
||||||
KlassHandle resolved_klass,
|
KlassHandle resolved_klass,
|
||||||
symbolHandle name,
|
Symbol* name,
|
||||||
symbolHandle signature,
|
Symbol* signature,
|
||||||
KlassHandle current_klass) {
|
KlassHandle current_klass) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
CallInfo info;
|
CallInfo info;
|
||||||
@ -983,8 +982,8 @@ methodHandle LinkResolver::resolve_interface_call_or_null(
|
|||||||
int LinkResolver::resolve_virtual_vtable_index(
|
int LinkResolver::resolve_virtual_vtable_index(
|
||||||
KlassHandle receiver_klass,
|
KlassHandle receiver_klass,
|
||||||
KlassHandle resolved_klass,
|
KlassHandle resolved_klass,
|
||||||
symbolHandle name,
|
Symbol* name,
|
||||||
symbolHandle signature,
|
Symbol* signature,
|
||||||
KlassHandle current_klass) {
|
KlassHandle current_klass) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
CallInfo info;
|
CallInfo info;
|
||||||
@ -998,8 +997,8 @@ int LinkResolver::resolve_virtual_vtable_index(
|
|||||||
|
|
||||||
methodHandle LinkResolver::resolve_static_call_or_null(
|
methodHandle LinkResolver::resolve_static_call_or_null(
|
||||||
KlassHandle resolved_klass,
|
KlassHandle resolved_klass,
|
||||||
symbolHandle name,
|
Symbol* name,
|
||||||
symbolHandle signature,
|
Symbol* signature,
|
||||||
KlassHandle current_klass) {
|
KlassHandle current_klass) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
CallInfo info;
|
CallInfo info;
|
||||||
@ -1011,7 +1010,7 @@ methodHandle LinkResolver::resolve_static_call_or_null(
|
|||||||
return info.selected_method();
|
return info.selected_method();
|
||||||
}
|
}
|
||||||
|
|
||||||
methodHandle LinkResolver::resolve_special_call_or_null(KlassHandle resolved_klass, symbolHandle name, symbolHandle signature,
|
methodHandle LinkResolver::resolve_special_call_or_null(KlassHandle resolved_klass, Symbol* name, Symbol* signature,
|
||||||
KlassHandle current_klass) {
|
KlassHandle current_klass) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
CallInfo info;
|
CallInfo info;
|
||||||
@ -1039,22 +1038,22 @@ void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHan
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkResolver::resolve_pool(KlassHandle& resolved_klass, symbolHandle& method_name, symbolHandle& method_signature,
|
void LinkResolver::resolve_pool(KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature,
|
||||||
KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) {
|
KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) {
|
||||||
// resolve klass
|
// resolve klass
|
||||||
resolve_klass(resolved_klass, pool, index, CHECK);
|
resolve_klass(resolved_klass, pool, index, CHECK);
|
||||||
|
|
||||||
// Get name, signature, and static klass
|
// Get name, signature, and static klass
|
||||||
method_name = symbolHandle(THREAD, pool->name_ref_at(index));
|
method_name = pool->name_ref_at(index);
|
||||||
method_signature = symbolHandle(THREAD, pool->signature_ref_at(index));
|
method_signature = pool->signature_ref_at(index);
|
||||||
current_klass = KlassHandle(THREAD, pool->pool_holder());
|
current_klass = KlassHandle(THREAD, pool->pool_holder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
|
void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
|
||||||
KlassHandle resolved_klass;
|
KlassHandle resolved_klass;
|
||||||
symbolHandle method_name;
|
Symbol* method_name = NULL;
|
||||||
symbolHandle method_signature;
|
Symbol* method_signature = NULL;
|
||||||
KlassHandle current_klass;
|
KlassHandle current_klass;
|
||||||
resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
|
resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
|
||||||
resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
|
resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
|
||||||
@ -1063,8 +1062,8 @@ void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle poo
|
|||||||
|
|
||||||
void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
|
void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
|
||||||
KlassHandle resolved_klass;
|
KlassHandle resolved_klass;
|
||||||
symbolHandle method_name;
|
Symbol* method_name = NULL;
|
||||||
symbolHandle method_signature;
|
Symbol* method_signature = NULL;
|
||||||
KlassHandle current_klass;
|
KlassHandle current_klass;
|
||||||
resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
|
resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
|
||||||
resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
||||||
@ -1076,8 +1075,8 @@ void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
|
|||||||
TRAPS) {
|
TRAPS) {
|
||||||
|
|
||||||
KlassHandle resolved_klass;
|
KlassHandle resolved_klass;
|
||||||
symbolHandle method_name;
|
Symbol* method_name = NULL;
|
||||||
symbolHandle method_signature;
|
Symbol* method_signature = NULL;
|
||||||
KlassHandle current_klass;
|
KlassHandle current_klass;
|
||||||
resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
|
resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
|
||||||
KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
|
KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
|
||||||
@ -1087,8 +1086,8 @@ void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
|
|||||||
|
|
||||||
void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
|
void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
|
||||||
KlassHandle resolved_klass;
|
KlassHandle resolved_klass;
|
||||||
symbolHandle method_name;
|
Symbol* method_name = NULL;
|
||||||
symbolHandle method_signature;
|
Symbol* method_signature = NULL;
|
||||||
KlassHandle current_klass;
|
KlassHandle current_klass;
|
||||||
resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
|
resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
|
||||||
KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
|
KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
|
||||||
@ -1102,8 +1101,8 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
|
|||||||
// This guy is reached from InterpreterRuntime::resolve_invokedynamic.
|
// This guy is reached from InterpreterRuntime::resolve_invokedynamic.
|
||||||
|
|
||||||
// At this point, we only need the signature, and can ignore the name.
|
// At this point, we only need the signature, and can ignore the name.
|
||||||
symbolHandle method_signature(THREAD, pool->signature_ref_at(raw_index)); // raw_index works directly
|
Symbol* method_signature = pool->signature_ref_at(raw_index); // raw_index works directly
|
||||||
symbolHandle method_name = vmSymbolHandles::invokeExact_name();
|
Symbol* method_name = vmSymbols::invokeExact_name();
|
||||||
KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
|
KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
|
||||||
|
|
||||||
// JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...)
|
// JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...)
|
||||||
|
@ -45,17 +45,17 @@ class LinkInfo VALUE_OBJ_CLASS_SPEC {
|
|||||||
class FieldAccessInfo: public LinkInfo {
|
class FieldAccessInfo: public LinkInfo {
|
||||||
protected:
|
protected:
|
||||||
KlassHandle _klass;
|
KlassHandle _klass;
|
||||||
symbolHandle _name;
|
Symbol* _name;
|
||||||
AccessFlags _access_flags;
|
AccessFlags _access_flags;
|
||||||
int _field_index; // original index in the klass
|
int _field_index; // original index in the klass
|
||||||
int _field_offset;
|
int _field_offset;
|
||||||
BasicType _field_type;
|
BasicType _field_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set(KlassHandle klass, symbolHandle name, int field_index, int field_offset,
|
void set(KlassHandle klass, Symbol* name, int field_index, int field_offset,
|
||||||
BasicType field_type, AccessFlags access_flags);
|
BasicType field_type, AccessFlags access_flags);
|
||||||
KlassHandle klass() const { return _klass; }
|
KlassHandle klass() const { return _klass; }
|
||||||
symbolHandle name() const { return _name; }
|
Symbol* name() const { return _name; }
|
||||||
int field_index() const { return _field_index; }
|
int field_index() const { return _field_index; }
|
||||||
int field_offset() const { return _field_offset; }
|
int field_offset() const { return _field_offset; }
|
||||||
BasicType field_type() const { return _field_type; }
|
BasicType field_type() const { return _field_type; }
|
||||||
@ -107,26 +107,26 @@ class CallInfo: public LinkInfo {
|
|||||||
|
|
||||||
class LinkResolver: AllStatic {
|
class LinkResolver: AllStatic {
|
||||||
private:
|
private:
|
||||||
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||||
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||||
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||||
static void lookup_implicit_method (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature,
|
static void lookup_implicit_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
|
||||||
KlassHandle current_klass, TRAPS);
|
KlassHandle current_klass, TRAPS);
|
||||||
|
|
||||||
static int vtable_index_of_miranda_method(KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||||
|
|
||||||
static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS);
|
static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS);
|
||||||
static void resolve_klass_no_update (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); // no update of constantPool entry
|
static void resolve_klass_no_update (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); // no update of constantPool entry
|
||||||
|
|
||||||
static void resolve_pool (KlassHandle& resolved_klass, symbolHandle& method_name, symbolHandle& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
|
static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
|
||||||
|
|
||||||
static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||||
static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||||
|
|
||||||
static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||||
static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||||
static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature,KlassHandle current_klass, bool check_access, TRAPS);
|
static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature,KlassHandle current_klass, bool check_access, TRAPS);
|
||||||
static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||||
|
|
||||||
static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS);
|
static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS);
|
||||||
static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
|
static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
|
||||||
@ -152,24 +152,24 @@ class LinkResolver: AllStatic {
|
|||||||
// runtime resolving:
|
// runtime resolving:
|
||||||
// resolved_klass = specified class (i.e., static receiver class)
|
// resolved_klass = specified class (i.e., static receiver class)
|
||||||
// current_klass = sending method holder (i.e., class containing the method containing the call being resolved)
|
// current_klass = sending method holder (i.e., class containing the method containing the call being resolved)
|
||||||
static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS);
|
static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS);
|
||||||
static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||||
static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
|
static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
|
||||||
static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
|
static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
|
||||||
|
|
||||||
// same as above for compile-time resolution; but returns null handle instead of throwing an exception on error
|
// same as above for compile-time resolution; but returns null handle instead of throwing an exception on error
|
||||||
// also, does not initialize klass (i.e., no side effects)
|
// also, does not initialize klass (i.e., no side effects)
|
||||||
static methodHandle resolve_virtual_call_or_null (KlassHandle receiver_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass);
|
static methodHandle resolve_virtual_call_or_null (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass);
|
||||||
static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass);
|
static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass);
|
||||||
static methodHandle resolve_static_call_or_null (KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass);
|
static methodHandle resolve_static_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass);
|
||||||
static methodHandle resolve_special_call_or_null (KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass);
|
static methodHandle resolve_special_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass);
|
||||||
|
|
||||||
// same as above for compile-time resolution; returns vtable_index if current_klass if linked
|
// same as above for compile-time resolution; returns vtable_index if current_klass if linked
|
||||||
static int resolve_virtual_vtable_index (KlassHandle receiver_klass, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass);
|
static int resolve_virtual_vtable_index (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass);
|
||||||
|
|
||||||
// static resolving for compiler (does not throw exceptions, returns null handle if unsuccessful)
|
// static resolving for compiler (does not throw exceptions, returns null handle if unsuccessful)
|
||||||
static methodHandle linktime_resolve_virtual_method_or_null (KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access);
|
static methodHandle linktime_resolve_virtual_method_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access);
|
||||||
static methodHandle linktime_resolve_interface_method_or_null(KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access);
|
static methodHandle linktime_resolve_interface_method_or_null(KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access);
|
||||||
|
|
||||||
// runtime resolving from constant pool
|
// runtime resolving from constant pool
|
||||||
static void resolve_invokestatic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
static void resolve_invokestatic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user