提交 4994604f 编写于 作者: C coleenp

6990754: Use native memory and reference counting to implement SymbolTable

Summary: move symbols from permgen into C heap and reference count them
Reviewed-by: never, acorn, jmasa, stefank
上级 a3afdf82
......@@ -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) {
public void doit(Tokens t) {
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) {
public void doit(Tokens t) {
if (t.countTokens() > 1) {
......@@ -1262,6 +1281,9 @@ public class CommandProcessor {
this.err = err;
for (int i = 0; i < commandList.length; i++) {
Command c = commandList[i];
if (commands.get(c.name) != null) {
throw new InternalError(c.name + " has multiple definitions");
}
commands.put(c.name, c);
}
if (debugger.isAttached()) {
......
......@@ -89,6 +89,37 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
readVMLongConstants();
}
public Type lookupType(String cTypeName, boolean throwException) {
Type fieldType = super.lookupType(cTypeName, false);
if (fieldType == null && cTypeName.startsWith("const ")) {
fieldType = (BasicType)lookupType(cTypeName.substring(6), false);
}
if (fieldType == null && cTypeName.endsWith(" const")) {
fieldType = (BasicType)lookupType(cTypeName.substring(0, cTypeName.length() - 6), false);
}
if (fieldType == null) {
if (cTypeName.startsWith("GrowableArray<") && cTypeName.endsWith(">*")) {
String ttype = cTypeName.substring("GrowableArray<".length(),
cTypeName.length() - 2);
Type templateType = lookupType(ttype, false);
if (templateType == null && typeNameIsPointerType(ttype)) {
templateType = recursiveCreateBasicPointerType(ttype);
}
if (templateType == null) {
lookupOrFail(ttype);
}
fieldType = recursiveCreateBasicPointerType(cTypeName);
}
}
if (fieldType == null && typeNameIsPointerType(cTypeName)) {
fieldType = recursiveCreateBasicPointerType(cTypeName);
}
if (fieldType == null && throwException) {
super.lookupType(cTypeName, true);
}
return fieldType;
}
private void readVMTypes() {
// Get the variables we need in order to traverse the VMTypeEntry[]
long typeEntryTypeNameOffset;
......@@ -250,7 +281,7 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
BasicType containingType = lookupOrFail(typeName);
// The field's Type must already be in the database -- no exceptions
BasicType fieldType = lookupOrFail(typeString);
BasicType fieldType = (BasicType)lookupType(typeString);
// Create field by type
createField(containingType, fieldName, fieldType,
......@@ -442,10 +473,17 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
workarounds due to incomplete information in the VMStructs
database. */
private BasicPointerType recursiveCreateBasicPointerType(String typeName) {
BasicPointerType result = (BasicPointerType)super.lookupType(typeName, false);
if (result != null) {
return result;
}
String targetTypeName = typeName.substring(0, typeName.lastIndexOf('*')).trim();
Type targetType = null;
if (typeNameIsPointerType(targetTypeName)) {
targetType = recursiveCreateBasicPointerType(targetTypeName);
targetType = lookupType(targetTypeName, false);
if (targetType == null) {
targetType = recursiveCreateBasicPointerType(targetTypeName);
}
} else {
targetType = lookupType(targetTypeName, false);
if (targetType == null) {
......@@ -466,6 +504,20 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
BasicType basicTargetType = createBasicType(targetTypeName, false, true, true);
basicTargetType.setSize(1);
targetType = basicTargetType;
} else if (targetTypeName.startsWith("GrowableArray<")) {
BasicType basicTargetType = createBasicType(targetTypeName, false, false, false);
// transfer fields from GenericGrowableArray to template instance
BasicType generic = lookupOrFail("GenericGrowableArray");
basicTargetType.setSize(generic.getSize());
Iterator fields = generic.getFields();
while (fields.hasNext()) {
Field f = (Field)fields.next();
basicTargetType.addField(internalCreateField(basicTargetType, f.getName(),
f.getType(), f.isStatic(),
f.getOffset(), null));
}
targetType = basicTargetType;
} else {
if (DEBUG) {
System.err.println("WARNING: missing target type \"" + targetTypeName + "\" for pointer type \"" + typeName + "\"");
......@@ -474,7 +526,10 @@ 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) {
......
......@@ -112,7 +112,7 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
}
// return Symbol (if unresolved) or Klass (if resolved)
public Oop getKlass() {
public Object getKlass() {
if (Assert.ASSERTS_ENABLED) {
Assert.that(isKlassConstant(), "not a klass literal");
}
......@@ -121,11 +121,11 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
// decide based on the oop type.
ConstantPool cpool = method().getConstants();
int cpIndex = index();
Oop oop = cpool.getObjAt(cpIndex);
if (oop.isKlass()) {
return (Klass) oop;
} else if (oop.isSymbol()) {
return (Symbol) oop;
ConstantPool.CPSlot oop = cpool.getSlotAt(cpIndex);
if (oop.isOop()) {
return (Klass) oop.getOop();
} else if (oop.isMetaData()) {
return oop.getSymbol();
} else {
throw new RuntimeException("should not reach here");
}
......@@ -165,12 +165,12 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
// tag change from 'unresolved' to 'string' does not happen atomically.
// We just look at the object at the corresponding index and
// decide based on the oop type.
Oop obj = cpool.getObjAt(cpIndex);
if (obj.isSymbol()) {
Symbol sym = (Symbol) obj;
return "<String \"" + sym.asString() + "\">";
} else if (obj.isInstance()) {
return "<String \"" + OopUtilities.stringOopToString(obj) + "\">";
ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
if (obj.isMetaData()) {
Symbol sym = obj.getSymbol();
return "<String \"" + sym.asString() + "\">";
} else if (obj.isOop()) {
return "<String \"" + OopUtilities.stringOopToString(obj.getOop()) + "\">";
} else {
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.
// We just look at the object at the corresponding index and
// decide based on the oop type.
Oop obj = cpool.getObjAt(cpIndex);
if (obj.isKlass()) {
Klass k = (Klass) obj;
return "<Class " + k.getName().asString() + "@" + k.getHandle() + ">";
} else if (obj.isSymbol()) {
Symbol sym = (Symbol) obj;
return "<Class " + sym.asString() + ">";
ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
if (obj.isOop()) {
Klass k = (Klass) obj.getOop();
return "<Class " + k.getName().asString() + "@" + k.getHandle() + ">";
} else if (obj.isMetaData()) {
Symbol sym = obj.getSymbol();
return "<Class " + sym.asString() + ">";
} else {
throw new RuntimeException("should not reach here");
}
......
......@@ -37,11 +37,11 @@ public class BytecodeWithKlass extends BytecodeWithCPIndex {
}
public Symbol getClassName() {
Oop obj = method().getConstants().getObjAt(index());
if (obj instanceof Symbol) {
return (Symbol)obj;
ConstantPool.CPSlot obj = method().getConstants().getSlotAt(index());
if (obj.isMetaData()) {
return obj.getSymbol();
} else {
return ((Klass)obj).getName();
return ((Klass)obj.getOop()).getName();
}
}
......
......@@ -63,7 +63,7 @@ public class DictionaryEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
}
public Klass klass() {
return (Klass) literal();
return (Klass)VM.getVM().getObjectHeap().newOop(literalValue().addOffsetToAsOopHandle(0));
}
public DictionaryEntry(Address addr) {
......
......@@ -42,14 +42,14 @@ public class LoaderConstraintEntry extends sun.jvm.hotspot.utilities.HashtableEn
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("LoaderConstraintEntry");
nameField = type.getOopField("_name");
nameField = type.getAddressField("_name");
numLoadersField = type.getCIntegerField("_num_loaders");
maxLoadersField = type.getCIntegerField("_max_loaders");
loadersField = type.getAddressField("_loaders");
}
// Fields
private static sun.jvm.hotspot.types.OopField nameField;
private static AddressField nameField;
private static CIntegerField numLoadersField;
private static CIntegerField maxLoadersField;
private static AddressField loadersField;
......@@ -57,7 +57,7 @@ public class LoaderConstraintEntry extends sun.jvm.hotspot.utilities.HashtableEn
// Accessors
public Symbol name() {
return (Symbol) VM.getVM().getObjectHeap().newOop(nameField.getValue(addr));
return Symbol.create(nameField.getValue(addr));
}
public int numLoaders() {
......
......@@ -58,7 +58,7 @@ public class PlaceholderEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
}
public Symbol klass() {
return (Symbol) literal();
return Symbol.create(literalValue());
}
/* covariant return type :-(
......
......@@ -70,11 +70,13 @@ public class StringTable extends sun.jvm.hotspot.utilities.Hashtable {
}
public void stringsDo(StringVisitor visitor) {
ObjectHeap oh = VM.getVM().getObjectHeap();
int numBuckets = tableSize();
for (int i = 0; i < numBuckets; i++) {
for (HashtableEntry e = (HashtableEntry) bucket(i); e != null;
e = (HashtableEntry) e.next()) {
visitor.visit((Instance) e.literal());
Instance s = (Instance)oh.newOop(e.literalValue().addOffsetToAsOopHandle(0));
visitor.visit(s);
}
}
}
......
......@@ -85,7 +85,7 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
long hashValue = hashSymbol(name);
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
if (e.hash() == hashValue) {
Symbol sym = (Symbol) e.literal();
Symbol sym = Symbol.create(e.literalValue());
if (sym.equals(name)) {
return sym;
}
......@@ -103,7 +103,7 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
for (int i = 0; i < numBuckets; i++) {
for (HashtableEntry e = (HashtableEntry) bucket(i); e != null;
e = (HashtableEntry) e.next()) {
visitor.visit((Symbol) e.literal());
visitor.visit(Symbol.create(e.literalValue()));
}
}
}
......
......@@ -35,6 +35,38 @@ import sun.jvm.hotspot.utilities.*;
// as described in the class file
public class ConstantPool extends Oop implements ClassConstants {
public class CPSlot {
private Address ptr;
CPSlot(Address ptr) {
this.ptr = ptr;
}
CPSlot(Symbol sym) {
this.ptr = sym.getAddress().orWithMask(1);
}
public boolean isOop() {
return (ptr.minus(null) & 1) == 0;
}
public boolean isMetaData() {
return (ptr.minus(null) & 1) == 1;
}
public Symbol getSymbol() {
if (isMetaData()) {
return Symbol.create(ptr.xorWithMask(1));
}
throw new InternalError("not a symbol");
}
public Oop getOop() {
if (isOop()) {
return VM.getVM().getObjectHeap().newOop(ptr.addOffsetToAsOopHandle(0));
}
throw new InternalError("not an oop");
}
}
// Used for debugging this code
private static final boolean DEBUG = false;
......@@ -110,12 +142,17 @@ public class ConstantPool extends Oop implements ClassConstants {
return new ConstantTag(getTags().getByteAt((int) index));
}
public Oop getObjAt(long index){
public CPSlot getSlotAt(long index) {
return new CPSlot(getHandle().getAddressAt(indexOffset(index)));
}
public Oop getObjAtRaw(long index){
return getHeap().newOop(getHandle().getOopHandleAt(indexOffset(index)));
}
public Symbol getSymbolAt(long index) {
return (Symbol) getObjAt(index);
CPSlot slot = getSlotAt(index);
return slot.getSymbol();
}
public int getIntAt(long index){
......@@ -187,7 +224,7 @@ public class ConstantPool extends Oop implements ClassConstants {
// returns null, if not resolved.
public Klass getKlassRefAt(int which) {
if( ! getTagAt(which).isKlass()) return null;
return (Klass) getObjAt(which);
return (Klass) getObjAtRaw(which);
}
// returns null, if not resolved.
......@@ -477,7 +514,7 @@ public class ConstantPool extends Oop implements ClassConstants {
case JVM_CONSTANT_Class: {
dos.writeByte(cpConstType);
// Klass already resolved. ConstantPool constains klassOop.
Klass refKls = (Klass) getObjAt(ci);
Klass refKls = (Klass) getObjAtRaw(ci);
String klassName = refKls.getName().asString();
Short s = (Short) utf8ToIndex.get(klassName);
dos.writeShort(s.shortValue());
......@@ -498,7 +535,7 @@ public class ConstantPool extends Oop implements ClassConstants {
case JVM_CONSTANT_String: {
dos.writeByte(cpConstType);
String str = OopUtilities.stringOopToString(getObjAt(ci));
String str = OopUtilities.stringOopToString(getObjAtRaw(ci));
Short s = (Short) utf8ToIndex.get(str);
dos.writeShort(s.shortValue());
if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);
......
......@@ -576,7 +576,7 @@ public class GenerateOopMap {
ConstantPool cp = method().getConstants();
int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx);
int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx);
symbolOop signature = cp.symbol_at(signatureIdx);
Symbol* signature = cp.symbol_at(signatureIdx);
tty.print("%s", signature.as_C_string());
*/
}
......@@ -616,7 +616,7 @@ public class GenerateOopMap {
constantPoolOop cp = method().constants();
int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx);
int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx);
symbolOop signature = cp.symbol_at(signatureIdx);
Symbol* signature = cp.symbol_at(signatureIdx);
tty.print("%s", signature.as_C_string());
*/
}
......
......@@ -82,8 +82,8 @@ public class InstanceKlass extends Klass {
classLoader = new OopField(type.getOopField("_class_loader"), Oop.getHeaderSize());
protectionDomain = new OopField(type.getOopField("_protection_domain"), Oop.getHeaderSize());
signers = new OopField(type.getOopField("_signers"), Oop.getHeaderSize());
sourceFileName = new OopField(type.getOopField("_source_file_name"), Oop.getHeaderSize());
sourceDebugExtension = new OopField(type.getOopField("_source_debug_extension"), Oop.getHeaderSize());
sourceFileName = type.getAddressField("_source_file_name");
sourceDebugExtension = type.getAddressField("_source_debug_extension");
innerClasses = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize());
nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize());
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
......@@ -94,7 +94,7 @@ public class InstanceKlass extends Klass {
vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize());
itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize());
breakpoints = type.getAddressField("_breakpoints");
genericSignature = new OopField(type.getOopField("_generic_signature"), Oop.getHeaderSize());
genericSignature = type.getAddressField("_generic_signature");
majorVersion = new CIntField(type.getCIntegerField("_major_version"), Oop.getHeaderSize());
minorVersion = new CIntField(type.getCIntegerField("_minor_version"), Oop.getHeaderSize());
headerSize = alignObjectOffset(Oop.getHeaderSize() + type.getSize());
......@@ -135,8 +135,8 @@ public class InstanceKlass extends Klass {
private static OopField classLoader;
private static OopField protectionDomain;
private static OopField signers;
private static OopField sourceFileName;
private static OopField sourceDebugExtension;
private static AddressField sourceFileName;
private static AddressField sourceDebugExtension;
private static OopField innerClasses;
private static CIntField nonstaticFieldSize;
private static CIntField staticFieldSize;
......@@ -147,7 +147,7 @@ public class InstanceKlass extends Klass {
private static CIntField vtableLen;
private static CIntField itableLen;
private static AddressField breakpoints;
private static OopField genericSignature;
private static AddressField genericSignature;
private static CIntField majorVersion;
private static CIntField minorVersion;
......@@ -257,8 +257,8 @@ public class InstanceKlass extends Klass {
public Oop getClassLoader() { return classLoader.getValue(this); }
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
public Symbol getSourceFileName() { return (Symbol) sourceFileName.getValue(this); }
public Symbol getSourceDebugExtension(){ return (Symbol) sourceDebugExtension.getValue(this); }
public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
public Symbol getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); }
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
public long getStaticFieldSize() { return staticFieldSize.getValue(this); }
......@@ -267,7 +267,7 @@ public class InstanceKlass extends Klass {
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
public long getVtableLen() { return vtableLen.getValue(this); }
public long getItableLen() { return itableLen.getValue(this); }
public Symbol getGenericSignature() { return (Symbol) genericSignature.getValue(this); }
public Symbol getGenericSignature() { return getSymbol(genericSignature); }
public long majorVersion() { return majorVersion.getValue(this); }
public long minorVersion() { return minorVersion.getValue(this); }
......@@ -308,12 +308,12 @@ public class InstanceKlass extends Klass {
if (ioff != 0) {
// only look at classes that are already loaded
// since we are looking for the flags for our self.
Oop classInfo = getConstants().getObjAt(ioff);
ConstantPool.CPSlot classInfo = getConstants().getSlotAt(ioff);
Symbol name = null;
if (classInfo instanceof Klass) {
name = ((Klass) classInfo).getName();
} else if (classInfo instanceof Symbol) {
name = (Symbol) classInfo;
if (classInfo.isOop()) {
name = ((Klass) classInfo.getOop()).getName();
} else if (classInfo.isMetaData()) {
name = classInfo.getSymbol();
} else {
throw new RuntimeException("should not reach here");
}
......@@ -358,12 +358,12 @@ public class InstanceKlass extends Klass {
// 'ioff' can be zero.
// refer to JVM spec. section 4.7.5.
if (ioff != 0) {
Oop iclassInfo = getConstants().getObjAt(ioff);
ConstantPool.CPSlot iclassInfo = getConstants().getSlotAt(ioff);
Symbol innerName = null;
if (iclassInfo instanceof Klass) {
innerName = ((Klass) iclassInfo).getName();
} else if (iclassInfo instanceof Symbol) {
innerName = (Symbol) iclassInfo;
if (iclassInfo.isOop()) {
innerName = ((Klass) iclassInfo.getOop()).getName();
} else if (iclassInfo.isMetaData()) {
innerName = iclassInfo.getSymbol();
} else {
throw new RuntimeException("should not reach here");
}
......@@ -387,12 +387,12 @@ public class InstanceKlass extends Klass {
}
}
} else {
Oop oclassInfo = getConstants().getObjAt(ooff);
ConstantPool.CPSlot oclassInfo = getConstants().getSlotAt(ooff);
Symbol outerName = null;
if (oclassInfo instanceof Klass) {
outerName = ((Klass) oclassInfo).getName();
} else if (oclassInfo instanceof Symbol) {
outerName = (Symbol) oclassInfo;
if (oclassInfo.isOop()) {
outerName = ((Klass) oclassInfo.getOop()).getName();
} else if (oclassInfo.isMetaData()) {
outerName = oclassInfo.getSymbol();
} else {
throw new RuntimeException("should not reach here");
}
......@@ -450,7 +450,6 @@ public class InstanceKlass extends Klass {
visitor.doOop(classLoader, true);
visitor.doOop(protectionDomain, true);
visitor.doOop(signers, true);
visitor.doOop(sourceFileName, true);
visitor.doOop(innerClasses, true);
visitor.doCInt(nonstaticFieldSize, true);
visitor.doCInt(staticFieldSize, true);
......@@ -467,7 +466,7 @@ public class InstanceKlass extends Klass {
for (int index = 0; index < length; index += NEXT_OFFSET) {
short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET);
short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET);
FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex));
FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex));
AccessFlags access = new AccessFlags(accessFlags);
if (access.isStatic()) {
visitField(visitor, type, index);
......@@ -490,7 +489,7 @@ public class InstanceKlass extends Klass {
short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET);
short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET);
FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex));
FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex));
AccessFlags access = new AccessFlags(accessFlags);
if (!access.isStatic()) {
visitField(visitor, type, index);
......@@ -787,7 +786,7 @@ public class InstanceKlass extends Klass {
private Field newField(int index) {
TypeArray fields = getFields();
short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET);
FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex));
FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex));
if (type.isOop()) {
if (VM.getVM().isCompressedOopsEnabled()) {
return new NarrowOopField(this, index);
......
......@@ -53,7 +53,7 @@ public class Klass extends Oop implements ClassConstants {
javaMirror = new OopField(type.getOopField("_java_mirror"), Oop.getHeaderSize());
superField = new OopField(type.getOopField("_super"), Oop.getHeaderSize());
layoutHelper = new IntField(type.getJIntField("_layout_helper"), Oop.getHeaderSize());
name = new OopField(type.getOopField("_name"), Oop.getHeaderSize());
name = type.getAddressField("_name");
accessFlags = new CIntField(type.getCIntegerField("_access_flags"), Oop.getHeaderSize());
subklass = new OopField(type.getOopField("_subklass"), Oop.getHeaderSize());
nextSibling = new OopField(type.getOopField("_next_sibling"), Oop.getHeaderSize());
......@@ -83,18 +83,26 @@ public class Klass extends Oop implements ClassConstants {
private static OopField javaMirror;
private static OopField superField;
private static IntField layoutHelper;
private static OopField name;
private static AddressField name;
private static CIntField accessFlags;
private static OopField subklass;
private static OopField nextSibling;
private static CIntField allocCount;
private Address getValue(AddressField field) {
return getHandle().getAddressAt(field.getOffset() + Oop.getHeaderSize());
}
protected Symbol getSymbol(AddressField field) {
return Symbol.create(getHandle().getAddressAt(field.getOffset() + Oop.getHeaderSize()));
}
// Accessors for declared fields
public Instance getJavaMirror() { return (Instance) javaMirror.getValue(this); }
public Klass getSuper() { return (Klass) superField.getValue(this); }
public Klass getJavaSuper() { return null; }
public int getLayoutHelper() { return (int) layoutHelper.getValue(this); }
public Symbol getName() { return (Symbol) name.getValue(this); }
public Symbol getName() { return getSymbol(name); }
public long getAccessFlags() { return accessFlags.getValue(this); }
// Convenience routine
public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); }
......@@ -162,7 +170,7 @@ public class Klass extends Oop implements ClassConstants {
visitor.doOop(javaMirror, true);
visitor.doOop(superField, true);
visitor.doInt(layoutHelper, true);
visitor.doOop(name, true);
// visitor.doOop(name, true);
visitor.doCInt(accessFlags, true);
visitor.doOop(subklass, true);
visitor.doOop(nextSibling, true);
......
......@@ -196,11 +196,11 @@ public class Method extends Oop {
public Address getFromCompiledCodeEntryPoint() { return fromCompiledCodeEntryPointField.getValue(this); }
*/
// Accessors
public Symbol getName() { return (Symbol) getConstants().getObjAt(getNameIndex()); }
public Symbol getSignature() { return (Symbol) getConstants().getObjAt(getSignatureIndex()); }
public Symbol getName() { return getConstants().getSymbolAt(getNameIndex()); }
public Symbol getSignature() { return getConstants().getSymbolAt(getSignatureIndex()); }
public Symbol getGenericSignature() {
long index = getGenericSignatureIndex();
return (index != 0L) ? (Symbol) getConstants().getObjAt(index) : null;
return (index != 0L) ? getConstants().getSymbolAt(index) : null;
}
// Method holder (the Klass holding this method)
......
......@@ -47,7 +47,6 @@ public class ObjectHeap {
DEBUG = System.getProperty("sun.jvm.hotspot.oops.ObjectHeap.DEBUG") != null;
}
private OopHandle symbolKlassHandle;
private OopHandle methodKlassHandle;
private OopHandle constMethodKlassHandle;
private OopHandle methodDataKlassHandle;
......@@ -68,7 +67,6 @@ public class ObjectHeap {
private OopHandle arrayKlassKlassHandle;
private OopHandle compiledICHolderKlassHandle;
private SymbolKlass symbolKlassObj;
private MethodKlass methodKlassObj;
private ConstMethodKlass constMethodKlassObj;
private MethodDataKlass methodDataKlassObj;
......@@ -93,9 +91,6 @@ public class ObjectHeap {
// Lookup the roots in the object hierarchy.
Type universeType = db.lookupType("Universe");
symbolKlassHandle = universeType.getOopField("_symbolKlassObj").getValue();
symbolKlassObj = new SymbolKlass(symbolKlassHandle, this);
methodKlassHandle = universeType.getOopField("_methodKlassObj").getValue();
methodKlassObj = new MethodKlass(methodKlassHandle, this);
......@@ -199,7 +194,6 @@ public class ObjectHeap {
public long getDoubleSize() { return doubleSize; }
// Accessors for well-known system classes (from Universe)
public SymbolKlass getSymbolKlassObj() { return symbolKlassObj; }
public MethodKlass getMethodKlassObj() { return methodKlassObj; }
public ConstMethodKlass getConstMethodKlassObj() { return constMethodKlassObj; }
public MethodDataKlass getMethodDataKlassObj() { return methodDataKlassObj; }
......@@ -337,7 +331,6 @@ public class ObjectHeap {
// First check if handle is one of the root objects
if (handle.equals(methodKlassHandle)) return getMethodKlassObj();
if (handle.equals(constMethodKlassHandle)) return getConstMethodKlassObj();
if (handle.equals(symbolKlassHandle)) return getSymbolKlassObj();
if (handle.equals(constantPoolKlassHandle)) return getConstantPoolKlassObj();
if (handle.equals(constantPoolCacheKlassHandle)) return getConstantPoolCacheKlassObj();
if (handle.equals(instanceKlassKlassHandle)) return getInstanceKlassKlassObj();
......@@ -363,7 +356,6 @@ public class ObjectHeap {
if (klass != null) {
if (klass.equals(methodKlassHandle)) return new Method(handle, this);
if (klass.equals(constMethodKlassHandle)) return new ConstMethod(handle, this);
if (klass.equals(symbolKlassHandle)) return new Symbol(handle, this);
if (klass.equals(constantPoolKlassHandle)) return new ConstantPool(handle, this);
if (klass.equals(constantPoolCacheKlassHandle)) return new ConstantPoolCache(handle, this);
if (!VM.getVM().isCore()) {
......
......@@ -34,7 +34,7 @@ import sun.jvm.hotspot.utilities.*;
// A Symbol is a canonicalized string.
// All Symbols reside in global symbolTable.
public class Symbol extends Oop {
public class Symbol extends VMObject {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
......@@ -44,9 +44,10 @@ public class Symbol extends Oop {
}
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("symbolOopDesc");
length = new CIntField(type.getCIntegerField("_length"), 0);
Type type = db.lookupType("Symbol");
length = type.getCIntegerField("_length");
baseOffset = type.getField("_body").getOffset();
idHash = type.getCIntegerField("_identity_hash");
}
// Format:
......@@ -55,8 +56,15 @@ public class Symbol extends Oop {
// [length] byte size of uft8 string
// ..body..
Symbol(OopHandle handle, ObjectHeap heap) {
super(handle, heap);
public static Symbol create(Address addr) {
if (addr == null) {
return null;
}
return new Symbol(addr);
}
Symbol(Address addr) {
super(addr);
}
public boolean isSymbol() { return true; }
......@@ -64,15 +72,19 @@ public class Symbol extends Oop {
private static long baseOffset; // tells where the array part starts
// Fields
private static CIntField length;
private static CIntegerField length;
// Accessors for declared fields
public long getLength() { return length.getValue(this); }
public long getLength() { return length.getValue(this.addr); }
public byte getByteAt(long index) {
return getHandle().getJByteAt(baseOffset + index);
return addr.getJByteAt(baseOffset + index);
}
private static CIntegerField idHash;
public int identityHash() { return (int)idHash.getValue(this.addr); }
public boolean equals(byte[] modUTF8Chars) {
int l = (int) getLength();
if (l != modUTF8Chars.length) return false;
......@@ -98,7 +110,9 @@ public class Symbol extends Oop {
// Decode the byte array and return the string.
try {
return readModifiedUTF8(asByteArray());
} catch(IOException e) {
} catch(Exception e) {
System.err.println(addr);
e.printStackTrace();
return null;
}
}
......@@ -111,28 +125,13 @@ public class Symbol extends Oop {
tty.print("#" + asString());
}
public long getObjectSize() {
return alignObjectSize(baseOffset + getLength());
}
void iterateFields(OopVisitor visitor, boolean doVMFields) {
super.iterateFields(visitor, doVMFields);
if (doVMFields) {
visitor.doCInt(length, true);
int length = (int) getLength();
for (int index = 0; index < length; index++) {
visitor.doByte(new ByteField(new IndexableFieldIdentifier(index), baseOffset + index, false), true);
}
}
}
/** Note: this comparison is used for vtable sorting only; it
doesn't matter what order it defines, as long as it is a total,
time-invariant order Since symbolOops are in permSpace, their
time-invariant order Since Symbol* are in C_HEAP, their
relative order in memory never changes, so use address
comparison for speed. */
public int fastCompare(Symbol other) {
return (int) getHandle().minus(other.getHandle());
return (int) addr.minus(other.addr);
}
private static String readModifiedUTF8(byte[] buf) throws IOException {
......
/*
* 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: {
dos.writeByte(cpConstType);
// Klass already resolved. ConstantPool constains klassOop.
Klass refKls = (Klass) cpool.getObjAt(ci);
Klass refKls = (Klass) cpool.getObjAtRaw(ci);
String klassName = refKls.getName().asString();
Short s = (Short) utf8ToIndex.get(klassName);
......@@ -255,7 +255,7 @@ public class ClassWriter implements /* imports */ ClassConstants
case JVM_CONSTANT_String: {
dos.writeByte(cpConstType);
String str = OopUtilities.stringOopToString(cpool.getObjAt(ci));
String str = OopUtilities.stringOopToString(cpool.getObjAtRaw(ci));
Short s = (Short) utf8ToIndex.get(str);
dos.writeShort(s.shortValue());
if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);
......
......@@ -56,7 +56,7 @@ import sun.jvm.hotspot.debugger.*;
</PRE>
FIXME: among other things, this interface is not sufficient to
describe fields which are themselves arrays (like symbolOop's
describe fields which are themselves arrays (like Symbol's
jbyte _body[1]). */
public interface Field {
/** Get the name of this field */
......
......@@ -530,7 +530,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
case JVM_CONSTANT_Class:
buf.cell("JVM_CONSTANT_Class");
Klass klass = (Klass) cpool.getObjAt(index);
Klass klass = (Klass) cpool.getObjAtRaw(index);
if (klass instanceof InstanceKlass) {
buf.cell(genKlassLink((InstanceKlass) klass));
} else {
......@@ -555,7 +555,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
case JVM_CONSTANT_String:
buf.cell("JVM_CONSTANT_String");
buf.cell("\"" +
escapeHTMLSpecialChars(OopUtilities.stringOopToString(cpool.getObjAt(index))) + "\"");
escapeHTMLSpecialChars(OopUtilities.stringOopToString(cpool.getObjAtRaw(index))) + "\"");
break;
case JVM_CONSTANT_Fieldref:
......@@ -672,11 +672,11 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
buf.beginTag("ul");
for (int exp = 0; exp < exceptions.length; exp++) {
short cpIndex = (short) exceptions[exp].getClassCPIndex();
Oop obj = cpool.getObjAt(cpIndex);
if (obj instanceof Symbol) {
buf.li(((Symbol)obj).asString().replace('/', '.'));
ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
if (obj.isMetaData()) {
buf.li((obj.getSymbol()).asString().replace('/', '.'));
} else {
buf.li(genKlassLink((InstanceKlass)obj));
buf.li(genKlassLink((InstanceKlass)obj.getOop()));
}
}
buf.endTag("ul");
......@@ -756,7 +756,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
} else if (instr instanceof BytecodeLoadConstant) {
BytecodeLoadConstant ldc = (BytecodeLoadConstant) instr;
if (ldc.isKlassConstant()) {
Oop oop = ldc.getKlass();
Object oop = ldc.getKlass();
if (oop instanceof Klass) {
buf.append("<a href='");
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 + 2)));
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) {
buf.cell("Any");
} else if (obj instanceof Symbol) {
buf.cell(((Symbol)obj).asString().replace('/', '.'));
} else if (obj.isMetaData()) {
buf.cell(obj.getSymbol().asString().replace('/', '.'));
} else {
buf.cell(genKlassLink((InstanceKlass)obj));
buf.cell(genKlassLink((InstanceKlass)obj.getOop()));
}
buf.endTag("tr");
}
......
......@@ -40,7 +40,7 @@ public class Hashtable extends BasicHashtable {
private static synchronized void initialize(TypeDataBase db) {
// 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>
......
......@@ -41,16 +41,16 @@ public class HashtableEntry extends BasicHashtableEntry {
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("HashtableEntry");
literalField = type.getOopField("_literal");
Type type = db.lookupType("HashtableEntry<intptr_t>");
literalField = type.getAddressField("_literal");
}
// Fields
private static OopField literalField;
private static AddressField literalField;
// Accessors
public Oop literal() {
return VM.getVM().getObjectHeap().newOop(literalField.getValue(addr));
public Address literalValue() {
return literalField.getValue(addr);
}
public HashtableEntry(Address addr) {
......
......@@ -740,7 +740,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
for (Iterator itr = fields.iterator(); itr.hasNext();) {
Field field = (Field) itr.next();
Symbol name = symTbl.probe(field.getID().getName());
writeObjectID(name);
writeSymbolID(name);
char typeCode = (char) field.getSignature().getByteAt(0);
int kind = signatureToHprofKind(typeCode);
out.writeByte((byte)kind);
......@@ -852,7 +852,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
private void writeSymbol(Symbol sym) throws IOException {
byte[] buf = sym.asString().getBytes("UTF-8");
writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE);
writeObjectID(sym);
writeSymbolID(sym);
out.write(buf);
}
......@@ -869,7 +869,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
out.writeInt(serialNum);
writeObjectID(clazz);
out.writeInt(DUMMY_STACK_TRACE_ID);
writeObjectID(k.getName());
writeSymbolID(k.getName());
serialNum++;
} catch (IOException exp) {
throw new RuntimeException(exp);
......@@ -901,6 +901,10 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
writeObjectID(address);
}
private void writeSymbolID(Symbol sym) throws IOException {
writeObjectID(getAddressValue(sym.getAddress()));
}
private void writeObjectID(long address) throws IOException {
if (OBJ_ID_SIZE == 4) {
out.writeInt((int) address);
......
......@@ -2541,7 +2541,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
in_sig_bt[i++] = bt; // Collect remaining bits of signature
out_sig_bt[total_c_args++] = bt;
if( bt == T_OBJECT) {
symbolOop s = ss.as_symbol_or_null();
Symbol* s = ss.as_symbol_or_null();
if (s == vmSymbols::java_lang_String()) {
total_strings++;
out_sig_bt[total_c_args-1] = T_ADDRESS;
......
......@@ -1974,7 +1974,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
in_sig_bt[i++] = bt; // Collect remaining bits of signature
out_sig_bt[total_c_args++] = bt;
if( bt == T_OBJECT) {
symbolOop s = ss.as_symbol_or_null();
Symbol* s = ss.as_symbol_or_null(); // symbol is created
if (s == vmSymbols::java_lang_String()) {
total_strings++;
out_sig_bt[total_c_args-1] = T_ADDRESS;
......
......@@ -1980,7 +1980,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm,
in_sig_bt[i++] = bt; // Collect remaining bits of signature
out_sig_bt[total_c_args++] = bt;
if( bt == T_OBJECT) {
symbolOop s = ss.as_symbol_or_null();
Symbol* s = ss.as_symbol_or_null(); // symbol is created
if (s == vmSymbols::java_lang_String()) {
total_strings++;
out_sig_bt[total_c_args-1] = T_ADDRESS;
......
......@@ -49,7 +49,7 @@
#include "oops/klass.hpp"
#include "oops/methodOop.hpp"
#include "oops/oop.hpp"
#include "oops/symbolOop.hpp"
#include "oops/symbol.hpp"
#include "runtime/virtualspace.hpp"
#include "runtime/vmStructs.hpp"
#include "utilities/accessFlags.hpp"
......@@ -215,8 +215,8 @@ int generateJvmOffsets(GEN_variant gen_variant) {
GEN_VALUE(AccessFlags_NATIVE, JVM_ACC_NATIVE);
GEN_VALUE(constMethodOopDesc_has_linenumber_table, constMethodOopDesc::_has_linenumber_table);
GEN_OFFS(AccessFlags, _flags);
GEN_OFFS(symbolOopDesc, _length);
GEN_OFFS(symbolOopDesc, _body);
GEN_OFFS(Symbol, _length);
GEN_OFFS(Symbol, _body);
printf("\n");
GEN_OFFS(methodOopDesc, _constMethod);
......
......@@ -114,8 +114,8 @@ dtrace:helper:ustack:
copyin_offset(OFFSET_HeapBlockHeader_used);
copyin_offset(OFFSET_oopDesc_metadata);
copyin_offset(OFFSET_symbolOopDesc_length);
copyin_offset(OFFSET_symbolOopDesc_body);
copyin_offset(OFFSET_Symbol_length);
copyin_offset(OFFSET_Symbol_body);
copyin_offset(OFFSET_methodOopDesc_constMethod);
copyin_offset(OFFSET_methodOopDesc_constants);
......@@ -366,13 +366,13 @@ dtrace:helper:ustack:
this->nameIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
this->nameSymbolLength = copyin_uint16(this->nameSymbol +
OFFSET_symbolOopDesc_length);
OFFSET_Symbol_length);
this->signatureSymbol = copyin_ptr(this->constantPool +
this->signatureIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
OFFSET_symbolOopDesc_length);
OFFSET_Symbol_length);
this->klassPtr = copyin_ptr(this->constantPool +
OFFSET_constantPoolOopDesc_pool_holder);
......@@ -381,7 +381,7 @@ dtrace:helper:ustack:
OFFSET_Klass_name + SIZE_oopDesc);
this->klassSymbolLength = copyin_uint16(this->klassSymbol +
OFFSET_symbolOopDesc_length);
OFFSET_Symbol_length);
/*
* Enough for three strings, plus the '.', plus the trailing '\0'.
......@@ -390,7 +390,7 @@ dtrace:helper:ustack:
this->nameSymbolLength +
this->signatureSymbolLength + 2 + 1);
copyinto(this->klassSymbol + OFFSET_symbolOopDesc_body,
copyinto(this->klassSymbol + OFFSET_Symbol_body,
this->klassSymbolLength, this->result);
/*
......@@ -398,11 +398,11 @@ dtrace:helper:ustack:
*/
this->result[this->klassSymbolLength] = '.';
copyinto(this->nameSymbol + OFFSET_symbolOopDesc_body,
copyinto(this->nameSymbol + OFFSET_Symbol_body,
this->nameSymbolLength,
this->result + this->klassSymbolLength + 1);
copyinto(this->signatureSymbol + OFFSET_symbolOopDesc_body,
copyinto(this->signatureSymbol + OFFSET_Symbol_body,
this->signatureSymbolLength,
this->result + this->klassSymbolLength +
this->nameSymbolLength + 1);
......
......@@ -524,10 +524,10 @@ name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t
CHECK_FAIL(err);
err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &nameSymbol);
CHECK_FAIL(err);
err = ps_pread(J->P, nameSymbol + OFFSET_symbolOopDesc_length, &nameSymbolLength, 2);
err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
CHECK_FAIL(err);
nameString = (char*)calloc(nameSymbolLength + 1, 1);
err = ps_pread(J->P, nameSymbol + OFFSET_symbolOopDesc_body, nameString, nameSymbolLength);
err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength);
CHECK_FAIL(err);
/* To get signature string */
......@@ -535,10 +535,10 @@ name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t
CHECK_FAIL(err);
err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol);
CHECK_FAIL(err);
err = ps_pread(J->P, signatureSymbol + OFFSET_symbolOopDesc_length, &signatureSymbolLength, 2);
err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
CHECK_FAIL(err);
signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
err = ps_pread(J->P, signatureSymbol + OFFSET_symbolOopDesc_body, signatureString, signatureSymbolLength);
err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength);
CHECK_FAIL(err);
/* To get klass string */
......@@ -546,10 +546,10 @@ name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t
CHECK_FAIL(err);
err = read_pointer(J, klassPtr + OFFSET_Klass_name + SIZE_oopDesc, &klassSymbol);
CHECK_FAIL(err);
err = ps_pread(J->P, klassSymbol + OFFSET_symbolOopDesc_length, &klassSymbolLength, 2);
err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2);
CHECK_FAIL(err);
klassString = (char*)calloc(klassSymbolLength + 1, 1);
err = ps_pread(J->P, klassSymbol + OFFSET_symbolOopDesc_body, klassString, klassSymbolLength);
err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength);
CHECK_FAIL(err);
result[0] = '\0';
......
......@@ -142,7 +142,7 @@ int DTraceJSDT::pd_activate(
++strcount;
for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
JVM_DTraceProbe* p = &(provider->probes[prbc]);
symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
// function + name + one per argument
strcount += 2 + ArgumentCount(sig).size();
}
......@@ -178,7 +178,7 @@ int DTraceJSDT::pd_activate(
stroffs[curstr++] = string_index;
string_index += strlen(name) + 1;
symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
SignatureStream ss(sig);
for ( ; !ss.at_return_type(); ss.next()) {
BasicType bt = ss.type();
......@@ -227,7 +227,7 @@ int DTraceJSDT::pd_activate(
uint32_t argscount = 0;
for(int prbc = 0; prbc < provider->probe_count; ++prbc) {
JVM_DTraceProbe* p = &(provider->probes[prbc]);
symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
argscount += ArgumentCount(sig).size();
}
secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]);
......@@ -298,7 +298,7 @@ int DTraceJSDT::pd_activate(
strcpy(str, name);
str += strlen(name) + 1;
symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
SignatureStream ss(sig);
for ( ; !ss.at_return_type(); ss.next()) {
BasicType bt = ss.type();
......@@ -433,7 +433,7 @@ int DTraceJSDT::pd_activate(
uint8_t* par = (uint8_t*)(dof + sec->dofs_offset);
for (int prbc = 0; prbc < provider->probe_count; ++prbc) {
JVM_DTraceProbe* p = &(provider->probes[prbc]);
symbolOop sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
Symbol* sig = JNIHandles::resolve_jmethod_id(p->method)->signature();
uint8_t count = (uint8_t)ArgumentCount(sig).size();
for (uint8_t i = 0; i < count; ++i) {
*par++ = i;
......
......@@ -60,7 +60,6 @@ class ciReturnAddress;
class ciKlass;
class ciInstanceKlass;
class ciMethodKlass;
class ciSymbolKlass;
class ciArrayKlass;
class ciObjArrayKlass;
class ciTypeArrayKlass;
......@@ -112,7 +111,6 @@ friend class ciReturnAddress; \
friend class ciKlass; \
friend class ciInstanceKlass; \
friend class ciMethodKlass; \
friend class ciSymbolKlass; \
friend class ciArrayKlass; \
friend class ciObjArrayKlass; \
friend class ciTypeArrayKlass; \
......
......@@ -68,7 +68,6 @@
ciObject* ciEnv::_null_object_instance;
ciMethodKlass* ciEnv::_method_klass_instance;
ciSymbolKlass* ciEnv::_symbol_klass_instance;
ciKlassKlass* ciEnv::_klass_klass_instance;
ciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance;
ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance;
......@@ -202,6 +201,7 @@ ciEnv::ciEnv(Arena* arena) {
ciEnv::~ciEnv() {
CompilerThread* current_thread = CompilerThread::current();
_factory->remove_symbols();
current_thread->set_env(NULL);
}
......@@ -234,7 +234,7 @@ void ciEnv::cache_dtrace_flags() {
// ------------------------------------------------------------------
// helper for lazy exception creation
ciInstance* ciEnv::get_or_create_exception(jobject& handle, symbolHandle name) {
ciInstance* ciEnv::get_or_create_exception(jobject& handle, Symbol* name) {
VM_ENTRY_MARK;
if (handle == NULL) {
// Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance.
......@@ -261,7 +261,7 @@ ciInstance* ciEnv::ArrayIndexOutOfBoundsException_instance() {
if (_ArrayIndexOutOfBoundsException_instance == NULL) {
_ArrayIndexOutOfBoundsException_instance
= get_or_create_exception(_ArrayIndexOutOfBoundsException_handle,
vmSymbolHandles::java_lang_ArrayIndexOutOfBoundsException());
vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
}
return _ArrayIndexOutOfBoundsException_instance;
}
......@@ -269,7 +269,7 @@ ciInstance* ciEnv::ArrayStoreException_instance() {
if (_ArrayStoreException_instance == NULL) {
_ArrayStoreException_instance
= get_or_create_exception(_ArrayStoreException_handle,
vmSymbolHandles::java_lang_ArrayStoreException());
vmSymbols::java_lang_ArrayStoreException());
}
return _ArrayStoreException_instance;
}
......@@ -277,7 +277,7 @@ ciInstance* ciEnv::ClassCastException_instance() {
if (_ClassCastException_instance == NULL) {
_ClassCastException_instance
= get_or_create_exception(_ClassCastException_handle,
vmSymbolHandles::java_lang_ClassCastException());
vmSymbols::java_lang_ClassCastException());
}
return _ClassCastException_instance;
}
......@@ -377,14 +377,16 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
EXCEPTION_CONTEXT;
// Now we need to check the SystemDictionary
symbolHandle sym(THREAD, name->get_symbolOop());
Symbol* sym = name->get_symbol();
if (sym->byte_at(0) == 'L' &&
sym->byte_at(sym->utf8_length()-1) == ';') {
// This is a name from a signature. Strip off the trimmings.
sym = oopFactory::new_symbol_handle(sym->as_utf8()+1,
sym->utf8_length()-2,
KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass));
name = get_object(sym())->as_symbol();
// Call recursive to keep scope of strippedsym.
TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
sym->utf8_length()-2,
KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass));
ciSymbol* strippedname = get_symbol(strippedsym);
return get_klass_by_name_impl(accessing_klass, strippedname, require_local);
}
// Check for prior unloaded klass. The SystemDictionary's answers
......@@ -430,13 +432,14 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
(sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) {
// We have an unloaded array.
// Build it on the fly if the element class exists.
symbolOop elem_sym = oopFactory::new_symbol(sym->as_utf8()+1,
sym->utf8_length()-1,
KILL_COMPILE_ON_FATAL_(fail_type));
TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
sym->utf8_length()-1,
KILL_COMPILE_ON_FATAL_(fail_type));
// Get element ciKlass recursively.
ciKlass* elem_klass =
get_klass_by_name_impl(accessing_klass,
get_object(elem_sym)->as_symbol(),
get_symbol(elem_sym),
require_local);
if (elem_klass != NULL && elem_klass->is_loaded()) {
// Now make an array for it
......@@ -475,7 +478,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
ciInstanceKlass* accessor) {
EXCEPTION_CONTEXT;
KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index));
symbolHandle klass_name;
Symbol* klass_name = NULL;
if (klass.is_null()) {
// The klass has not been inserted into the constant pool.
// Try to look it up by name.
......@@ -490,10 +493,10 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
// very recently.
klass = KlassHandle(THREAD, cpool->resolved_klass_at(index));
} else if (tag.is_symbol()) {
klass_name = symbolHandle(THREAD, cpool->symbol_at(index));
klass_name = cpool->symbol_at(index);
} else {
assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag");
klass_name = symbolHandle(THREAD, cpool->unresolved_klass_at(index));
klass_name = cpool->unresolved_klass_at(index);
}
}
}
......@@ -501,7 +504,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
if (klass.is_null()) {
// Not found in constant pool. Use the name to do the lookup.
ciKlass* k = get_klass_by_name_impl(accessor,
get_object(klass_name())->as_symbol(),
get_symbol(klass_name),
false);
// Calculate accessibility the hard way.
if (!k->is_loaded()) {
......@@ -519,7 +522,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
// Check for prior unloaded klass. The SystemDictionary's answers
// can vary over time but the compiler needs consistency.
ciSymbol* name = get_object(klass()->klass_part()->name())->as_symbol();
ciSymbol* name = get_symbol(klass()->klass_part()->name());
ciKlass* unloaded_klass = check_get_unloaded_klass(accessor, name);
if (unloaded_klass != NULL) {
is_accessible = false;
......@@ -605,7 +608,7 @@ ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,
return ciConstant(T_OBJECT, ciobj);
} else if (tag.is_method_type()) {
// must execute Java code to link this CP entry into cache[i].f1
ciSymbol* signature = get_object(cpool->method_type_signature_at(index))->as_symbol();
ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index));
ciObject* ciobj = get_unloaded_method_type_constant(signature);
return ciConstant(T_OBJECT, ciobj);
} else if (tag.is_method_handle()) {
......@@ -613,8 +616,8 @@ ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,
int ref_kind = cpool->method_handle_ref_kind_at(index);
int callee_index = cpool->method_handle_klass_index_at(index);
ciKlass* callee = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor);
ciSymbol* name = get_object(cpool->method_handle_name_ref_at(index))->as_symbol();
ciSymbol* signature = get_object(cpool->method_handle_signature_ref_at(index))->as_symbol();
ciSymbol* name = get_symbol(cpool->method_handle_name_ref_at(index));
ciSymbol* signature = get_symbol(cpool->method_handle_signature_ref_at(index));
ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind);
return ciConstant(T_OBJECT, ciobj);
} else {
......@@ -674,33 +677,31 @@ ciField* ciEnv::get_field_by_index(ciInstanceKlass* accessor,
// name, signature, and bytecode.
methodOop ciEnv::lookup_method(instanceKlass* accessor,
instanceKlass* holder,
symbolOop name,
symbolOop sig,
Symbol* name,
Symbol* sig,
Bytecodes::Code bc) {
EXCEPTION_CONTEXT;
KlassHandle h_accessor(THREAD, accessor);
KlassHandle h_holder(THREAD, holder);
symbolHandle h_name(THREAD, name);
symbolHandle h_sig(THREAD, sig);
LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
methodHandle dest_method;
switch (bc) {
case Bytecodes::_invokestatic:
dest_method =
LinkResolver::resolve_static_call_or_null(h_holder, h_name, h_sig, h_accessor);
LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor);
break;
case Bytecodes::_invokespecial:
dest_method =
LinkResolver::resolve_special_call_or_null(h_holder, h_name, h_sig, h_accessor);
LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor);
break;
case Bytecodes::_invokeinterface:
dest_method =
LinkResolver::linktime_resolve_interface_method_or_null(h_holder, h_name, h_sig,
LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig,
h_accessor, true);
break;
case Bytecodes::_invokevirtual:
dest_method =
LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, h_name, h_sig,
LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig,
h_accessor, true);
break;
default: ShouldNotReachHere();
......@@ -721,8 +722,8 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
// Get the method's name and signature.
symbolOop name_sym = cpool->name_ref_at(index);
symbolOop sig_sym = cpool->signature_ref_at(index);
Symbol* name_sym = cpool->name_ref_at(index);
Symbol* sig_sym = cpool->signature_ref_at(index);
if (holder_is_accessible) { // Our declared holder is loaded.
instanceKlass* lookup = declared_holder->get_instanceKlass();
......@@ -738,8 +739,8 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
// lookup.
return get_unloaded_method(declared_holder,
get_object(name_sym)->as_symbol(),
get_object(sig_sym)->as_symbol());
get_symbol(name_sym),
get_symbol(sig_sym));
}
......@@ -759,7 +760,7 @@ ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
// compiler, but it is simpler to stop the code path here with an unlinked method.
if (!is_resolved) {
ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
ciSymbol* sig_sym = get_object(cpool->signature_ref_at(index))->as_symbol();
ciSymbol* sig_sym = get_symbol(cpool->signature_ref_at(index));
return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym);
}
......
......@@ -79,7 +79,6 @@ private:
// Distinguished instances of certain ciObjects..
static ciObject* _null_object_instance;
static ciMethodKlass* _method_klass_instance;
static ciSymbolKlass* _symbol_klass_instance;
static ciKlassKlass* _klass_klass_instance;
static ciInstanceKlassKlass* _instance_klass_klass_instance;
static ciTypeArrayKlassKlass* _type_array_klass_klass_instance;
......@@ -160,8 +159,8 @@ private:
klassOop resolved_klassOop);
methodOop lookup_method(instanceKlass* accessor,
instanceKlass* holder,
symbolOop name,
symbolOop sig,
Symbol* name,
Symbol* sig,
Bytecodes::Code bc);
// Get a ciObject from the object factory. Ensures uniqueness
......@@ -174,9 +173,18 @@ 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);
ciInstance* get_or_create_exception(jobject& handle, symbolHandle name);
ciInstance* get_or_create_exception(jobject& handle, Symbol* name);
// Get a ciMethod representing either an unfound method or
// a method with an unloaded holder. Ensures uniqueness of
......
......@@ -79,15 +79,15 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with(NULL) {
constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants());
// Get the field's name, signature, and type.
symbolHandle name (thread, cpool->name_ref_at(index));
_name = ciEnv::current(thread)->get_object(name())->as_symbol();
Symbol* name = cpool->name_ref_at(index);
_name = ciEnv::current(thread)->get_symbol(name);
int nt_index = cpool->name_and_type_ref_index_at(index);
int sig_index = cpool->signature_ref_index_at(nt_index);
symbolHandle signature (thread, cpool->symbol_at(sig_index));
_signature = ciEnv::current(thread)->get_object(signature())->as_symbol();
Symbol* signature = cpool->symbol_at(sig_index);
_signature = ciEnv::current(thread)->get_symbol(signature);
BasicType field_type = FieldType::basic_type(signature());
BasicType field_type = FieldType::basic_type(signature);
// If the field is a pointer type, get the klass of the
// field.
......@@ -100,7 +100,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with(NULL) {
_type = ciType::make(field_type);
}
_name = (ciSymbol*)ciEnv::current(thread)->get_object(name());
_name = (ciSymbol*)ciEnv::current(thread)->get_symbol(name);
// Get the field's declared holder.
//
......@@ -130,7 +130,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with(NULL) {
// Perform the field lookup.
fieldDescriptor field_desc;
klassOop canonical_holder =
loaded_decl_holder->find_field(name(), signature(), &field_desc);
loaded_decl_holder->find_field(name, signature, &field_desc);
if (canonical_holder == NULL) {
// Field lookup failed. Will be detected by will_link.
_holder = declared_holder;
......@@ -150,8 +150,8 @@ ciField::ciField(fieldDescriptor *fd): _known_to_link_with(NULL) {
// Get the field's name, signature, and type.
ciEnv* env = CURRENT_ENV;
_name = env->get_object(fd->name())->as_symbol();
_signature = env->get_object(fd->signature())->as_symbol();
_name = env->get_symbol(fd->name());
_signature = env->get_symbol(fd->signature());
BasicType field_type = fd->field_type();
......
......@@ -380,7 +380,7 @@ ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature,
VM_ENTRY_MARK;
instanceKlass* k = get_instanceKlass();
fieldDescriptor fd;
klassOop def = k->find_field(name->get_symbolOop(), signature->get_symbolOop(), is_static, &fd);
klassOop def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd);
if (def == NULL) {
return NULL;
}
......@@ -541,8 +541,8 @@ ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) {
VM_ENTRY_MARK;
instanceKlass* k = get_instanceKlass();
symbolOop name_sym = name->get_symbolOop();
symbolOop sig_sym= signature->get_symbolOop();
Symbol* name_sym = name->get_symbol();
Symbol* sig_sym= signature->get_symbol();
methodOop m = k->find_method(name_sym, sig_sym);
if (m == NULL) return NULL;
......
......@@ -39,9 +39,9 @@ ciKlass::ciKlass(KlassHandle h_k) : ciType(h_k) {
assert(get_oop()->is_klass(), "wrong type");
Klass* k = get_Klass();
_layout_helper = k->layout_helper();
symbolOop klass_name = k->name();
Symbol* klass_name = k->name();
assert(klass_name != NULL, "wrong ciKlass constructor");
_name = CURRENT_ENV->get_object(klass_name)->as_symbol();
_name = CURRENT_ENV->get_symbol(klass_name);
}
// ------------------------------------------------------------------
......
......@@ -122,9 +122,9 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
// generating _signature may allow GC and therefore move m.
// These fields are always filled in.
_name = env->get_object(h_m()->name())->as_symbol();
_name = env->get_symbol(h_m()->name());
_holder = env->get_object(h_m()->method_holder())->as_instance_klass();
ciSymbol* sig_symbol = env->get_object(h_m()->signature())->as_symbol();
ciSymbol* sig_symbol = env->get_symbol(h_m()->signature());
_signature = new (env->arena()) ciSignature(_holder, sig_symbol);
_method_data = NULL;
// Take a snapshot of these values, so they will be commensurate with the MDO.
......@@ -649,8 +649,8 @@ ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) {
KlassHandle caller_klass (THREAD, caller->get_klassOop());
KlassHandle h_recv (THREAD, exact_receiver->get_klassOop());
KlassHandle h_resolved (THREAD, holder()->get_klassOop());
symbolHandle h_name (THREAD, name()->get_symbolOop());
symbolHandle h_signature (THREAD, signature()->get_symbolOop());
Symbol* h_name = name()->get_symbol();
Symbol* h_signature = signature()->get_symbol();
methodHandle m;
// Only do exact lookup if receiver klass has been linked. Otherwise,
......@@ -702,8 +702,8 @@ int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) {
KlassHandle caller_klass (THREAD, caller->get_klassOop());
KlassHandle h_recv (THREAD, receiver->get_klassOop());
symbolHandle h_name (THREAD, name()->get_symbolOop());
symbolHandle h_signature (THREAD, signature()->get_symbolOop());
Symbol* h_name = name()->get_symbol();
Symbol* h_signature = signature()->get_symbol();
vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass);
if (vtable_index == methodOopDesc::nonvirtual_vtable_index) {
......
......@@ -110,7 +110,7 @@ ciSymbol* ciObjArrayKlass::construct_array_name(ciSymbol* element_name,
EXCEPTION_CONTEXT;
int element_len = element_name->utf8_length();
symbolOop base_name_sym = element_name->get_symbolOop();
Symbol* base_name_sym = element_name->get_symbol();
char* name;
if (base_name_sym->byte_at(0) == '[' ||
......
......@@ -268,10 +268,6 @@ public:
assert(is_type_array_klass(), "bad cast");
return (ciTypeArrayKlass*)this;
}
ciSymbolKlass* as_symbol_klass() {
assert(is_symbol_klass(), "bad cast");
return (ciSymbolKlass*)this;
}
ciKlassKlass* as_klass_klass() {
assert(is_klass_klass(), "bad cast");
return (ciKlassKlass*)this;
......
......@@ -38,7 +38,6 @@
#include "ci/ciObjArrayKlassKlass.hpp"
#include "ci/ciObjectFactory.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciSymbolKlass.hpp"
#include "ci/ciTypeArray.hpp"
#include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciTypeArrayKlassKlass.hpp"
......@@ -98,6 +97,8 @@ ciObjectFactory::ciObjectFactory(Arena* arena,
_unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL);
_return_addresses =
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.
int i;
for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) {
symbolHandle sym_handle = vmSymbolHandles::symbol_handle_at((vmSymbols::SID) i);
assert(vmSymbols::find_sid(sym_handle()) == i, "1-1 mapping");
ciSymbol* sym = new (_arena) ciSymbol(sym_handle, (vmSymbols::SID) i);
Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i);
assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping");
ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i);
init_ident_of(sym);
_shared_ci_symbols[i] = sym;
}
#ifdef ASSERT
for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) {
symbolHandle sym_handle = vmSymbolHandles::symbol_handle_at((vmSymbols::SID) i);
Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i);
ciSymbol* sym = vm_symbol_at((vmSymbols::SID) i);
assert(sym->get_oop() == sym_handle(), "oop must match");
assert(sym->get_symbol() == vmsym, "oop must match");
}
assert(ciSymbol::void_class_signature()->get_oop() == vmSymbols::void_class_signature(), "spot check");
assert(ciSymbol::void_class_signature()->get_symbol() == vmSymbols::void_class_signature(), "spot check");
#endif
}
......@@ -157,8 +158,6 @@ void ciObjectFactory::init_shared_objects() {
init_ident_of(ciEnv::_null_object_instance);
ciEnv::_method_klass_instance =
get(Universe::methodKlassObj())->as_method_klass();
ciEnv::_symbol_klass_instance =
get(Universe::symbolKlassObj())->as_symbol_klass();
ciEnv::_klass_klass_instance =
get(Universe::klassKlassObj())->as_klass_klass();
ciEnv::_instance_klass_klass_instance =
......@@ -188,7 +187,7 @@ 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
ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL);
init_ident_of(ciEnv::_unloaded_ciinstance_klass);
......@@ -218,6 +217,30 @@ void ciObjectFactory::init_shared_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
//
......@@ -255,15 +278,6 @@ ciObject* ciObjectFactory::get(oop key) {
return bucket->object();
}
// Check in the shared symbol area before putting it in the list.
if (key->is_symbol()) {
vmSymbols::SID sid = vmSymbols::find_sid((symbolOop)key);
if (sid != vmSymbols::NO_SID) {
// do not pollute the main cache with it
return vm_symbol_at(sid);
}
}
// The ciObject does not yet exist. Create it and insert it
// into the cache.
Handle keyHandle(key);
......@@ -297,11 +311,7 @@ ciObject* ciObjectFactory::get(oop key) {
ciObject* ciObjectFactory::create_new_object(oop o) {
EXCEPTION_CONTEXT;
if (o->is_symbol()) {
symbolHandle h_o(THREAD, (symbolOop)o);
assert(vmSymbols::find_sid(h_o()) == vmSymbols::NO_SID, "");
return new (arena()) ciSymbol(h_o, vmSymbols::NO_SID);
} else if (o->is_klass()) {
if (o->is_klass()) {
KlassHandle h_k(THREAD, (klassOop)o);
Klass* k = ((klassOop)o)->klass_part();
if (k->oop_is_instance()) {
......@@ -312,8 +322,6 @@ ciObject* ciObjectFactory::create_new_object(oop o) {
return new (arena()) ciTypeArrayKlass(h_k);
} else if (k->oop_is_method()) {
return new (arena()) ciMethodKlass(h_k);
} else if (k->oop_is_symbol()) {
return new (arena()) ciSymbolKlass(h_k);
} else if (k->oop_is_klass()) {
if (k->oop_is_objArrayKlass()) {
return new (arena()) ciObjArrayKlassKlass(h_k);
......@@ -426,22 +434,20 @@ ciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass,
// unloaded instanceKlass. Deal with both.
if (name->byte_at(0) == '[') {
// Decompose the name.'
jint dimension = 0;
symbolOop element_name = NULL;
BasicType element_type= FieldType::get_array_info(name->get_symbolOop(),
&dimension,
&element_name,
THREAD);
FieldArrayInfo fd;
BasicType element_type = FieldType::get_array_info(name->get_symbol(),
fd, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
CURRENT_THREAD_ENV->record_out_of_memory_failure();
return ciEnv::_unloaded_ciobjarrayklass;
}
int dimension = fd.dimension();
assert(element_type != T_ARRAY, "unsuccessful decomposition");
ciKlass* element_klass = NULL;
if (element_type == T_OBJECT) {
ciEnv *env = CURRENT_THREAD_ENV;
ciSymbol* ci_name = env->get_object(element_name)->as_symbol();
ciSymbol* ci_name = env->get_symbol(fd.object_key());
element_klass =
env->get_klass_by_name(accessing_klass, ci_name, false)->as_instance_klass();
} else {
......@@ -573,6 +579,10 @@ void ciObjectFactory::init_ident_of(ciObject* obj) {
obj->set_ident(_next_ident++);
}
void ciObjectFactory::init_ident_of(ciSymbol* obj) {
obj->set_ident(_next_ident++);
}
// ------------------------------------------------------------------
// ciObjectFactory::find
......
......@@ -48,6 +48,7 @@ private:
GrowableArray<ciKlass*>* _unloaded_klasses;
GrowableArray<ciInstance*>* _unloaded_instances;
GrowableArray<ciReturnAddress*>* _return_addresses;
GrowableArray<ciSymbol*>* _symbols; // keep list of symbols created
int _next_ident;
public:
......@@ -76,6 +77,7 @@ private:
void insert_non_perm(NonPermObject* &where, oop key, ciObject* obj);
void init_ident_of(ciObject* obj);
void init_ident_of(ciSymbol* obj);
Arena* arena() { return _arena; }
......@@ -88,13 +90,15 @@ public:
static void initialize();
void init_shared_objects();
void remove_symbols();
ciObjectFactory(Arena* arena, int expected_size);
// Get the ciObject corresponding to some oop.
ciObject* get(oop key);
ciSymbol* get_symbol(Symbol* key);
// Get the ciSymbol corresponding to one of the vmSymbols.
static ciSymbol* vm_symbol_at(int index);
......
......@@ -47,7 +47,8 @@ ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol) {
int size = 0;
int count = 0;
symbolHandle sh (THREAD, symbol->get_symbolOop());
ResourceMark rm(THREAD);
Symbol* sh = symbol->get_symbol();
SignatureStream ss(sh);
for (; ; ss.next()) {
// Process one element of the signature
......@@ -55,14 +56,14 @@ ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol) {
if (!ss.is_object()) {
type = ciType::make(ss.type());
} else {
symbolOop name = ss.as_symbol(THREAD);
Symbol* name = ss.as_symbol(THREAD);
if (HAS_PENDING_EXCEPTION) {
type = ss.is_array() ? (ciType*)ciEnv::unloaded_ciobjarrayklass()
: (ciType*)ciEnv::unloaded_ciinstance_klass();
env->record_out_of_memory_failure();
CLEAR_PENDING_EXCEPTION;
} else {
ciSymbol* klass_name = env->get_object(name)->as_symbol();
ciSymbol* klass_name = env->get_symbol(name);
type = env->get_klass_by_name_impl(_accessing_klass, klass_name, false);
}
}
......
......@@ -48,7 +48,7 @@ private:
void get_all_klasses();
symbolOop get_symbolOop() const { return _symbol->get_symbolOop(); }
Symbol* get_symbol() const { return _symbol->get_symbol(); }
public:
ciSymbol* as_symbol() const { return _symbol; }
......
......@@ -30,23 +30,27 @@
// ------------------------------------------------------------------
// ciSymbol::ciSymbol
//
// Preallocated handle variant. Used with handles from vmSymboHandles.
ciSymbol::ciSymbol(symbolHandle h_s, vmSymbols::SID sid)
: ciObject(h_s), _sid(sid)
// Preallocated symbol variant. Used with symbols from vmSymbols.
ciSymbol::ciSymbol(Symbol* s, vmSymbols::SID sid)
: _symbol(s), _sid(sid)
{
assert(_symbol != NULL, "adding null symbol");
_symbol->increment_refcount(); // increment ref count
assert(sid_ok(), "must be in vmSymbols");
}
// Normal case for non-famous symbols.
ciSymbol::ciSymbol(symbolOop s)
: ciObject(s), _sid(vmSymbols::NO_SID)
ciSymbol::ciSymbol(Symbol* s)
: _symbol(s), _sid(vmSymbols::NO_SID)
{
assert(_symbol != NULL, "adding null symbol");
_symbol->increment_refcount(); // increment ref count
assert(sid_ok(), "must not be in vmSymbols");
}
// ciSymbol
//
// This class represents a symbolOop in the HotSpot virtual
// This class represents a Symbol* in the HotSpot virtual
// machine.
// ------------------------------------------------------------------
......@@ -55,20 +59,20 @@ ciSymbol::ciSymbol(symbolOop s)
// The text of the symbol as a null-terminated C string.
const char* ciSymbol::as_utf8() {
VM_QUICK_ENTRY_MARK;
symbolOop s = get_symbolOop();
Symbol* s = get_symbol();
return s->as_utf8();
}
// ------------------------------------------------------------------
// ciSymbol::base
jbyte* ciSymbol::base() {
GUARDED_VM_ENTRY(return get_symbolOop()->base();)
const jbyte* ciSymbol::base() {
GUARDED_VM_ENTRY(return get_symbol()->base();)
}
// ------------------------------------------------------------------
// ciSymbol::byte_at
int ciSymbol::byte_at(int i) {
GUARDED_VM_ENTRY(return get_symbolOop()->byte_at(i);)
GUARDED_VM_ENTRY(return get_symbol()->byte_at(i);)
}
// ------------------------------------------------------------------
......@@ -76,7 +80,7 @@ int ciSymbol::byte_at(int i) {
//
// Tests if the symbol starts with the given prefix.
bool ciSymbol::starts_with(const char* prefix, int len) const {
GUARDED_VM_ENTRY(return get_symbolOop()->starts_with(prefix, len);)
GUARDED_VM_ENTRY(return get_symbol()->starts_with(prefix, len);)
}
// ------------------------------------------------------------------
......@@ -84,13 +88,13 @@ bool ciSymbol::starts_with(const char* prefix, int len) const {
//
// Determines where the symbol contains the given substring.
int ciSymbol::index_of_at(int i, const char* str, int len) const {
GUARDED_VM_ENTRY(return get_symbolOop()->index_of_at(i, str, len);)
GUARDED_VM_ENTRY(return get_symbol()->index_of_at(i, str, len);)
}
// ------------------------------------------------------------------
// ciSymbol::utf8_length
int ciSymbol::utf8_length() {
GUARDED_VM_ENTRY(return get_symbolOop()->utf8_length();)
GUARDED_VM_ENTRY(return get_symbol()->utf8_length();)
}
// ------------------------------------------------------------------
......@@ -107,7 +111,7 @@ void ciSymbol::print_impl(outputStream* st) {
//
// Print the value of this symbol on an outputStream
void ciSymbol::print_symbol_on(outputStream *st) {
GUARDED_VM_ENTRY(get_symbolOop()->print_symbol_on(st);)
GUARDED_VM_ENTRY(get_symbol()->print_symbol_on(st);)
}
// ------------------------------------------------------------------
......@@ -116,15 +120,13 @@ void ciSymbol::print_symbol_on(outputStream *st) {
// Make a ciSymbol from a C string (implementation).
ciSymbol* ciSymbol::make_impl(const char* s) {
EXCEPTION_CONTEXT;
// For some reason, oopFactory::new_symbol doesn't declare its
// char* argument as const.
symbolOop sym = oopFactory::new_symbol((char*)s, (int)strlen(s), THREAD);
TempNewSymbol sym = SymbolTable::new_symbol(s, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
CURRENT_THREAD_ENV->record_out_of_memory_failure();
return ciEnv::_unloaded_cisymbol;
}
return CURRENT_THREAD_ENV->get_object(sym)->as_symbol();
return CURRENT_THREAD_ENV->get_symbol(sym);
}
// ------------------------------------------------------------------
......
......@@ -28,15 +28,18 @@
#include "ci/ciObject.hpp"
#include "ci/ciObjectFactory.hpp"
#include "classfile/vmSymbols.hpp"
#include "oops/symbolOop.hpp"
#include "oops/symbol.hpp"
// ciSymbol
//
// This class represents a symbolOop in the HotSpot virtual
// This class represents a Symbol* in the HotSpot virtual
// machine.
class ciSymbol : public ciObject {
class ciSymbol : public ResourceObj {
Symbol* _symbol;
uint _ident;
CI_PACKAGE_ACCESS
// These friends all make direct use of get_symbolOop:
// These friends all make direct use of get_symbol:
friend class ciEnv;
friend class ciInstanceKlass;
friend class ciSignature;
......@@ -45,24 +48,28 @@ class ciSymbol : public ciObject {
private:
const vmSymbols::SID _sid;
DEBUG_ONLY( bool sid_ok() { return vmSymbols::find_sid(get_symbolOop()) == _sid; } )
DEBUG_ONLY( bool sid_ok() { return vmSymbols::find_sid(get_symbol()) == _sid; } )
ciSymbol(symbolOop s); // normal case, for symbols not mentioned in vmSymbols
ciSymbol(symbolHandle s, vmSymbols::SID sid); // for use with vmSymbolHandles
ciSymbol(Symbol* s); // normal case, for symbols not mentioned in vmSymbols
ciSymbol(Symbol* s, vmSymbols::SID sid); // for use with vmSymbols
symbolOop get_symbolOop() const { return (symbolOop)get_oop(); }
Symbol* get_symbol() const { return _symbol; }
const char* type_string() { return "ciSymbol"; }
void print_impl(outputStream* st);
// This is public in symbolOop but private here, because the base can move:
jbyte* base();
// This is public in Symbol* but private here, because the base can move:
const jbyte* base();
// Make a ciSymbol from a C string (implementation).
static ciSymbol* make_impl(const char* s);
void set_ident(uint id) { _ident = id; }
public:
// A number unique to this object.
uint ident() { return _ident; }
// The enumeration ID from vmSymbols, or vmSymbols::NO_SID if none.
vmSymbols::SID sid() const { return _sid; }
......@@ -79,9 +86,6 @@ public:
// Determines where the symbol contains the given substring.
int index_of_at(int i, const char* str, int len) const;
// What kind of ciObject is this?
bool is_symbol() { return true; }
void print_symbol_on(outputStream* st);
void print_symbol() {
print_symbol_on(tty);
......@@ -96,6 +100,13 @@ public:
static ciSymbol* name() { return ciObjectFactory::vm_symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(name)); }
VM_SYMBOLS_DO(CI_SYMBOL_DECLARE, CI_SYMBOL_DECLARE)
#undef CI_SYMBOL_DECLARE
void print() {
_symbol->print();
}
// Are two ciSymbols equal?
bool equals(ciSymbol* obj) { return this->_symbol == obj->get_symbol(); }
};
#endif // SHARE_VM_CI_CISYMBOL_HPP
/*
* 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;
}
/*
* 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/ciStreams.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciSymbolKlass.hpp"
#include "ci/ciTypeArray.hpp"
#include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciTypeArrayKlassKlass.hpp"
......
......@@ -31,25 +31,25 @@
void ClassFileParser::classfile_parse_error(const char* msg, TRAPS) {
ResourceMark rm(THREAD);
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbolHandles::java_lang_ClassFormatError(),
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(),
msg, _class_name->as_C_string());
}
void ClassFileParser::classfile_parse_error(const char* msg, int index, TRAPS) {
ResourceMark rm(THREAD);
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbolHandles::java_lang_ClassFormatError(),
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(),
msg, index, _class_name->as_C_string());
}
void ClassFileParser::classfile_parse_error(const char* msg, const char *name, TRAPS) {
ResourceMark rm(THREAD);
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbolHandles::java_lang_ClassFormatError(),
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(),
msg, name, _class_name->as_C_string());
}
void ClassFileParser::classfile_parse_error(const char* msg, int index, const char *name, TRAPS) {
ResourceMark rm(THREAD);
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbolHandles::java_lang_ClassFormatError(),
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(),
msg, index, name, _class_name->as_C_string());
}
......@@ -57,7 +57,7 @@ void StackMapStream::stackmap_format_error(const char* msg, TRAPS) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbolHandles::java_lang_ClassFormatError(),
vmSymbols::java_lang_ClassFormatError(),
"StackMapTable format error: %s", msg
);
}
......@@ -32,6 +32,7 @@
#include "runtime/handles.inline.hpp"
#include "utilities/accessFlags.hpp"
class TempNewSymbol;
// Parser for for .class files
//
// The bytes describing the class file structure is read from a Stream object
......@@ -42,7 +43,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
bool _relax_verify;
u2 _major_version;
u2 _minor_version;
symbolHandle _class_name;
Symbol* _class_name;
KlassHandle _host_klass;
GrowableArray<Handle>* _cp_patches; // overrides for CP entries
......@@ -73,7 +74,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int length,
Handle class_loader,
Handle protection_domain,
symbolHandle class_name,
Symbol* class_name,
TRAPS);
// Field parsing
......@@ -209,21 +210,21 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
}
void throwIllegalSignature(
const char* type, symbolHandle name, symbolHandle sig, TRAPS);
const char* type, Symbol* name, Symbol* sig, TRAPS);
bool is_supported_version(u2 major, u2 minor);
bool has_illegal_visibility(jint flags);
void verify_constantvalue(int constantvalue_index, int signature_index, constantPoolHandle cp, TRAPS);
void verify_legal_utf8(const unsigned char* buffer, int length, TRAPS);
void verify_legal_class_name(symbolHandle name, TRAPS);
void verify_legal_field_name(symbolHandle name, TRAPS);
void verify_legal_method_name(symbolHandle name, TRAPS);
void verify_legal_field_signature(symbolHandle fieldname, symbolHandle signature, TRAPS);
int verify_legal_method_signature(symbolHandle methodname, symbolHandle signature, TRAPS);
void verify_legal_class_name(Symbol* name, TRAPS);
void verify_legal_field_name(Symbol* name, TRAPS);
void verify_legal_method_name(Symbol* name, TRAPS);
void verify_legal_field_signature(Symbol* fieldname, Symbol* signature, TRAPS);
int verify_legal_method_signature(Symbol* methodname, Symbol* signature, TRAPS);
void verify_legal_class_modifiers(jint flags, TRAPS);
void verify_legal_field_modifiers(jint flags, bool is_interface, TRAPS);
void verify_legal_method_modifiers(jint flags, bool is_interface, symbolHandle name, TRAPS);
void verify_legal_method_modifiers(jint flags, bool is_interface, Symbol* name, TRAPS);
bool verify_unqualified_name(char* name, unsigned int length, int type);
char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
......@@ -272,21 +273,21 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
//
// "parsed_name" is updated by this method, and is the name found
// while parsing the stream.
instanceKlassHandle parseClassFile(symbolHandle name,
instanceKlassHandle parseClassFile(Symbol* name,
Handle class_loader,
Handle protection_domain,
symbolHandle& parsed_name,
TempNewSymbol& parsed_name,
bool verify,
TRAPS) {
KlassHandle no_host_klass;
return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD);
}
instanceKlassHandle parseClassFile(symbolHandle name,
instanceKlassHandle parseClassFile(Symbol* name,
Handle class_loader,
Handle protection_domain,
KlassHandle host_klass,
GrowableArray<Handle>* cp_patches,
symbolHandle& parsed_name,
TempNewSymbol& parsed_name,
bool verify,
TRAPS);
......
......@@ -41,7 +41,7 @@
#include "oops/instanceKlass.hpp"
#include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbolOop.hpp"
#include "oops/symbol.hpp"
#include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp"
#include "runtime/compilationPolicy.hpp"
......@@ -752,11 +752,7 @@ void PackageHashtable::copy_table(char** top, char* end,
}
}
if (*top + n + sizeof(intptr_t) >= end) {
warning("\nThe shared miscellaneous data space is not large "
"enough to \npreload requested classes. Use "
"-XX:SharedMiscDataSize= to increase \nthe initial "
"size of the miscellaneous data space.\n");
exit(2);
report_out_of_shared_space(SharedMiscData);
}
// Copy the table data (the strings) to the shared space.
......@@ -875,9 +871,9 @@ 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);
EventMark m("loading class " INTPTR_FORMAT, (address)h_name());
EventMark m("loading class " INTPTR_FORMAT, (address)h_name);
ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
stringStream st;
......@@ -912,7 +908,7 @@ instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {
ClassFileParser parser(stream);
Handle class_loader;
Handle protection_domain;
symbolHandle parsed_name;
TempNewSymbol parsed_name = NULL;
instanceKlassHandle result = parser.parseClassFile(h_name,
class_loader,
protection_domain,
......@@ -1308,7 +1304,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
if (_compile_the_world_counter > CompileTheWorldStopAt) return;
// Construct name without extension
symbolHandle sym = oopFactory::new_symbol_handle(buffer, CHECK);
TempNewSymbol sym = SymbolTable::new_symbol(buffer, CHECK);
// Use loader to load and initialize class
klassOop ik = SystemDictionary::resolve_or_null(sym, loader, Handle(), THREAD);
instanceKlassHandle k (THREAD, ik);
......
......@@ -280,7 +280,7 @@ class ClassLoader: AllStatic {
}
// Load individual .class file
static instanceKlassHandle load_classfile(symbolHandle h_name, TRAPS);
static instanceKlassHandle load_classfile(Symbol* h_name, TRAPS);
// If the specified package has been loaded by the system, then returns
// the name of the directory or ZIP file that the package was loaded from.
......
......@@ -36,7 +36,7 @@ int Dictionary::_current_class_index = 0;
Dictionary::Dictionary(int table_size)
: TwoOopHashtable(table_size, sizeof(DictionaryEntry)) {
: TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry)) {
_current_class_index = 0;
_current_class_entry = NULL;
};
......@@ -45,7 +45,7 @@ Dictionary::Dictionary(int table_size)
Dictionary::Dictionary(int table_size, HashtableBucket* t,
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_entry = NULL;
};
......@@ -54,7 +54,7 @@ Dictionary::Dictionary(int table_size, HashtableBucket* t,
DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass,
oop loader) {
DictionaryEntry* entry;
entry = (DictionaryEntry*)Hashtable::new_entry(hash, klass);
entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(hash, klass);
entry->set_loader(loader);
entry->set_pd_set(NULL);
return entry;
......@@ -62,7 +62,7 @@ DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass,
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_pd_set(NULL);
return entry;
......@@ -76,7 +76,7 @@ void Dictionary::free_entry(DictionaryEntry* entry) {
entry->set_pd_set(to_delete->next());
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);
probe != NULL;
probe = probe->next()) {
oop e = probe->klass();
klassOop e = probe->klass();
oop class_loader = probe->loader();
if (is_strongly_reachable(class_loader, e)) {
blk->do_oop((oop*)probe->klass_addr());
......@@ -421,11 +421,11 @@ klassOop Dictionary::try_get_next_class() {
// also cast to volatile; we do this to ensure store order is maintained
// by the compilers.
void Dictionary::add_klass(symbolHandle class_name, Handle class_loader,
void Dictionary::add_klass(Symbol* class_name, Handle class_loader,
KlassHandle obj) {
assert_locked_or_safepoint(SystemDictionary_lock);
assert(obj() != NULL, "adding NULL obj");
assert(Klass::cast(obj())->name() == class_name(), "sanity check on name");
assert(Klass::cast(obj())->name() == class_name, "sanity check on name");
unsigned int hash = compute_hash(class_name, class_loader);
int index = hash_to_index(hash);
......@@ -444,15 +444,14 @@ void Dictionary::add_klass(symbolHandle class_name, Handle class_loader,
// Callers should be aware that an entry could be added just after
// _buckets[index] is read here, so the caller will not see the new entry.
DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
symbolHandle class_name,
Symbol* class_name,
Handle class_loader) {
symbolOop name_ = class_name();
oop loader_ = class_loader();
oop loader = class_loader();
debug_only(_lookup_count++);
for (DictionaryEntry* entry = bucket(index);
entry != NULL;
entry = entry->next()) {
if (entry->hash() == hash && entry->equals(name_, loader_)) {
if (entry->hash() == hash && entry->equals(class_name, loader)) {
return entry;
}
debug_only(_lookup_length++);
......@@ -461,7 +460,7 @@ 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) {
DictionaryEntry* entry = get_entry(index, hash, name, loader);
if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {
......@@ -473,7 +472,7 @@ klassOop Dictionary::find(int index, unsigned int hash, symbolHandle name,
klassOop Dictionary::find_class(int index, unsigned int hash,
symbolHandle name, Handle loader) {
Symbol* name, Handle loader) {
assert_locked_or_safepoint(SystemDictionary_lock);
assert (index == index_for(name, loader), "incorrect index?");
......@@ -486,7 +485,7 @@ klassOop Dictionary::find_class(int index, unsigned int hash,
// that table is static.
klassOop Dictionary::find_shared_class(int index, unsigned int hash,
symbolHandle name) {
Symbol* name) {
assert (index == index_for(name, Handle()), "incorrect index?");
DictionaryEntry* entry = get_entry(index, hash, name, Handle());
......@@ -498,7 +497,7 @@ void Dictionary::add_protection_domain(int index, unsigned int hash,
instanceKlassHandle klass,
Handle loader, Handle protection_domain,
TRAPS) {
symbolHandle klass_name(THREAD, klass->name());
Symbol* klass_name = klass->name();
DictionaryEntry* entry = get_entry(index, hash, klass_name, loader);
assert(entry != NULL,"entry must be present, we just created it");
......@@ -513,7 +512,7 @@ void Dictionary::add_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 protection_domain) {
DictionaryEntry* entry = get_entry(index, hash, name, loader);
......@@ -545,7 +544,7 @@ void Dictionary::reorder_dictionary() {
DictionaryEntry* p = master_list;
master_list = master_list->next();
p->set_next(NULL);
symbolHandle class_name (thread, instanceKlass::cast((klassOop)(p->klass()))->name());
Symbol* class_name = instanceKlass::cast((klassOop)(p->klass()))->name();
unsigned int hash = compute_hash(class_name, Handle(thread, p->loader()));
int index = hash_to_index(hash);
p->set_hash(hash);
......@@ -555,22 +554,22 @@ void Dictionary::reorder_dictionary() {
}
SymbolPropertyTable::SymbolPropertyTable(int table_size)
: Hashtable(table_size, sizeof(SymbolPropertyEntry))
: Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry))
{
}
SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t,
int number_of_entries)
: Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
: Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
{
}
SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash,
symbolHandle sym,
Symbol* sym,
intptr_t sym_mode) {
assert(index == index_for(sym, sym_mode), "incorrect index?");
for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {
if (p->hash() == hash && p->symbol() == sym() && p->symbol_mode() == sym_mode) {
if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) {
return p;
}
}
......@@ -579,13 +578,13 @@ SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int has
SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash,
symbolHandle sym, intptr_t sym_mode) {
Symbol* sym, intptr_t sym_mode) {
assert_locked_or_safepoint(SystemDictionary_lock);
assert(index == index_for(sym, sym_mode), "incorrect index?");
assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry");
SymbolPropertyEntry* p = new_entry(hash, sym(), sym_mode);
Hashtable::add_entry(index, p);
SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode);
Hashtable<Symbol*>::add_entry(index, p);
return p;
}
......@@ -593,7 +592,6 @@ SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash
void SymbolPropertyTable::oops_do(OopClosure* f) {
for (int index = 0; index < table_size(); index++) {
for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {
f->do_oop((oop*) p->symbol_addr());
if (p->property_oop() != NULL) {
f->do_oop(p->property_oop_addr());
}
......
......@@ -36,7 +36,7 @@ class DictionaryEntry;
// The data structure for the system dictionary (and the shared system
// dictionary).
class Dictionary : public TwoOopHashtable {
class Dictionary : public TwoOopHashtable<klassOop> {
friend class VMStructs;
private:
// current iteration index.
......@@ -45,19 +45,19 @@ private:
static DictionaryEntry* _current_class_entry;
DictionaryEntry* get_entry(int index, unsigned int hash,
symbolHandle name, Handle loader);
Symbol* name, Handle loader);
DictionaryEntry* bucket(int i) {
return (DictionaryEntry*)Hashtable::bucket(i);
return (DictionaryEntry*)Hashtable<klassOop>::bucket(i);
}
// The following method is not MT-safe and must be done under lock.
DictionaryEntry** bucket_addr(int i) {
return (DictionaryEntry**)Hashtable::bucket_addr(i);
return (DictionaryEntry**)Hashtable<klassOop>::bucket_addr(i);
}
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 add_klass(symbolHandle class_name, Handle class_loader,KlassHandle obj);
void add_klass(Symbol* class_name, Handle class_loader,KlassHandle obj);
klassOop find_class(int index, unsigned int hash,
symbolHandle name, Handle loader);
Symbol* name, Handle loader);
klassOop find_shared_class(int index, unsigned int hash, symbolHandle name);
klassOop find_shared_class(int index, unsigned int hash, Symbol* name);
// Compiler support
klassOop try_get_next_class();
......@@ -95,7 +95,7 @@ public:
// Classes loaded by the bootstrap loader are always strongly reachable.
// If we're not doing class unloading, all classes are strongly reachable.
static bool is_strongly_reachable(oop class_loader, oop klass) {
static bool is_strongly_reachable(oop class_loader, klassOop klass) {
assert (klass != NULL, "should have non-null klass");
return (class_loader == NULL || !ClassUnloading);
}
......@@ -105,10 +105,10 @@ public:
bool do_unloading(BoolObjectClosure* is_alive);
// Protection domains
klassOop find(int index, unsigned int hash, symbolHandle name,
klassOop find(int index, unsigned int hash, Symbol* name,
Handle loader, Handle protection_domain, TRAPS);
bool is_valid_protection_domain(int index, unsigned int hash,
symbolHandle name, Handle class_loader,
Symbol* name, Handle class_loader,
Handle protection_domain);
void add_protection_domain(int index, unsigned int hash,
instanceKlassHandle klass, Handle loader,
......@@ -147,7 +147,7 @@ class ProtectionDomainEntry :public CHeapObj {
// An entry in the system dictionary, this describes a class as
// { klassOop, loader, protection_domain }.
class DictionaryEntry : public HashtableEntry {
class DictionaryEntry : public HashtableEntry<klassOop> {
friend class VMStructs;
private:
// 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(); }
DictionaryEntry* next() const {
return (DictionaryEntry*)HashtableEntry::next();
return (DictionaryEntry*)HashtableEntry<klassOop>::next();
}
DictionaryEntry** next_addr() {
return (DictionaryEntry**)HashtableEntry::next_addr();
return (DictionaryEntry**)HashtableEntry<klassOop>::next_addr();
}
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();
return (instanceKlass::cast(klass)->name() == class_name &&
_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.
class SymbolPropertyEntry : public HashtableEntry {
class SymbolPropertyEntry : public HashtableEntry<Symbol*> {
friend class VMStructs;
private:
intptr_t _symbol_mode; // secondary key
......@@ -236,7 +236,7 @@ class SymbolPropertyEntry : public HashtableEntry {
address _property_data;
public:
symbolOop symbol() const { return (symbolOop) literal(); }
Symbol* symbol() const { return literal(); }
intptr_t symbol_mode() const { return _symbol_mode; }
void set_symbol_mode(intptr_t m) { _symbol_mode = m; }
......@@ -248,14 +248,13 @@ class SymbolPropertyEntry : public HashtableEntry {
void set_property_data(address p) { _property_data = p; }
SymbolPropertyEntry* next() const {
return (SymbolPropertyEntry*)HashtableEntry::next();
return (SymbolPropertyEntry*)HashtableEntry<Symbol*>::next();
}
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; }
void print_on(outputStream* st) const {
......@@ -279,16 +278,16 @@ class SymbolPropertyEntry : public HashtableEntry {
// A system-internal mapping of symbols to pointers, both managed
// and unmanaged. Used to record the auto-generation of each method
// MethodHandle.invoke(S)T, for all signatures (S)T.
class SymbolPropertyTable : public Hashtable {
class SymbolPropertyTable : public Hashtable<Symbol*> {
friend class VMStructs;
private:
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.
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) {
......@@ -298,8 +297,10 @@ private:
ShouldNotReachHere();
}
SymbolPropertyEntry* new_entry(unsigned int hash, symbolOop symbol, intptr_t symbol_mode) {
SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable::new_entry(hash, symbol);
SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {
SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<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_property_oop(NULL);
entry->set_property_data(NULL);
......@@ -311,23 +312,25 @@ public:
SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries);
void free_entry(SymbolPropertyEntry* entry) {
Hashtable::free_entry(entry);
// decrement Symbol refcount here because hashtable doesn't.
entry->literal()->decrement_refcount();
Hashtable<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.
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));
}
// need not be locked; no state change
SymbolPropertyEntry* find_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode);
SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
// must be done under SystemDictionary_lock
SymbolPropertyEntry* add_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode);
SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
// GC support
void oops_do(OopClosure* f);
......@@ -343,6 +346,4 @@ public:
#endif
void verify();
};
#endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP
......@@ -93,7 +93,7 @@ void JavaAssertions::addOption(const char* name, bool enable) {
}
oop JavaAssertions::createAssertionStatusDirectives(TRAPS) {
symbolHandle asd_sym = vmSymbolHandles::java_lang_AssertionStatusDirectives();
Symbol* asd_sym = vmSymbols::java_lang_AssertionStatusDirectives();
klassOop k = SystemDictionary::resolve_or_fail(asd_sym, true, CHECK_NULL);
instanceKlassHandle asd_klass (THREAD, k);
asd_klass->initialize(CHECK_NULL);
......
......@@ -36,7 +36,7 @@
#include "oops/klass.hpp"
#include "oops/klassOop.hpp"
#include "oops/methodOop.hpp"
#include "oops/symbolOop.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
......@@ -57,7 +57,7 @@
#endif
static bool find_field(instanceKlass* ik,
symbolOop name_symbol, symbolOop signature_symbol,
Symbol* name_symbol, Symbol* signature_symbol,
fieldDescriptor* fd,
bool allow_super = false) {
if (allow_super)
......@@ -69,7 +69,7 @@ static bool find_field(instanceKlass* ik,
// Helpful routine for computing field offsets at run time rather than hardcoding them
static void
compute_offset(int &dest_offset,
klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol,
klassOop klass_oop, Symbol* name_symbol, Symbol* signature_symbol,
bool allow_super = false) {
fieldDescriptor fd;
instanceKlass* ik = instanceKlass::cast(klass_oop);
......@@ -84,7 +84,7 @@ compute_offset(int &dest_offset,
// Same as above but for "optional" offsets that might not be present in certain JDK versions
static void
compute_optional_offset(int& dest_offset,
klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol,
klassOop klass_oop, Symbol* name_symbol, Symbol* signature_symbol,
bool allow_super = false) {
fieldDescriptor fd;
instanceKlass* ik = instanceKlass::cast(klass_oop);
......@@ -164,7 +164,7 @@ oop java_lang_String::create_oop_from_str(const char* utf8_str, TRAPS) {
return h_obj();
}
Handle java_lang_String::create_from_symbol(symbolHandle symbol, TRAPS) {
Handle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) {
int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length());
Handle h_obj = basic_create(length, false, CHECK_NH);
if (length > 0) {
......@@ -278,17 +278,17 @@ jchar* java_lang_String::as_unicode_string(oop java_string, int& length) {
return result;
}
symbolHandle java_lang_String::as_symbol(Handle java_string, TRAPS) {
Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) {
oop obj = java_string();
typeArrayOop value = java_lang_String::value(obj);
int offset = java_lang_String::offset(obj);
int length = java_lang_String::length(obj);
jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
symbolOop sym = SymbolTable::lookup_unicode(base, length, THREAD);
return symbolHandle(THREAD, sym);
Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD);
return sym;
}
symbolOop java_lang_String::as_symbol_or_null(oop java_string) {
Symbol* java_lang_String::as_symbol_or_null(oop java_string) {
typeArrayOop value = java_lang_String::value(java_string);
int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
......@@ -437,7 +437,7 @@ klassOop java_lang_Class::as_klassOop(oop java_class) {
void java_lang_Class::print_signature(oop java_class, outputStream* st) {
assert(java_lang_Class::is_instance(java_class), "must be a Class object");
symbolOop name = NULL;
Symbol* name = NULL;
bool is_instance = false;
if (is_primitive(java_class)) {
name = vmSymbols::type_signature(primitive_type(java_class));
......@@ -455,25 +455,32 @@ void java_lang_Class::print_signature(oop java_class, outputStream* st) {
if (is_instance) st->print(";");
}
symbolOop java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) {
Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) {
assert(java_lang_Class::is_instance(java_class), "must be a Class object");
symbolOop name = NULL;
Symbol* name;
if (is_primitive(java_class)) {
return vmSymbols::type_signature(primitive_type(java_class));
name = vmSymbols::type_signature(primitive_type(java_class));
// Because this can create a new symbol, the caller has to decrement
// the refcount, so make adjustment here and below for symbols returned
// that are not created or incremented due to a successful lookup.
name->increment_refcount();
} else {
klassOop k = as_klassOop(java_class);
if (!Klass::cast(k)->oop_is_instance()) {
return Klass::cast(k)->name();
name = Klass::cast(k)->name();
name->increment_refcount();
} else {
ResourceMark rm;
const char* sigstr = Klass::cast(k)->signature_name();
int siglen = (int) strlen(sigstr);
if (!intern_if_not_found)
return SymbolTable::probe(sigstr, siglen);
else
return oopFactory::new_symbol(sigstr, siglen, THREAD);
if (!intern_if_not_found) {
name = SymbolTable::probe(sigstr, siglen);
} else {
name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
}
}
}
return name;
}
......@@ -1022,8 +1029,8 @@ void java_lang_Throwable::print_to_stream(Handle stream, const char* str) {
JavaCalls::call_virtual(&result,
stream,
KlassHandle(THREAD, stream->klass()),
vmSymbolHandles::println_name(),
vmSymbolHandles::char_array_void_signature(),
vmSymbols::println_name(),
vmSymbols::char_array_void_signature(),
arg,
THREAD);
}
......@@ -1077,8 +1084,8 @@ void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) {
JavaCalls::call_virtual(&result,
h_throwable,
KlassHandle(THREAD, h_throwable->klass()),
vmSymbolHandles::getCause_name(),
vmSymbolHandles::void_throwable_signature(),
vmSymbols::getCause_name(),
vmSymbols::void_throwable_signature(),
THREAD);
// Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
if (HAS_PENDING_EXCEPTION) {
......@@ -1516,7 +1523,7 @@ oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
oop methodname = StringTable::intern(method->name(), CHECK_0);
java_lang_StackTraceElement::set_methodName(element(), methodname);
// Fill in source file name
symbolOop source = instanceKlass::cast(method->method_holder())->source_file_name();
Symbol* source = instanceKlass::cast(method->method_holder())->source_file_name();
oop filename = StringTable::intern(source, CHECK_0);
java_lang_StackTraceElement::set_fileName(element(), filename);
// File in source line number
......@@ -1732,7 +1739,7 @@ void java_lang_reflect_Constructor::compute_offsets() {
Handle java_lang_reflect_Constructor::create(TRAPS) {
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
symbolHandle name = vmSymbolHandles::java_lang_reflect_Constructor();
Symbol* name = vmSymbols::java_lang_reflect_Constructor();
klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
instanceKlassHandle klass (THREAD, k);
// Ensure it is initialized
......@@ -1854,7 +1861,7 @@ void java_lang_reflect_Field::compute_offsets() {
Handle java_lang_reflect_Field::create(TRAPS) {
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
symbolHandle name = vmSymbolHandles::java_lang_reflect_Field();
Symbol* name = vmSymbols::java_lang_reflect_Field();
klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
instanceKlassHandle klass (THREAD, k);
// Ensure it is initialized
......@@ -2422,16 +2429,19 @@ void java_dyn_MethodType::print_signature(oop mt, outputStream* 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;
stringStream buffer(128);
print_signature(mt, &buffer);
const char* sigstr = buffer.base();
int siglen = (int) buffer.size();
if (!intern_if_not_found)
return SymbolTable::probe(sigstr, siglen);
else
return oopFactory::new_symbol(sigstr, siglen, THREAD);
Symbol *name;
if (!intern_if_not_found) {
name = SymbolTable::probe(sigstr, siglen);
} else {
name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
}
return name;
}
oop java_dyn_MethodType::rtype(oop mt) {
......@@ -2908,13 +2918,12 @@ void JavaClasses::compute_offsets() {
bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
EXCEPTION_MARK;
fieldDescriptor fd;
symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH);
TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
instanceKlassHandle h_klass (THREAD, k);
//instanceKlassHandle h_klass(klass);
symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH);
symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH);
if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) {
TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name);
return false;
}
......@@ -2935,12 +2944,12 @@ bool JavaClasses::check_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) {
EXCEPTION_MARK;
fieldDescriptor fd;
symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH);
TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
instanceKlassHandle h_klass (THREAD, k);
symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH);
symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH);
if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) {
TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
tty->print_cr("Static field %s.%s not found", klass_name, field_name);
return false;
}
......@@ -2960,12 +2969,12 @@ bool JavaClasses::check_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) {
EXCEPTION_MARK;
fieldDescriptor fd;
symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH);
TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
instanceKlassHandle h_klass (THREAD, k);
symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH);
symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH);
if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) {
TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
tty->print_cr("Static field %s.%s not found", klass_name, field_name);
return false;
}
......
......@@ -78,7 +78,7 @@ class java_lang_String : AllStatic {
static oop create_oop_from_unicode(jchar* unicode, int len, TRAPS);
static Handle create_from_str(const char* utf8_str, TRAPS);
static oop create_oop_from_str(const char* utf8_str, TRAPS);
static Handle create_from_symbol(symbolHandle symbol, TRAPS);
static Handle create_from_symbol(Symbol* symbol, TRAPS);
static Handle create_from_platform_dependent_str(const char* str, TRAPS);
static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS);
......@@ -116,8 +116,8 @@ class java_lang_String : AllStatic {
static Handle internalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '.', '/', THREAD); }
// Conversion
static symbolHandle as_symbol(Handle java_string, TRAPS);
static symbolOop as_symbol_or_null(oop java_string);
static Symbol* as_symbol(Handle java_string, TRAPS);
static Symbol* as_symbol_or_null(oop java_string);
// Testers
static bool is_instance(oop obj) {
......@@ -167,7 +167,7 @@ class java_lang_Class : AllStatic {
(*reference_klass) = KlassHandle(refk_oop);
return result;
}
static symbolOop as_signature(oop java_class, bool intern_if_not_found, TRAPS);
static Symbol* as_signature(oop java_class, bool intern_if_not_found, TRAPS);
static void print_signature(oop java_class, outputStream *st);
// Testing
static bool is_instance(oop obj) {
......@@ -1039,7 +1039,7 @@ class java_dyn_MethodType: AllStatic {
static oop ptype(oop mt, int index);
static int ptype_count(oop mt);
static symbolOop as_signature(oop mt, bool intern_if_not_found, TRAPS);
static Symbol* as_signature(oop mt, bool intern_if_not_found, TRAPS);
static void print_signature(oop mt, outputStream* st);
static bool is_instance(oop obj) {
......
......@@ -31,28 +31,33 @@
#include "utilities/hashtable.inline.hpp"
LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
: Hashtable(nof_buckets, sizeof(LoaderConstraintEntry)) {};
: Hashtable<klassOop>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
LoaderConstraintEntry* LoaderConstraintTable::new_entry(
unsigned int hash, symbolOop name,
unsigned int hash, Symbol* name,
klassOop klass, int num_loaders,
int max_loaders) {
LoaderConstraintEntry* entry;
entry = (LoaderConstraintEntry*)Hashtable::new_entry(hash, klass);
entry = (LoaderConstraintEntry*)Hashtable<klassOop>::new_entry(hash, klass);
entry->set_name(name);
entry->set_num_loaders(num_loaders);
entry->set_max_loaders(max_loaders);
return entry;
}
void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) {
// decrement name refcount before freeing
entry->name()->decrement_refcount();
Hashtable<klassOop>::free_entry(entry);
}
void LoaderConstraintTable::oops_do(OopClosure* f) {
for (int index = 0; index < table_size(); index++) {
for (LoaderConstraintEntry* probe = bucket(index);
probe != NULL;
probe = probe->next()) {
f->do_oop((oop*)(probe->name_addr()));
if (probe->klass() != NULL) {
f->do_oop((oop*)probe->klass_addr());
}
......@@ -65,27 +70,13 @@ 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
// SystemDictionary lock held. This is true even for readers as
// entries in the table could be being dynamically resized.
LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint(
symbolHandle name, Handle loader) {
Symbol* name, Handle loader) {
unsigned int hash = compute_hash(name);
int index = hash_to_index(hash);
......@@ -93,7 +84,7 @@ LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint(
while (*pp) {
LoaderConstraintEntry* p = *pp;
if (p->hash() == hash) {
if (p->name() == name()) {
if (p->name() == name) {
for (int i = p->num_loaders() - 1; i >= 0; i--) {
if (p->loader(i) == loader()) {
return pp;
......@@ -177,7 +168,6 @@ void LoaderConstraintTable::purge_loader_constraints(BoolObjectClosure* is_alive
free_entry(probe);
} else {
#ifdef ASSERT
assert(is_alive->do_object_b(probe->name()), "name should be live");
if (probe->klass() != NULL) {
assert(is_alive->do_object_b(probe->klass()), "klass should be live");
}
......@@ -194,7 +184,7 @@ 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 klass2, Handle class_loader2) {
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);
int index = hash_to_index(hash);
LoaderConstraintEntry* p;
p = new_entry(hash, class_name(), klass, 2, 2);
p = new_entry(hash, class_name, klass, 2, 2);
p->set_loaders(NEW_C_HEAP_ARRAY(oop, 2));
p->set_loader(0, class_loader1());
p->set_loader(1, class_loader2());
......@@ -244,7 +234,7 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
ResourceMark rm;
tty->print("[Adding new constraint for name: %s, loader[0]: %s,"
" loader[1]: %s ]\n",
class_name()->as_C_string(),
class_name->as_C_string(),
SystemDictionary::loader_name(class_loader1()),
SystemDictionary::loader_name(class_loader2())
);
......@@ -257,7 +247,7 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
ResourceMark rm;
tty->print("[Setting class object in existing constraint for"
" name: %s and loader %s ]\n",
class_name()->as_C_string(),
class_name->as_C_string(),
SystemDictionary::loader_name(class_loader1())
);
}
......@@ -288,7 +278,7 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
}
tty->print("[Failed to add constraint for name: %s, loader[0]: %s,"
" loader[1]: %s, Reason: %s ]\n",
class_name()->as_C_string(),
class_name->as_C_string(),
SystemDictionary::loader_name(class_loader1()),
SystemDictionary::loader_name(class_loader2()),
reason
......@@ -303,14 +293,14 @@ bool LoaderConstraintTable::add_entry(symbolHandle class_name,
// violated
bool LoaderConstraintTable::check_or_update(instanceKlassHandle k,
Handle loader,
symbolHandle name) {
Symbol* name) {
LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
if (p && p->klass() != NULL && p->klass() != k()) {
if (TraceLoaderConstraints) {
ResourceMark rm;
tty->print("[Constraint check failed for name %s, loader %s: "
"the presented class object differs from that stored ]\n",
name()->as_C_string(),
name->as_C_string(),
SystemDictionary::loader_name(loader()));
}
return false;
......@@ -321,7 +311,7 @@ bool LoaderConstraintTable::check_or_update(instanceKlassHandle k,
ResourceMark rm;
tty->print("[Updating constraint for name %s, loader %s, "
"by setting class object ]\n",
name()->as_C_string(),
name->as_C_string(),
SystemDictionary::loader_name(loader()));
}
}
......@@ -329,7 +319,7 @@ bool LoaderConstraintTable::check_or_update(instanceKlassHandle k,
}
}
klassOop LoaderConstraintTable::find_constrained_klass(symbolHandle name,
klassOop LoaderConstraintTable::find_constrained_klass(Symbol* name,
Handle loader) {
LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
if (p != NULL && p->klass() != NULL)
......@@ -442,11 +432,10 @@ void LoaderConstraintTable::verify(Dictionary* dictionary,
for (LoaderConstraintEntry* probe = bucket(cindex);
probe != NULL;
probe = probe->next()) {
guarantee(probe->name()->is_symbol(), "should be symbol");
if (probe->klass() != NULL) {
instanceKlass* ik = instanceKlass::cast(probe->klass());
guarantee(ik->name() == probe->name(), "name should match");
symbolHandle name (thread, ik->name());
Symbol* name = ik->name();
Handle loader(thread, ik->class_loader());
unsigned int d_hash = dictionary->compute_hash(name, loader);
int d_index = dictionary->hash_to_index(d_hash);
......
......@@ -31,7 +31,7 @@
class LoaderConstraintEntry;
class LoaderConstraintTable : public Hashtable {
class LoaderConstraintTable : public Hashtable<klassOop> {
friend class VMStructs;
private:
......@@ -40,39 +40,39 @@ private:
_nof_buckets = 1009 // number of buckets in hash table
};
LoaderConstraintEntry** find_loader_constraint(symbolHandle name,
LoaderConstraintEntry** find_loader_constraint(Symbol* name,
Handle loader);
public:
LoaderConstraintTable(int nof_buckets);
LoaderConstraintEntry* new_entry(unsigned int hash, symbolOop name,
LoaderConstraintEntry* new_entry(unsigned int hash, Symbol* name,
klassOop klass, int num_loaders,
int max_loaders);
void free_entry(LoaderConstraintEntry *entry);
LoaderConstraintEntry* bucket(int i) {
return (LoaderConstraintEntry*)Hashtable::bucket(i);
return (LoaderConstraintEntry*)Hashtable<klassOop>::bucket(i);
}
LoaderConstraintEntry** bucket_addr(int i) {
return (LoaderConstraintEntry**)Hashtable::bucket_addr(i);
return (LoaderConstraintEntry**)Hashtable<klassOop>::bucket_addr(i);
}
// GC support
void oops_do(OopClosure* f);
void always_strong_classes_do(OopClosure* blk);
// Check class loader constraints
bool add_entry(symbolHandle name, klassOop klass1, Handle loader1,
bool add_entry(Symbol* name, klassOop klass1, Handle loader1,
klassOop klass2, Handle loader2);
// Note: The main entry point for this module is via SystemDictionary.
// SystemDictionary::check_signature_loaders(symbolHandle signature,
// SystemDictionary::check_signature_loaders(Symbol* signature,
// Handle loader1, Handle loader2,
// bool is_method, TRAPS)
klassOop find_constrained_klass(symbolHandle name, Handle loader);
klassOop find_constrained_klass(Symbol* name, Handle loader);
// Class loader constraints
......@@ -83,7 +83,7 @@ public:
LoaderConstraintEntry** pp2, klassOop klass);
bool check_or_update(instanceKlassHandle k, Handle loader,
symbolHandle name);
Symbol* name);
void purge_loader_constraints(BoolObjectClosure* is_alive);
......@@ -94,34 +94,36 @@ public:
#endif
};
class LoaderConstraintEntry : public HashtableEntry {
class LoaderConstraintEntry : public HashtableEntry<klassOop> {
friend class VMStructs;
private:
symbolOop _name; // class name
Symbol* _name; // class name
int _num_loaders;
int _max_loaders;
oop* _loaders; // initiating loaders
public:
klassOop klass() { return (klassOop)literal(); }
klassOop* klass_addr() { return (klassOop*)literal_addr(); }
klassOop klass() { return literal(); }
klassOop* klass_addr() { return literal_addr(); }
void set_klass(klassOop k) { set_literal(k); }
LoaderConstraintEntry* next() {
return (LoaderConstraintEntry*)HashtableEntry::next();
return (LoaderConstraintEntry*)HashtableEntry<klassOop>::next();
}
LoaderConstraintEntry** next_addr() {
return (LoaderConstraintEntry**)HashtableEntry::next_addr();
return (LoaderConstraintEntry**)HashtableEntry<klassOop>::next_addr();
}
void set_next(LoaderConstraintEntry* next) {
HashtableEntry::set_next(next);
HashtableEntry<klassOop>::set_next(next);
}
symbolOop name() { return _name; }
symbolOop* name_addr() { return &_name; }
void set_name(symbolOop name) { _name = name; }
Symbol* name() { return _name; }
void set_name(Symbol* name) {
_name = name;
if (name != NULL) name->increment_refcount();
}
int num_loaders() { return _num_loaders; }
void set_num_loaders(int i) { _num_loaders = i; }
......
......@@ -31,10 +31,12 @@
// Placeholder methods
PlaceholderEntry* PlaceholderTable::new_entry(int hash, symbolOop name,
PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
oop loader, bool havesupername,
symbolOop supername) {
PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable::new_entry(hash, name);
Symbol* supername) {
PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*>::new_entry(hash, name);
// Hashtable with Symbol* literal must increment and decrement refcount.
name->increment_refcount();
entry->set_loader(loader);
entry->set_havesupername(havesupername);
entry->set_supername(supername);
......@@ -46,33 +48,40 @@ PlaceholderEntry* PlaceholderTable::new_entry(int hash, symbolOop name,
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.
// All threads examining the placeholder table must hold the
// SystemDictionary_lock, so we don't need special precautions
// on store ordering here.
void PlaceholderTable::add_entry(int index, unsigned int hash,
symbolHandle class_name, Handle class_loader,
bool havesupername, symbolHandle supername){
Symbol* class_name, Handle class_loader,
bool havesupername, Symbol* supername){
assert_locked_or_safepoint(SystemDictionary_lock);
assert(!class_name.is_null(), "adding NULL obj");
assert(class_name != NULL, "adding NULL obj");
// Both readers and writers are locked so it's safe to just
// create the placeholder and insert it in the list without a membar.
PlaceholderEntry* entry = new_entry(hash, class_name(), class_loader(), havesupername, supername());
PlaceholderEntry* entry = new_entry(hash, class_name, class_loader(), havesupername, supername);
add_entry(index, entry);
}
// Remove a placeholder object.
void PlaceholderTable::remove_entry(int index, unsigned int hash,
symbolHandle class_name,
Symbol* class_name,
Handle class_loader) {
assert_locked_or_safepoint(SystemDictionary_lock);
PlaceholderEntry** p = bucket_addr(index);
while (*p) {
PlaceholderEntry *probe = *p;
if (probe->hash() == hash && probe->equals(class_name(), class_loader())) {
if (probe->hash() == hash && probe->equals(class_name, class_loader())) {
// Delete entry
*p = probe->next();
free_entry(probe);
......@@ -83,29 +92,28 @@ void PlaceholderTable::remove_entry(int index, unsigned int hash,
}
PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash,
symbolHandle class_name,
Symbol* class_name,
Handle class_loader) {
assert_locked_or_safepoint(SystemDictionary_lock);
symbolOop class_name_ = class_name();
oop class_loader_ = class_loader();
for (PlaceholderEntry *place_probe = bucket(index);
place_probe != NULL;
place_probe = place_probe->next()) {
if (place_probe->hash() == hash &&
place_probe->equals(class_name_, class_loader_)) {
place_probe->equals(class_name, class_loader_)) {
return place_probe;
}
}
return NULL;
}
symbolOop PlaceholderTable::find_entry(int index, unsigned int hash,
symbolHandle class_name,
Symbol* PlaceholderTable::find_entry(int index, unsigned int hash,
Symbol* class_name,
Handle class_loader) {
PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader);
return (probe? probe->klass(): symbolOop(NULL));
return (probe? probe->klassname(): (Symbol*)NULL);
}
// find_and_add returns probe pointer - old or new
......@@ -113,7 +121,7 @@ symbolOop PlaceholderTable::find_entry(int index, unsigned int hash,
// If entry exists, reuse entry
// For both, push SeenThread for classloadAction
// if havesupername: this is used for circularity for instanceklass loading
PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, symbolHandle name, Handle loader, classloadAction action, symbolHandle supername, Thread* thread) {
PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, Symbol* name, Handle loader, classloadAction action, Symbol* supername, Thread* thread) {
PlaceholderEntry* probe = get_entry(index, hash, name, loader);
if (probe == NULL) {
// Nothing found, add place holder
......@@ -122,7 +130,7 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, s
} else {
if (action == LOAD_SUPER) {
probe->set_havesupername(true);
probe->set_supername(supername());
probe->set_supername(supername);
}
}
if (probe) probe->add_seen_thread(thread, action);
......@@ -145,7 +153,7 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, s
// Therefore - must always check SD first
// Ignores the case where entry is not found
void PlaceholderTable::find_and_remove(int index, unsigned int hash,
symbolHandle name, Handle loader, Thread* thread) {
Symbol* name, Handle loader, Thread* thread) {
assert_locked_or_safepoint(SystemDictionary_lock);
PlaceholderEntry *probe = get_entry(index, hash, name, loader);
if (probe != NULL) {
......@@ -158,7 +166,7 @@ void PlaceholderTable::find_and_remove(int index, unsigned int hash,
}
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) {
assert(klass() != NULL, "should have a non-null klass");
blk->do_oop((oop*)klass_addr());
assert(klassname() != NULL, "should have a non-null klass");
if (_loader != NULL) {
blk->do_oop(loader_addr());
}
if (_supername != NULL) {
blk->do_oop((oop*)supername_addr());
}
if (_instanceKlass != NULL) {
blk->do_oop((oop*)instanceKlass_addr());
}
}
// do all entries in the placeholder table
void PlaceholderTable::entries_do(void f(symbolOop, oop)) {
void PlaceholderTable::entries_do(void f(Symbol*, oop)) {
for (int index = 0; index < table_size(); index++) {
for (PlaceholderEntry* probe = bucket(index);
probe != NULL;
probe = probe->next()) {
f(probe->klass(), probe->loader());
f(probe->klassname(), probe->loader());
}
}
}
......@@ -202,7 +206,7 @@ void PlaceholderTable::entries_do(void f(symbolOop, oop)) {
#ifndef PRODUCT
// Note, doesn't append a cr
void PlaceholderEntry::print() const {
klass()->print_value();
klassname()->print_value();
if (loader() != NULL) {
tty->print(", loader ");
loader()->print_value();
......@@ -238,7 +242,6 @@ void PlaceholderEntry::verify() const {
guarantee(instanceKlass() == NULL
|| Klass::cast(instanceKlass())->oop_is_instance(),
"checking type of instanceKlass result");
klass()->verify();
}
void PlaceholderTable::verify() {
......
......@@ -34,35 +34,36 @@ class PlaceholderEntry;
// being loaded, as well as arrays of primitives.
//
class PlaceholderTable : public TwoOopHashtable {
class PlaceholderTable : public TwoOopHashtable<Symbol*> {
friend class VMStructs;
public:
PlaceholderTable(int table_size);
PlaceholderEntry* new_entry(int hash, symbolOop name, oop loader, bool havesupername, symbolOop supername);
PlaceholderEntry* new_entry(int hash, Symbol* name, oop loader, bool havesupername, Symbol* supername);
void free_entry(PlaceholderEntry* entry);
PlaceholderEntry* bucket(int i) {
return (PlaceholderEntry*)Hashtable::bucket(i);
return (PlaceholderEntry*)Hashtable<Symbol*>::bucket(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) {
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,
Handle loader, bool havesupername, symbolHandle supername);
void add_entry(int index, unsigned int hash, Symbol* name,
Handle loader, bool havesupername, Symbol* supername);
// This returns a symbolOop to match type for SystemDictionary
symbolOop find_entry(int index, unsigned int hash,
symbolHandle name, Handle loader);
// This returns a Symbol* to match type for SystemDictionary
Symbol* find_entry(int index, unsigned int hash,
Symbol* name, Handle loader);
PlaceholderEntry* get_entry(int index, unsigned int hash,
symbolHandle name, Handle loader);
Symbol* name, Handle loader);
// caller to create a placeholder entry must enumerate an action
// caller claims ownership of that action
......@@ -84,22 +85,22 @@ public:
// If no entry exists, add a placeholder entry and push SeenThread
// If entry exists, reuse entry and push SeenThread for classloadAction
PlaceholderEntry* find_and_add(int index, unsigned int hash,
symbolHandle name, Handle loader,
classloadAction action, symbolHandle supername,
Symbol* name, Handle loader,
classloadAction action, Symbol* supername,
Thread* thread);
void remove_entry(int index, unsigned int hash,
symbolHandle name, Handle loader);
Symbol* name, Handle loader);
// Remove placeholder information
void find_and_remove(int index, unsigned int hash,
symbolHandle name, Handle loader, Thread* thread);
Symbol* name, Handle loader, Thread* thread);
// GC support.
void oops_do(OopClosure* f);
// JVMTI support
void entries_do(void f(symbolOop, oop));
void entries_do(void f(Symbol*, oop));
#ifndef PRODUCT
void print();
......@@ -151,14 +152,14 @@ public:
// on store ordering here.
// The system dictionary is the only user of this class.
class PlaceholderEntry : public HashtableEntry {
class PlaceholderEntry : public HashtableEntry<Symbol*> {
friend class VMStructs;
private:
oop _loader; // initiating loader
bool _havesupername; // distinguish between null supername, and unknown
symbolOop _supername;
Symbol* _supername;
Thread* _definer; // owner of define token
klassOop _instanceKlass; // instanceKlass from successful define
SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class
......@@ -173,8 +174,7 @@ class PlaceholderEntry : public HashtableEntry {
public:
// Simple accessors, used only by SystemDictionary
symbolOop klass() const { return (symbolOop)literal(); }
symbolOop* klass_addr() { return (symbolOop*)literal_addr(); }
Symbol* klassname() const { return literal(); }
oop loader() const { return _loader; }
void set_loader(oop loader) { _loader = loader; }
......@@ -183,9 +183,11 @@ class PlaceholderEntry : public HashtableEntry {
bool havesupername() const { return _havesupername; }
void set_havesupername(bool havesupername) { _havesupername = havesupername; }
symbolOop supername() const { return _supername; }
void set_supername(symbolOop supername) { _supername = supername; }
symbolOop* supername_addr() { return &_supername; }
Symbol* supername() const { return _supername; }
void set_supername(Symbol* supername) {
_supername = supername;
if (_supername != NULL) _supername->increment_refcount();
}
Thread* definer() const {return _definer; }
void set_definer(Thread* definer) { _definer = definer; }
......@@ -204,17 +206,17 @@ class PlaceholderEntry : public HashtableEntry {
void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
PlaceholderEntry* next() const {
return (PlaceholderEntry*)HashtableEntry::next();
return (PlaceholderEntry*)HashtableEntry<Symbol*>::next();
}
PlaceholderEntry** next_addr() {
return (PlaceholderEntry**)HashtableEntry::next_addr();
return (PlaceholderEntry**)HashtableEntry<Symbol*>::next_addr();
}
// Test for equality
// Entries are unique for class/classloader name pair
bool equals(symbolOop class_name, oop class_loader) const {
return (klass() == class_name && loader() == class_loader);
bool equals(Symbol* class_name, oop class_loader) const {
return (klassname() == class_name && loader() == class_loader);
}
SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
......
......@@ -32,12 +32,12 @@
// add new entry to the table
void ResolutionErrorTable::add_entry(int index, unsigned int hash,
constantPoolHandle pool, int cp_index, symbolHandle error)
constantPoolHandle pool, int cp_index, Symbol* error)
{
assert_locked_or_safepoint(SystemDictionary_lock);
assert(!pool.is_null() && !error.is_null(), "adding NULL obj");
assert(!pool.is_null() && error != NULL, "adding NULL obj");
ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error());
ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error);
add_entry(index, entry);
}
......@@ -57,20 +57,35 @@ ResolutionErrorEntry* ResolutionErrorTable::find_entry(int index, unsigned int h
return NULL;
}
void ResolutionErrorEntry::set_error(Symbol* e) {
assert(e == NULL || _error == NULL, "cannot reset error");
_error = e;
if (_error != NULL) _error->increment_refcount();
}
// create new error entry
ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, constantPoolOop pool,
int cp_index, symbolOop error)
int cp_index, Symbol* error)
{
ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable::new_entry(hash, pool);
ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<constantPoolOop>::new_entry(hash, pool);
entry->set_cp_index(cp_index);
NOT_PRODUCT(entry->set_error(NULL);)
entry->set_error(error);
return entry;
}
void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) {
// decrement error refcount
assert(entry->error() != NULL, "error should be set");
entry->error()->decrement_refcount();
Hashtable<constantPoolOop>::free_entry(entry);
}
// create resolution error table
ResolutionErrorTable::ResolutionErrorTable(int table_size)
: Hashtable(table_size, sizeof(ResolutionErrorEntry)) {
: Hashtable<constantPoolOop>(table_size, sizeof(ResolutionErrorEntry)) {
}
// GC support
......@@ -80,7 +95,7 @@ void ResolutionErrorTable::oops_do(OopClosure* f) {
probe != NULL;
probe = probe->next()) {
assert(probe->pool() != (constantPoolOop)NULL, "resolution error table is corrupt");
assert(probe->error() != (symbolOop)NULL, "resolution error table is corrupt");
assert(probe->error() != (Symbol*)NULL, "resolution error table is corrupt");
probe->oops_do(f);
}
}
......@@ -89,20 +104,6 @@ void ResolutionErrorTable::oops_do(OopClosure* f) {
// GC support
void ResolutionErrorEntry::oops_do(OopClosure* blk) {
blk->do_oop((oop*)pool_addr());
blk->do_oop((oop*)error_addr());
}
// We must keep the symbolOop used in the error alive. The constantPoolOop will
// decide when the entry can be purged.
void ResolutionErrorTable::always_strong_classes_do(OopClosure* blk) {
for (int i = 0; i < table_size(); i++) {
for (ResolutionErrorEntry* probe = bucket(i);
probe != NULL;
probe = probe->next()) {
assert(probe->error() != (symbolOop)NULL, "resolution error table is corrupt");
blk->do_oop((oop*)probe->error_addr());
}
}
}
// Remove unloaded entries from the table
......
......@@ -33,27 +33,28 @@ class ResolutionErrorEntry;
// ResolutionError objects are used to record errors encountered during
// constant pool resolution (JVMS 5.4.3).
class ResolutionErrorTable : public Hashtable {
class ResolutionErrorTable : public Hashtable<constantPoolOop> {
public:
ResolutionErrorTable(int table_size);
ResolutionErrorEntry* new_entry(int hash, constantPoolOop pool, int cp_index, symbolOop error);
ResolutionErrorEntry* new_entry(int hash, constantPoolOop pool, int cp_index, Symbol* error);
void free_entry(ResolutionErrorEntry *entry);
ResolutionErrorEntry* bucket(int i) {
return (ResolutionErrorEntry*)Hashtable::bucket(i);
return (ResolutionErrorEntry*)Hashtable<constantPoolOop>::bucket(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) {
Hashtable::add_entry(index, (HashtableEntry*)new_entry);
Hashtable<constantPoolOop>::add_entry(index, (HashtableEntry<constantPoolOop>*)new_entry);
}
void add_entry(int index, unsigned int hash,
constantPoolHandle pool, int which, symbolHandle error);
constantPoolHandle pool, int which, Symbol* error);
// find error given the constant pool and constant pool index
......@@ -68,18 +69,15 @@ public:
// purges unloaded entries from the table
void purge_resolution_errors(BoolObjectClosure* is_alive);
// this table keeps symbolOops alive
void always_strong_classes_do(OopClosure* blk);
// GC support.
void oops_do(OopClosure* f);
};
class ResolutionErrorEntry : public HashtableEntry {
class ResolutionErrorEntry : public HashtableEntry<constantPoolOop> {
private:
int _cp_index;
symbolOop _error;
Symbol* _error;
public:
constantPoolOop pool() const { return (constantPoolOop)literal(); }
......@@ -88,16 +86,15 @@ class ResolutionErrorEntry : public HashtableEntry {
int cp_index() const { return _cp_index; }
void set_cp_index(int cp_index) { _cp_index = cp_index; }
symbolOop error() const { return _error; }
void set_error(symbolOop e) { _error = e; }
symbolOop* error_addr() { return &_error; }
Symbol* error() const { return _error; }
void set_error(Symbol* e);
ResolutionErrorEntry* next() const {
return (ResolutionErrorEntry*)HashtableEntry::next();
return (ResolutionErrorEntry*)HashtableEntry<constantPoolOop>::next();
}
ResolutionErrorEntry** next_addr() {
return (ResolutionErrorEntry**)HashtableEntry::next_addr();
return (ResolutionErrorEntry**)HashtableEntry<constantPoolOop>::next_addr();
}
// GC support
......
......@@ -27,7 +27,7 @@
#include "classfile/verifier.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbolOop.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/globalDefinitions.hpp"
......@@ -90,8 +90,7 @@ void StackMapFrame::initialize_object(
VerificationType StackMapFrame::set_locals_from_arg(
const methodHandle m, VerificationType thisKlass, TRAPS) {
symbolHandle signature(THREAD, m->signature());
SignatureStream ss(signature);
SignatureStream ss(m->signature());
int init_local_num = 0;
if (!m->is_static()) {
init_local_num++;
......@@ -118,8 +117,14 @@ VerificationType StackMapFrame::set_locals_from_arg(
case T_OBJECT:
case T_ARRAY:
{
symbolOop sig = ss.as_symbol(CHECK_(VerificationType::bogus_type()));
return VerificationType::reference_type(symbolHandle(THREAD, sig));
Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type()));
// Create another symbol to save as signature stream unreferences
// this symbol.
Symbol* sig_copy =
verifier()->create_temporary_symbol(sig, 0, sig->utf8_length(),
CHECK_(VerificationType::bogus_type()));
assert(sig_copy == sig, "symbols don't match");
return VerificationType::reference_type(sig_copy);
}
case T_INT: return VerificationType::integer_type();
case T_BYTE: return VerificationType::byte_type();
......@@ -157,7 +162,7 @@ bool StackMapFrame::is_assignable_to(
VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
for (int32_t i = 0; i < len; i++) {
bool subtype = to[i].is_assignable_from(
from[i], verifier()->current_class(), THREAD);
from[i], verifier(), THREAD);
if (!subtype) {
return false;
}
......@@ -187,7 +192,7 @@ VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
}
VerificationType top = _stack[--_stack_size];
bool subtype = type.is_assignable_from(
top, verifier()->current_class(), CHECK_(VerificationType::bogus_type()));
top, verifier(), CHECK_(VerificationType::bogus_type()));
if (!subtype) {
verifier()->verify_error(_offset, "Bad type on operand stack");
return VerificationType::bogus_type();
......@@ -203,7 +208,7 @@ VerificationType StackMapFrame::get_local(
return VerificationType::bogus_type();
}
bool subtype = type.is_assignable_from(_locals[index],
verifier()->current_class(), CHECK_(VerificationType::bogus_type()));
verifier(), CHECK_(VerificationType::bogus_type()));
if (!subtype) {
verifier()->verify_error(_offset, "Bad local variable type");
return VerificationType::bogus_type();
......@@ -221,9 +226,9 @@ void StackMapFrame::get_local_2(
return;
}
bool subtype1 = type1.is_assignable_from(
_locals[index], verifier()->current_class(), CHECK);
_locals[index], verifier(), CHECK);
bool subtype2 = type2.is_assignable_from(
_locals[index+1], verifier()->current_class(), CHECK);
_locals[index+1], verifier(), CHECK);
if (!subtype1 || !subtype2) {
verifier()->verify_error(_offset, "Bad local variable type");
return;
......
......@@ -177,8 +177,7 @@ class StackMapFrame : public ResourceObj {
if (_stack_size != 0) {
VerificationType top = _stack[_stack_size - 1];
bool subtype = type.is_assignable_from(
top, verifier()->current_class(),
CHECK_(VerificationType::bogus_type()));
top, verifier(), CHECK_(VerificationType::bogus_type()));
if (subtype) {
_stack_size --;
NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
......@@ -194,11 +193,9 @@ class StackMapFrame : public ResourceObj {
assert(type2.is_long() || type2.is_double(), "must be long/double_2");
if (_stack_size >= 2) {
VerificationType top1 = _stack[_stack_size - 1];
bool subtype1 = type1.is_assignable_from(
top1, verifier()->current_class(), CHECK);
bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK);
VerificationType top2 = _stack[_stack_size - 2];
bool subtype2 = type2.is_assignable_from(
top2, verifier()->current_class(), CHECK);
bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK);
if (subtype1 && subtype2) {
_stack_size -= 2;
NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
......
......@@ -184,8 +184,7 @@ VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) {
_stream->stackmap_format_error("bad class index", THREAD);
return VerificationType::bogus_type();
}
return VerificationType::reference_type(
symbolHandle(THREAD, _cp->klass_name_at(class_index)));
return VerificationType::reference_type(_cp->klass_name_at(class_index));
}
if (tag == ITEM_UninitializedThis) {
if (flags != NULL) {
......
......@@ -31,7 +31,6 @@
#include "memory/gcLocker.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oop.inline2.hpp"
#include "oops/symbolKlass.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/hashtable.inline.hpp"
......@@ -39,14 +38,97 @@
SymbolTable* SymbolTable::_the_table = NULL;
Symbol* SymbolTable::allocate_symbol(const u1* name, int len, TRAPS) {
// Don't allow symbols to be created which cannot fit in a Symbol*.
if (len > Symbol::max_length()) {
THROW_MSG_0(vmSymbols::java_lang_InternalError(),
"name is too long to represent");
}
Symbol* sym = new (len) Symbol(name, len);
assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
return sym;
}
bool SymbolTable::allocate_symbols(int names_count, const u1** names,
int* lengths, Symbol** syms, TRAPS) {
for (int i = 0; i< names_count; i++) {
if (lengths[i] > Symbol::max_length()) {
THROW_MSG_0(vmSymbols::java_lang_InternalError(),
"name is too long to represent");
}
}
for (int i = 0; i< names_count; i++) {
int len = lengths[i];
syms[i] = new (len) Symbol(names[i], len);
assert(syms[i] != NULL, "new should call vm_exit_out_of_memory if "
"C_HEAP is exhausted");
}
return true;
}
// Call function for all symbols in the symbol table.
void SymbolTable::symbols_do(SymbolClosure *cl) {
const int n = the_table()->table_size();
for (int i = 0; i < n; i++) {
for (HashtableEntry<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.
symbolOop SymbolTable::lookup(int index, const char* name,
Symbol* SymbolTable::lookup(int index, const char* name,
int len, unsigned int hash) {
for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) {
for (HashtableEntry<Symbol*>* e = bucket(index); e != NULL; e = e->next()) {
if (e->hash() == hash) {
symbolOop sym = symbolOop(e->literal());
Symbol* sym = e->literal();
if (sym->equals(name, len)) {
// something is referencing this symbol now.
sym->increment_refcount();
return sym;
}
}
......@@ -62,11 +144,11 @@ symbolOop SymbolTable::lookup(int index, const char* name,
// entries in the symbol table during normal execution (only during
// safepoints).
symbolOop SymbolTable::lookup(const char* name, int len, TRAPS) {
Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
unsigned int hashValue = hash_symbol(name, len);
int index = the_table()->hash_to_index(hashValue);
symbolOop s = the_table()->lookup(index, name, len, hashValue);
Symbol* s = the_table()->lookup(index, name, len, hashValue);
// Found
if (s != NULL) return s;
......@@ -75,7 +157,7 @@ symbolOop SymbolTable::lookup(const char* name, int len, TRAPS) {
return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL);
}
symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) {
Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
char* buffer;
int index, len;
unsigned int hashValue;
......@@ -87,7 +169,7 @@ symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) {
len = end - begin;
hashValue = hash_symbol(name, len);
index = the_table()->hash_to_index(hashValue);
symbolOop s = the_table()->lookup(index, name, len, hashValue);
Symbol* s = the_table()->lookup(index, name, len, hashValue);
// Found
if (s != NULL) return s;
......@@ -111,18 +193,19 @@ symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) {
return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL);
}
symbolOop SymbolTable::lookup_only(const char* name, int len,
Symbol* SymbolTable::lookup_only(const char* name, int len,
unsigned int& hash) {
hash = hash_symbol(name, len);
int index = the_table()->hash_to_index(hash);
return the_table()->lookup(index, name, len, hash);
Symbol* s = the_table()->lookup(index, name, len, hash);
return s;
}
// Suggestion: Push unicode-based lookup all the way into the hashing
// and probing logic, so there is no need for convert_to_utf8 until
// an actual new symbolOop is created.
symbolOop SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
// an actual new Symbol* is created.
Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
char stack_buf[128];
if (utf8_length < (int) sizeof(stack_buf)) {
......@@ -137,7 +220,7 @@ symbolOop SymbolTable::lookup_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) {
int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
char stack_buf[128];
......@@ -163,25 +246,23 @@ void SymbolTable::add(constantPoolHandle cp, int names_count,
// do it the hard way
for (int i=0; i<names_count; 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);
cp->symbol_at_put(cp_indices[i], sym);
}
}
}
symbolOop SymbolTable::basic_add(int index, u1 *name, int len,
Symbol* SymbolTable::basic_add(int index, u1 *name, int len,
unsigned int hashValue, TRAPS) {
assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
"proposed name of symbol must be stable");
// We assume that lookup() has been called already, that it failed,
// and symbol was not found. We create the symbol here.
symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part();
symbolOop s_oop = sk->allocate_symbol(name, len, CHECK_NULL);
symbolHandle sym (THREAD, s_oop);
Symbol* sym = allocate_symbol(name, len, CHECK_NULL);
// Allocation must be done before grapping the SymbolTable_lock lock
// Allocation must be done before grabbing the SymbolTable_lock lock
MutexLocker ml(SymbolTable_lock, THREAD);
assert(sym->equals((char*)name, len), "symbol must be properly initialized");
......@@ -189,51 +270,51 @@ symbolOop SymbolTable::basic_add(int index, u1 *name, int len,
// Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol.
symbolOop test = lookup(index, (char*)name, len, hashValue);
Symbol* test = lookup(index, (char*)name, len, hashValue);
if (test != NULL) {
// A race occurred and another thread introduced the symbol, this one
// will be dropped and collected.
delete sym;
assert(test->refcount() != 0, "lookup should have incremented the count");
return test;
}
HashtableEntry* entry = new_entry(hashValue, sym());
HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym);
sym->increment_refcount();
add_entry(index, entry);
return sym();
return sym;
}
bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
const char** names, int* lengths,
int* cp_indices, unsigned int* hashValues,
TRAPS) {
symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part();
symbolOop sym_oops[symbol_alloc_batch_size];
bool allocated = sk->allocate_symbols(names_count, names, lengths,
sym_oops, CHECK_false);
Symbol* syms[symbol_alloc_batch_size];
bool allocated = allocate_symbols(names_count, (const u1**)names, lengths,
syms, CHECK_false);
if (!allocated) {
return false;
}
symbolHandle syms[symbol_alloc_batch_size];
int i;
for (i=0; i<names_count; i++) {
syms[i] = symbolHandle(THREAD, sym_oops[i]);
}
// Allocation must be done before grabbing the SymbolTable_lock lock
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");
// Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol.
int index = hash_to_index(hashValues[i]);
symbolOop test = lookup(index, names[i], lengths[i], hashValues[i]);
Symbol* test = lookup(index, names[i], lengths[i], hashValues[i]);
if (test != NULL) {
// A race occurred and another thread introduced the symbol, this one
// will be dropped and collected. Use test instead.
cp->symbol_at_put(cp_indices[i], test);
assert(test->refcount() != 0, "lookup should have incremented the count");
delete syms[i];
} else {
symbolOop sym = syms[i]();
HashtableEntry* entry = new_entry(hashValues[i], sym);
Symbol* sym = syms[i];
HashtableEntry<Symbol*>* entry = new_entry(hashValues[i], sym);
sym->increment_refcount(); // increment refcount in external hashtable
add_entry(index, entry);
cp->symbol_at_put(cp_indices[i], sym);
}
......@@ -245,12 +326,10 @@ bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
void SymbolTable::verify() {
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()) {
symbolOop s = symbolOop(p->literal());
Symbol* s = (Symbol*)(p->literal());
guarantee(s != NULL, "symbol is NULL");
s->verify();
guarantee(s->is_perm(), "symbol not in permspace");
unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length());
guarantee(p->hash() == h, "broken hash in symbol table entry");
guarantee(the_table()->hash_to_index(h) == i,
......@@ -279,10 +358,14 @@ void SymbolTable::print_histogram() {
int total = 0;
int max_symbols = 0;
int out_of_range = 0;
int memory_total = 0;
int count = 0;
for (i = 0; i < the_table()->table_size(); i++) {
HashtableEntry* p = the_table()->bucket(i);
HashtableEntry<Symbol*>* p = the_table()->bucket(i);
for ( ; p != NULL; p = p->next()) {
int counter = symbolOop(p->literal())->utf8_length();
memory_total += p->literal()->object_size();
count++;
int counter = p->literal()->utf8_length();
total += counter;
if (counter < results_length) {
results[counter]++;
......@@ -293,6 +376,17 @@ void SymbolTable::print_histogram() {
}
}
tty->print_cr("Symbol Table:");
tty->print_cr("Total number of symbols %5d", count);
tty->print_cr("Total size in memory %5dK",
(memory_total*HeapWordSize)/1024);
tty->print_cr("Total counted %5d", symbols_counted);
tty->print_cr("Total removed %5d", symbols_removed);
if (symbols_counted > 0) {
tty->print_cr("Percent removed %3.2f",
((float)symbols_removed/(float)symbols_counted)* 100);
}
tty->print_cr("Reference counts %5d", Symbol::_total_count);
tty->print_cr("Histogram of symbol length:");
tty->print_cr("%8s %5d", "Total ", total);
tty->print_cr("%8s %5d", "Maximum", max_symbols);
tty->print_cr("%8s %3.2f", "Average",
......@@ -304,24 +398,43 @@ void SymbolTable::print_histogram() {
tty->print_cr("%6d %10d", i, results[i]);
}
}
int line_length = 70;
tty->print_cr("%s %30s", " Length", "Number chains that length");
for (i = 0; i < results_length; i++) {
if (results[i] > 0) {
tty->print("%4d", i);
for (j = 0; (j < results[i]) && (j < line_length); j++) {
tty->print("%1s", "*");
if (Verbose) {
int line_length = 70;
tty->print_cr("%s %30s", " Length", "Number chains that length");
for (i = 0; i < results_length; i++) {
if (results[i] > 0) {
tty->print("%4d", i);
for (j = 0; (j < results[i]) && (j < line_length); j++) {
tty->print("%1s", "*");
}
if (j == line_length) {
tty->print("%1s", "+");
}
tty->cr();
}
if (j == line_length) {
tty->print("%1s", "+");
}
tty->cr();
}
}
tty->print_cr(" %s %d: %d\n", "Number chains longer than",
results_length, out_of_range);
}
void SymbolTable::print() {
for (int i = 0; i < the_table()->table_size(); ++i) {
HashtableEntry<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
// --------------------------------------------------------------------------
......@@ -396,7 +509,7 @@ StringTable* StringTable::_the_table = NULL;
oop StringTable::lookup(int index, jchar* name,
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 (java_lang_String::equals(l->literal(), name, len)) {
return l->literal();
......@@ -436,13 +549,13 @@ oop StringTable::basic_add(int index, Handle string_or_null, jchar* name,
return test;
}
HashtableEntry* entry = new_entry(hashValue, string());
HashtableEntry<oop>* entry = new_entry(hashValue, string());
add_entry(index, entry);
return string();
}
oop StringTable::lookup(symbolOop symbol) {
oop StringTable::lookup(Symbol* symbol) {
ResourceMark rm;
int length;
jchar* chars = symbol->as_unicode(length);
......@@ -466,7 +579,7 @@ oop StringTable::intern(Handle string_or_null, jchar* name,
hashValue, CHECK_NULL);
}
oop StringTable::intern(symbolOop symbol, TRAPS) {
oop StringTable::intern(Symbol* symbol, TRAPS) {
if (symbol == NULL) return NULL;
ResourceMark rm(THREAD);
int length;
......@@ -500,9 +613,50 @@ oop StringTable::intern(const char* utf8_string, TRAPS) {
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() {
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()) {
oop s = p->literal();
guarantee(s != NULL, "interned string is NULL");
......
......@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/verificationType.hpp"
#include "classfile/verifier.hpp"
VerificationType VerificationType::from_tag(u1 tag) {
switch (tag) {
......@@ -41,7 +42,8 @@ VerificationType VerificationType::from_tag(u1 tag) {
}
bool VerificationType::is_reference_assignable_from(
const VerificationType& from, instanceKlassHandle context, TRAPS) const {
const VerificationType& from, ClassVerifier* context, TRAPS) const {
instanceKlassHandle klass = context->current_class();
if (from.is_null()) {
// null is assignable to any reference
return true;
......@@ -56,8 +58,8 @@ bool VerificationType::is_reference_assignable_from(
return true;
}
klassOop obj = SystemDictionary::resolve_or_fail(
name_handle(), Handle(THREAD, context->class_loader()),
Handle(THREAD, context->protection_domain()), true, CHECK_false);
name(), Handle(THREAD, klass->class_loader()),
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
KlassHandle this_class(THREAD, obj);
if (this_class->is_interface()) {
......@@ -66,13 +68,13 @@ bool VerificationType::is_reference_assignable_from(
return true;
} else if (from.is_object()) {
klassOop from_class = SystemDictionary::resolve_or_fail(
from.name_handle(), Handle(THREAD, context->class_loader()),
Handle(THREAD, context->protection_domain()), true, CHECK_false);
from.name(), Handle(THREAD, klass->class_loader()),
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
return instanceKlass::cast(from_class)->is_subclass_of(this_class());
}
} else if (is_array() && from.is_array()) {
VerificationType comp_this = get_component(CHECK_false);
VerificationType comp_from = from.get_component(CHECK_false);
VerificationType comp_this = get_component(context, CHECK_false);
VerificationType comp_from = from.get_component(context, CHECK_false);
if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
return comp_this.is_assignable_from(comp_from, context, CHECK_false);
}
......@@ -80,9 +82,9 @@ bool VerificationType::is_reference_assignable_from(
return false;
}
VerificationType VerificationType::get_component(TRAPS) const {
VerificationType VerificationType::get_component(ClassVerifier *context, TRAPS) const {
assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
symbolOop component;
Symbol* component;
switch (name()->byte_at(1)) {
case 'Z': return VerificationType(Boolean);
case 'B': return VerificationType(Byte);
......@@ -93,12 +95,12 @@ VerificationType VerificationType::get_component(TRAPS) const {
case 'F': return VerificationType(Float);
case 'D': return VerificationType(Double);
case '[':
component = SymbolTable::lookup(
component = context->create_temporary_symbol(
name(), 1, name()->utf8_length(),
CHECK_(VerificationType::bogus_type()));
return VerificationType::reference_type(component);
case 'L':
component = SymbolTable::lookup(
component = context->create_temporary_symbol(
name(), 2, name()->utf8_length() - 1,
CHECK_(VerificationType::bogus_type()));
return VerificationType::reference_type(component);
......
......@@ -29,7 +29,7 @@
#include "memory/allocation.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbolOop.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.hpp"
#include "runtime/signature.hpp"
......@@ -47,6 +47,8 @@ enum {
ITEM_Bogus = (uint)-1
};
class ClassVerifier;
class VerificationType VALUE_OBJ_CLASS_SPEC {
private:
// Least significant bits of _handle are always 0, so we use these as
......@@ -56,7 +58,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
// will catch this and we'll have to add a descriminator tag to this
// structure.
union {
symbolOop* _handle;
Symbol* _sym;
uintptr_t _data;
} _u;
......@@ -73,7 +75,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
TypeMask = 0x00000003,
// Topmost types encoding
Reference = 0x0, // _handle contains the name
Reference = 0x0, // _sym contains the name
Primitive = 0x1, // see below for primitive list
Uninitialized = 0x2, // 0x00ffff00 contains bci
TypeQuery = 0x3, // Meta-types used for category testing
......@@ -85,7 +87,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
Category2_2ndFlag = 0x04, // Second word of a two-word value
// special reference values
Null = 0x00000000, // A reference with a 0 handle is null
Null = 0x00000000, // A reference with a 0 sym is null
// Primitives categories (the second byte determines the category)
Category1 = (Category1Flag << 1 * BitsPerByte) | Primitive,
......@@ -152,17 +154,14 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
static VerificationType category2_2nd_check()
{ return VerificationType(Category2_2ndQuery); }
// For reference types, store the actual oop* handle
static VerificationType reference_type(symbolHandle sh) {
assert(((uintptr_t)sh.raw_value() & 0x3) == 0, "Oops must be aligned");
// For reference types, store the actual Symbol
static VerificationType reference_type(Symbol* sh) {
assert(((uintptr_t)sh & 0x3) == 0, "Oops must be aligned");
// If the above assert fails in the future because oop* isn't aligned,
// then this type encoding system will have to change to have a tag value
// to descriminate between oops and primitives.
return VerificationType((uintptr_t)((symbolOop*)sh.raw_value()));
return VerificationType((uintptr_t)sh);
}
static VerificationType reference_type(symbolOop s, TRAPS)
{ return reference_type(symbolHandle(THREAD, s)); }
static VerificationType uninitialized_type(u2 bci)
{ return VerificationType(bci << 1 * BitsPerByte | Uninitialized); }
static VerificationType uninitialized_this_type()
......@@ -242,13 +241,9 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
return ((_u._data & BciMask) >> 1 * BitsPerByte);
}
symbolHandle name_handle() const {
assert(is_reference() && !is_null(), "Must be a non-null reference");
return symbolHandle(_u._handle, true);
}
symbolOop name() const {
Symbol* name() const {
assert(is_reference() && !is_null(), "Must be a non-null reference");
return *(_u._handle);
return _u._sym;
}
bool equals(const VerificationType& t) const {
......@@ -269,7 +264,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
// is assignable to another. Returns true if one can assign 'from' to
// this.
bool is_assignable_from(
const VerificationType& from, instanceKlassHandle context, TRAPS) const {
const VerificationType& from, ClassVerifier* context, TRAPS) const {
if (equals(from) || is_bogus()) {
return true;
} else {
......@@ -298,7 +293,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
}
}
VerificationType get_component(TRAPS) const;
VerificationType get_component(ClassVerifier* context, TRAPS) const;
int dimensions() const {
assert(is_array(), "Must be an array");
......@@ -312,7 +307,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
private:
bool is_reference_assignable_from(
const VerificationType&, instanceKlassHandle, TRAPS) const;
const VerificationType&, ClassVerifier*, TRAPS) const;
};
#endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册