mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
7168280: Eliminate the generic signature index slot from field array for field without generic signature
Only allocate the generic signature index slot in the field array for field with generic signature attribute. Reviewed-by: coleenp, dlong
This commit is contained in:
parent
57692966b7
commit
31e63d5a3a
12 changed files with 199 additions and 53 deletions
|
@ -81,6 +81,7 @@ public class AccessFlags implements /* imports */ ClassConstants {
|
||||||
// field flags
|
// field flags
|
||||||
public boolean fieldAccessWatched () { return (flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; }
|
public boolean fieldAccessWatched () { return (flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; }
|
||||||
public boolean fieldModificationWatched() { return (flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
|
public boolean fieldModificationWatched() { return (flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
|
||||||
|
public boolean fieldHasGenericSignature() { return (flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE)!= 0; }
|
||||||
|
|
||||||
public void printOn(PrintStream tty) {
|
public void printOn(PrintStream tty) {
|
||||||
// prints only .class flags and not the hotspot internal flags
|
// prints only .class flags and not the hotspot internal flags
|
||||||
|
|
|
@ -50,7 +50,6 @@ public class InstanceKlass extends Klass {
|
||||||
private static int INITVAL_INDEX_OFFSET;
|
private static int INITVAL_INDEX_OFFSET;
|
||||||
private static int LOW_OFFSET;
|
private static int LOW_OFFSET;
|
||||||
private static int HIGH_OFFSET;
|
private static int HIGH_OFFSET;
|
||||||
private static int GENERIC_SIGNATURE_INDEX_OFFSET;
|
|
||||||
private static int FIELD_SLOTS;
|
private static int FIELD_SLOTS;
|
||||||
|
|
||||||
// ClassState constants
|
// ClassState constants
|
||||||
|
@ -99,7 +98,6 @@ public class InstanceKlass extends Klass {
|
||||||
INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
|
INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
|
||||||
LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue();
|
LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue();
|
||||||
HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue();
|
HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue();
|
||||||
GENERIC_SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::generic_signature_offset").intValue();
|
|
||||||
FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
|
FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
|
||||||
// read ClassState constants
|
// read ClassState constants
|
||||||
CLASS_STATE_UNPARSABLE_BY_GC = db.lookupIntConstant("instanceKlass::unparsable_by_gc").intValue();
|
CLASS_STATE_UNPARSABLE_BY_GC = db.lookupIntConstant("instanceKlass::unparsable_by_gc").intValue();
|
||||||
|
@ -279,7 +277,25 @@ public class InstanceKlass extends Klass {
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getFieldGenericSignatureIndex(int index) {
|
public short getFieldGenericSignatureIndex(int index) {
|
||||||
return getFields().getShortAt(index * FIELD_SLOTS + GENERIC_SIGNATURE_INDEX_OFFSET);
|
int len = (int)getFields().getLength();
|
||||||
|
int allFieldsCount = getAllFieldsCount();
|
||||||
|
int generic_signature_slot = allFieldsCount * FIELD_SLOTS;
|
||||||
|
for (int i = 0; i < allFieldsCount; i++) {
|
||||||
|
short flags = getFieldAccessFlags(i);
|
||||||
|
AccessFlags access = new AccessFlags(flags);
|
||||||
|
if (i == index) {
|
||||||
|
if (access.fieldHasGenericSignature()) {
|
||||||
|
return getFields().getShortAt(generic_signature_slot);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (access.fieldHasGenericSignature()) {
|
||||||
|
generic_signature_slot ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Symbol getFieldGenericSignature(int index) {
|
public Symbol getFieldGenericSignature(int index) {
|
||||||
|
@ -309,7 +325,18 @@ public class InstanceKlass extends Klass {
|
||||||
public ObjArray getTransitiveInterfaces() { return (ObjArray) transitiveInterfaces.getValue(this); }
|
public ObjArray getTransitiveInterfaces() { return (ObjArray) transitiveInterfaces.getValue(this); }
|
||||||
public TypeArray getFields() { return (TypeArray) fields.getValue(this); }
|
public TypeArray getFields() { return (TypeArray) fields.getValue(this); }
|
||||||
public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); }
|
public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); }
|
||||||
public int getAllFieldsCount() { return (int)getFields().getLength() / FIELD_SLOTS; }
|
public int getAllFieldsCount() {
|
||||||
|
int len = (int)getFields().getLength();
|
||||||
|
int allFieldsCount = 0;
|
||||||
|
for (; allFieldsCount*FIELD_SLOTS < len; allFieldsCount++) {
|
||||||
|
short flags = getFieldAccessFlags(allFieldsCount);
|
||||||
|
AccessFlags access = new AccessFlags(flags);
|
||||||
|
if (access.fieldHasGenericSignature()) {
|
||||||
|
len --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allFieldsCount;
|
||||||
|
}
|
||||||
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
|
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
|
||||||
public Oop getClassLoader() { return classLoader.getValue(this); }
|
public Oop getClassLoader() { return classLoader.getValue(this); }
|
||||||
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
|
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
|
||||||
|
|
|
@ -153,6 +153,8 @@ public interface ClassConstants
|
||||||
public static final long JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000;
|
public static final long JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000;
|
||||||
// field modification is watched by JVMTI
|
// field modification is watched by JVMTI
|
||||||
public static final long JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000;
|
public static final long JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000;
|
||||||
|
// field has generic signature
|
||||||
|
public static final long JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800;
|
||||||
|
|
||||||
// flags accepted by set_field_flags
|
// flags accepted by set_field_flags
|
||||||
public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS;
|
public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS;
|
||||||
|
|
|
@ -1082,12 +1082,36 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||||
|
|
||||||
int num_injected = 0;
|
int num_injected = 0;
|
||||||
InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected);
|
InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected);
|
||||||
|
int total_fields = length + num_injected;
|
||||||
|
|
||||||
// Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index]
|
// The field array starts with tuples of shorts
|
||||||
typeArrayOop new_fields = oopFactory::new_permanent_shortArray((length + num_injected) * FieldInfo::field_slots, CHECK_(nullHandle));
|
// [access, name index, sig index, initial value index, byte offset].
|
||||||
typeArrayHandle fields(THREAD, new_fields);
|
// A generic signature slot only exists for field with generic
|
||||||
|
// signature attribute. And the access flag is set with
|
||||||
|
// JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE for that field. The generic
|
||||||
|
// signature slots are at the end of the field array and after all
|
||||||
|
// other fields data.
|
||||||
|
//
|
||||||
|
// f1: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||||
|
// f2: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||||
|
// ...
|
||||||
|
// fn: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||||
|
// [generic signature index]
|
||||||
|
// [generic signature index]
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// Allocate a temporary resource array for field data. For each field,
|
||||||
|
// a slot is reserved in the temporary array for the generic signature
|
||||||
|
// index. After parsing all fields, the data are copied to a permanent
|
||||||
|
// array and any unused slots will be discarded.
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
u2* fa = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||||
|
THREAD, u2, total_fields * (FieldInfo::field_slots + 1));
|
||||||
|
|
||||||
typeArrayHandle field_annotations;
|
typeArrayHandle field_annotations;
|
||||||
|
// The generic signature slots start after all other fields' data.
|
||||||
|
int generic_signature_slot = total_fields * FieldInfo::field_slots;
|
||||||
|
int num_generic_signature = 0;
|
||||||
for (int n = 0; n < length; n++) {
|
for (int n = 0; n < length; n++) {
|
||||||
cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count
|
cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count
|
||||||
|
|
||||||
|
@ -1135,14 +1159,19 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||||
if (is_synthetic) {
|
if (is_synthetic) {
|
||||||
access_flags.set_is_synthetic();
|
access_flags.set_is_synthetic();
|
||||||
}
|
}
|
||||||
|
if (generic_signature_index != 0) {
|
||||||
|
access_flags.set_field_has_generic_signature();
|
||||||
|
fa[generic_signature_slot] = generic_signature_index;
|
||||||
|
generic_signature_slot ++;
|
||||||
|
num_generic_signature ++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldInfo* field = FieldInfo::from_field_array(fields(), n);
|
FieldInfo* field = FieldInfo::from_field_array(fa, n);
|
||||||
field->initialize(access_flags.as_short(),
|
field->initialize(access_flags.as_short(),
|
||||||
name_index,
|
name_index,
|
||||||
signature_index,
|
signature_index,
|
||||||
constantvalue_index,
|
constantvalue_index,
|
||||||
generic_signature_index,
|
|
||||||
0);
|
0);
|
||||||
|
|
||||||
BasicType type = cp->basic_type_for_signature_at(signature_index);
|
BasicType type = cp->basic_type_for_signature_at(signature_index);
|
||||||
|
@ -1155,8 +1184,8 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||||
field->set_offset(atype);
|
field->set_offset(atype);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_injected != 0) {
|
|
||||||
int index = length;
|
int index = length;
|
||||||
|
if (num_injected != 0) {
|
||||||
for (int n = 0; n < num_injected; n++) {
|
for (int n = 0; n < num_injected; n++) {
|
||||||
// Check for duplicates
|
// Check for duplicates
|
||||||
if (injected[n].may_be_java) {
|
if (injected[n].may_be_java) {
|
||||||
|
@ -1164,7 +1193,7 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||||
Symbol* signature = injected[n].signature();
|
Symbol* signature = injected[n].signature();
|
||||||
bool duplicate = false;
|
bool duplicate = false;
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
FieldInfo* f = FieldInfo::from_field_array(fields(), i);
|
FieldInfo* f = FieldInfo::from_field_array(fa, i);
|
||||||
if (name == cp->symbol_at(f->name_index()) &&
|
if (name == cp->symbol_at(f->name_index()) &&
|
||||||
signature == cp->symbol_at(f->signature_index())) {
|
signature == cp->symbol_at(f->signature_index())) {
|
||||||
// Symbol is desclared in Java so skip this one
|
// Symbol is desclared in Java so skip this one
|
||||||
|
@ -1179,12 +1208,11 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Injected field
|
// Injected field
|
||||||
FieldInfo* field = FieldInfo::from_field_array(fields(), index);
|
FieldInfo* field = FieldInfo::from_field_array(fa, index);
|
||||||
field->initialize(JVM_ACC_FIELD_INTERNAL,
|
field->initialize(JVM_ACC_FIELD_INTERNAL,
|
||||||
injected[n].name_index,
|
injected[n].name_index,
|
||||||
injected[n].signature_index,
|
injected[n].signature_index,
|
||||||
0,
|
0,
|
||||||
0,
|
|
||||||
0);
|
0);
|
||||||
|
|
||||||
BasicType type = FieldType::basic_type(injected[n].signature());
|
BasicType type = FieldType::basic_type(injected[n].signature());
|
||||||
|
@ -1197,17 +1225,27 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||||
field->set_offset(atype);
|
field->set_offset(atype);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (index < length + num_injected) {
|
// Now copy the fields' data from the temporary resource array.
|
||||||
// sometimes injected fields already exist in the Java source so
|
// Sometimes injected fields already exist in the Java source so
|
||||||
// the fields array could be too long. In that case trim the
|
// the fields array could be too long. In that case the
|
||||||
// fields array.
|
// fields array is trimed. Also unused slots that were reserved
|
||||||
new_fields = oopFactory::new_permanent_shortArray(index * FieldInfo::field_slots, CHECK_(nullHandle));
|
// for generic signature indexes are discarded.
|
||||||
for (int i = 0; i < index * FieldInfo::field_slots; i++) {
|
typeArrayOop new_fields = oopFactory::new_permanent_shortArray(
|
||||||
new_fields->short_at_put(i, fields->short_at(i));
|
index * FieldInfo::field_slots + num_generic_signature,
|
||||||
|
CHECK_(nullHandle));
|
||||||
|
typeArrayHandle fields(THREAD, new_fields);
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (; i < index * FieldInfo::field_slots; i++) {
|
||||||
|
new_fields->short_at_put(i, fa[i]);
|
||||||
}
|
}
|
||||||
fields = new_fields;
|
for (int j = total_fields * FieldInfo::field_slots;
|
||||||
|
j < generic_signature_slot; j++) {
|
||||||
|
new_fields->short_at_put(i++, fa[j]);
|
||||||
}
|
}
|
||||||
|
assert(i == new_fields->length(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_need_verify && length > 1) {
|
if (_need_verify && length > 1) {
|
||||||
|
|
|
@ -2763,7 +2763,7 @@ class ClassStatistics: AllStatic {
|
||||||
class_size += ik->local_interfaces()->size();
|
class_size += ik->local_interfaces()->size();
|
||||||
class_size += ik->transitive_interfaces()->size();
|
class_size += ik->transitive_interfaces()->size();
|
||||||
// We do not have to count implementors, since we only store one!
|
// We do not have to count implementors, since we only store one!
|
||||||
class_size += ik->all_fields_count() * FieldInfo::field_slots;
|
class_size += ik->fields()->length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,7 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
|
||||||
initval_index_offset = 3,
|
initval_index_offset = 3,
|
||||||
low_offset = 4,
|
low_offset = 4,
|
||||||
high_offset = 5,
|
high_offset = 5,
|
||||||
generic_signature_offset = 6,
|
field_slots = 6
|
||||||
field_slots = 7
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -60,29 +59,28 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
|
||||||
void set_name_index(u2 val) { _shorts[name_index_offset] = val; }
|
void set_name_index(u2 val) { _shorts[name_index_offset] = val; }
|
||||||
void set_signature_index(u2 val) { _shorts[signature_index_offset] = val; }
|
void set_signature_index(u2 val) { _shorts[signature_index_offset] = val; }
|
||||||
void set_initval_index(u2 val) { _shorts[initval_index_offset] = val; }
|
void set_initval_index(u2 val) { _shorts[initval_index_offset] = val; }
|
||||||
void set_generic_signature_index(u2 val) { _shorts[generic_signature_offset] = val; }
|
|
||||||
|
|
||||||
u2 name_index() const { return _shorts[name_index_offset]; }
|
u2 name_index() const { return _shorts[name_index_offset]; }
|
||||||
u2 signature_index() const { return _shorts[signature_index_offset]; }
|
u2 signature_index() const { return _shorts[signature_index_offset]; }
|
||||||
u2 initval_index() const { return _shorts[initval_index_offset]; }
|
u2 initval_index() const { return _shorts[initval_index_offset]; }
|
||||||
u2 generic_signature_index() const { return _shorts[generic_signature_offset]; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static FieldInfo* from_field_array(typeArrayOop fields, int index) {
|
static FieldInfo* from_field_array(typeArrayOop fields, int index) {
|
||||||
return ((FieldInfo*)fields->short_at_addr(index * field_slots));
|
return ((FieldInfo*)fields->short_at_addr(index * field_slots));
|
||||||
}
|
}
|
||||||
|
static FieldInfo* from_field_array(u2* fields, int index) {
|
||||||
|
return ((FieldInfo*)(fields + index * field_slots));
|
||||||
|
}
|
||||||
|
|
||||||
void initialize(u2 access_flags,
|
void initialize(u2 access_flags,
|
||||||
u2 name_index,
|
u2 name_index,
|
||||||
u2 signature_index,
|
u2 signature_index,
|
||||||
u2 initval_index,
|
u2 initval_index,
|
||||||
u2 generic_signature_index,
|
|
||||||
u4 offset) {
|
u4 offset) {
|
||||||
_shorts[access_flags_offset] = access_flags;
|
_shorts[access_flags_offset] = access_flags;
|
||||||
_shorts[name_index_offset] = name_index;
|
_shorts[name_index_offset] = name_index;
|
||||||
_shorts[signature_index_offset] = signature_index;
|
_shorts[signature_index_offset] = signature_index;
|
||||||
_shorts[initval_index_offset] = initval_index;
|
_shorts[initval_index_offset] = initval_index;
|
||||||
_shorts[generic_signature_offset] = generic_signature_index;
|
|
||||||
set_offset(offset);
|
set_offset(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,14 +103,6 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
|
||||||
return cp->symbol_at(index);
|
return cp->symbol_at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* generic_signature(constantPoolHandle cp) const {
|
|
||||||
int index = generic_signature_index();
|
|
||||||
if (index == 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return cp->symbol_at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; }
|
void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; }
|
||||||
void set_offset(u4 val) {
|
void set_offset(u4 val) {
|
||||||
_shorts[low_offset] = extract_low_short_from_int(val);
|
_shorts[low_offset] = extract_low_short_from_int(val);
|
||||||
|
|
|
@ -42,21 +42,57 @@ class FieldStreamBase : public StackObj {
|
||||||
constantPoolHandle _constants;
|
constantPoolHandle _constants;
|
||||||
int _index;
|
int _index;
|
||||||
int _limit;
|
int _limit;
|
||||||
|
int _generic_signature_slot;
|
||||||
|
|
||||||
FieldInfo* field() const { return FieldInfo::from_field_array(_fields(), _index); }
|
FieldInfo* field() const { return FieldInfo::from_field_array(_fields(), _index); }
|
||||||
|
|
||||||
|
int init_generic_signature_start_slot() {
|
||||||
|
int length = _fields->length();
|
||||||
|
int num_fields = 0;
|
||||||
|
int skipped_generic_signature_slots = 0;
|
||||||
|
FieldInfo* fi;
|
||||||
|
AccessFlags flags;
|
||||||
|
/* Scan from 0 to the current _index. Count the number of generic
|
||||||
|
signature slots for field[0] to field[_index - 1]. */
|
||||||
|
for (int i = 0; i < _index; i++) {
|
||||||
|
fi = FieldInfo::from_field_array(_fields(), i);
|
||||||
|
flags.set_flags(fi->access_flags());
|
||||||
|
if (flags.field_has_generic_signature()) {
|
||||||
|
length --;
|
||||||
|
skipped_generic_signature_slots ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Scan from the current _index. */
|
||||||
|
for (int i = _index; i*FieldInfo::field_slots < length; i++) {
|
||||||
|
fi = FieldInfo::from_field_array(_fields(), i);
|
||||||
|
flags.set_flags(fi->access_flags());
|
||||||
|
if (flags.field_has_generic_signature()) {
|
||||||
|
length --;
|
||||||
|
}
|
||||||
|
num_fields ++;
|
||||||
|
}
|
||||||
|
_generic_signature_slot = length + skipped_generic_signature_slots;
|
||||||
|
assert(_generic_signature_slot <= _fields->length(), "");
|
||||||
|
return num_fields;
|
||||||
|
}
|
||||||
|
|
||||||
FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants, int start, int limit) {
|
FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants, int start, int limit) {
|
||||||
_fields = fields;
|
_fields = fields;
|
||||||
_constants = constants;
|
_constants = constants;
|
||||||
_index = start;
|
_index = start;
|
||||||
|
int num_fields = init_generic_signature_start_slot();
|
||||||
|
if (limit < start) {
|
||||||
|
_limit = num_fields;
|
||||||
|
} else {
|
||||||
_limit = limit;
|
_limit = limit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants) {
|
FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants) {
|
||||||
_fields = fields;
|
_fields = fields;
|
||||||
_constants = constants;
|
_constants = constants;
|
||||||
_index = 0;
|
_index = 0;
|
||||||
_limit = fields->length() / FieldInfo::field_slots;
|
_limit = init_generic_signature_start_slot();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -65,18 +101,26 @@ class FieldStreamBase : public StackObj {
|
||||||
_constants = klass->constants();
|
_constants = klass->constants();
|
||||||
_index = 0;
|
_index = 0;
|
||||||
_limit = klass->java_fields_count();
|
_limit = klass->java_fields_count();
|
||||||
|
init_generic_signature_start_slot();
|
||||||
}
|
}
|
||||||
FieldStreamBase(instanceKlassHandle klass) {
|
FieldStreamBase(instanceKlassHandle klass) {
|
||||||
_fields = klass->fields();
|
_fields = klass->fields();
|
||||||
_constants = klass->constants();
|
_constants = klass->constants();
|
||||||
_index = 0;
|
_index = 0;
|
||||||
_limit = klass->java_fields_count();
|
_limit = klass->java_fields_count();
|
||||||
|
init_generic_signature_start_slot();
|
||||||
}
|
}
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
int index() const { return _index; }
|
int index() const { return _index; }
|
||||||
|
|
||||||
void next() { _index += 1; }
|
void next() {
|
||||||
|
if (access_flags().field_has_generic_signature()) {
|
||||||
|
_generic_signature_slot ++;
|
||||||
|
assert(_generic_signature_slot <= _fields->length(), "");
|
||||||
|
}
|
||||||
|
_index += 1;
|
||||||
|
}
|
||||||
bool done() const { return _index >= _limit; }
|
bool done() const { return _index >= _limit; }
|
||||||
|
|
||||||
// Accessors for current field
|
// Accessors for current field
|
||||||
|
@ -103,7 +147,13 @@ class FieldStreamBase : public StackObj {
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* generic_signature() const {
|
Symbol* generic_signature() const {
|
||||||
return field()->generic_signature(_constants);
|
if (access_flags().field_has_generic_signature()) {
|
||||||
|
assert(_generic_signature_slot < _fields->length(), "out of bounds");
|
||||||
|
int index = _fields->short_at(_generic_signature_slot);
|
||||||
|
return _constants->symbol_at(index);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int offset() const {
|
int offset() const {
|
||||||
|
@ -139,11 +189,19 @@ class JavaFieldStream : public FieldStreamBase {
|
||||||
}
|
}
|
||||||
int generic_signature_index() const {
|
int generic_signature_index() const {
|
||||||
assert(!field()->is_internal(), "regular only");
|
assert(!field()->is_internal(), "regular only");
|
||||||
return field()->generic_signature_index();
|
if (access_flags().field_has_generic_signature()) {
|
||||||
|
assert(_generic_signature_slot < _fields->length(), "out of bounds");
|
||||||
|
return _fields->short_at(_generic_signature_slot);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void set_generic_signature_index(int index) {
|
void set_generic_signature_index(int index) {
|
||||||
assert(!field()->is_internal(), "regular only");
|
assert(!field()->is_internal(), "regular only");
|
||||||
field()->set_generic_signature_index(index);
|
if (access_flags().field_has_generic_signature()) {
|
||||||
|
assert(_generic_signature_slot < _fields->length(), "out of bounds");
|
||||||
|
_fields->short_at_put(_generic_signature_slot, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int initval_index() const {
|
int initval_index() const {
|
||||||
assert(!field()->is_internal(), "regular only");
|
assert(!field()->is_internal(), "regular only");
|
||||||
|
@ -159,8 +217,8 @@ class JavaFieldStream : public FieldStreamBase {
|
||||||
// Iterate over only the internal fields
|
// Iterate over only the internal fields
|
||||||
class InternalFieldStream : public FieldStreamBase {
|
class InternalFieldStream : public FieldStreamBase {
|
||||||
public:
|
public:
|
||||||
InternalFieldStream(instanceKlass* k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), k->all_fields_count()) {}
|
InternalFieldStream(instanceKlass* k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
|
||||||
InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), k->all_fields_count()) {}
|
InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -168,8 +168,19 @@ class instanceKlass: public Klass {
|
||||||
objArrayOop _local_interfaces;
|
objArrayOop _local_interfaces;
|
||||||
// Interface (klassOops) this class implements transitively.
|
// Interface (klassOops) this class implements transitively.
|
||||||
objArrayOop _transitive_interfaces;
|
objArrayOop _transitive_interfaces;
|
||||||
// Instance and static variable information, 5-tuples of shorts [access, name
|
// Instance and static variable information, starts with 6-tuples of shorts
|
||||||
// index, sig index, initval index, offset].
|
// [access, name index, sig index, initval index, low_offset, high_offset]
|
||||||
|
// for all fields, followed by the generic signature data at the end of
|
||||||
|
// the array. Only fields with generic signature attributes have the generic
|
||||||
|
// signature data set in the array. The fields array looks like following:
|
||||||
|
//
|
||||||
|
// f1: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||||
|
// f2: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||||
|
// ...
|
||||||
|
// fn: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||||
|
// [generic signature index]
|
||||||
|
// [generic signature index]
|
||||||
|
// ...
|
||||||
typeArrayOop _fields;
|
typeArrayOop _fields;
|
||||||
// Constant pool for this class.
|
// Constant pool for this class.
|
||||||
constantPoolOop _constants;
|
constantPoolOop _constants;
|
||||||
|
@ -351,9 +362,6 @@ class instanceKlass: public Klass {
|
||||||
// Number of Java declared fields
|
// Number of Java declared fields
|
||||||
int java_fields_count() const { return (int)_java_fields_count; }
|
int java_fields_count() const { return (int)_java_fields_count; }
|
||||||
|
|
||||||
// Number of fields including any injected fields
|
|
||||||
int all_fields_count() const { return _fields->length() / FieldInfo::field_slots; }
|
|
||||||
|
|
||||||
typeArrayOop fields() const { return _fields; }
|
typeArrayOop fields() const { return _fields; }
|
||||||
|
|
||||||
void set_fields(typeArrayOop f, u2 java_fields_count) {
|
void set_fields(typeArrayOop f, u2 java_fields_count) {
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "memory/resourceArea.hpp"
|
#include "memory/resourceArea.hpp"
|
||||||
#include "memory/universe.inline.hpp"
|
#include "memory/universe.inline.hpp"
|
||||||
#include "oops/instanceKlass.hpp"
|
#include "oops/instanceKlass.hpp"
|
||||||
|
#include "oops/fieldStreams.hpp"
|
||||||
#include "runtime/fieldDescriptor.hpp"
|
#include "runtime/fieldDescriptor.hpp"
|
||||||
#include "runtime/handles.inline.hpp"
|
#include "runtime/handles.inline.hpp"
|
||||||
#include "runtime/signature.hpp"
|
#include "runtime/signature.hpp"
|
||||||
|
@ -37,6 +38,20 @@ oop fieldDescriptor::loader() const {
|
||||||
return instanceKlass::cast(_cp->pool_holder())->class_loader();
|
return instanceKlass::cast(_cp->pool_holder())->class_loader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Symbol* fieldDescriptor::generic_signature() const {
|
||||||
|
int idx = 0;
|
||||||
|
instanceKlass* ik = instanceKlass::cast(field_holder());
|
||||||
|
for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
|
||||||
|
if (idx == _index) {
|
||||||
|
return fs.generic_signature();
|
||||||
|
} else {
|
||||||
|
idx ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(false, "should never happen");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
typeArrayOop fieldDescriptor::annotations() const {
|
typeArrayOop fieldDescriptor::annotations() const {
|
||||||
instanceKlass* ik = instanceKlass::cast(field_holder());
|
instanceKlass* ik = instanceKlass::cast(field_holder());
|
||||||
objArrayOop md = ik->fields_annotations();
|
objArrayOop md = ik->fields_annotations();
|
||||||
|
|
|
@ -67,7 +67,7 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC {
|
||||||
oop loader() const;
|
oop loader() const;
|
||||||
// Offset (in words) of field from start of instanceOop / klassOop
|
// Offset (in words) of field from start of instanceOop / klassOop
|
||||||
int offset() const { return field()->offset(); }
|
int offset() const { return field()->offset(); }
|
||||||
Symbol* generic_signature() const { return field()->generic_signature(_cp); }
|
Symbol* generic_signature() const;
|
||||||
int index() const { return _index; }
|
int index() const { return _index; }
|
||||||
typeArrayOop annotations() const;
|
typeArrayOop annotations() const;
|
||||||
|
|
||||||
|
|
|
@ -2352,7 +2352,6 @@ static inline uint64_t cast_uint64_t(size_t x)
|
||||||
declare_constant(FieldInfo::initval_index_offset) \
|
declare_constant(FieldInfo::initval_index_offset) \
|
||||||
declare_constant(FieldInfo::low_offset) \
|
declare_constant(FieldInfo::low_offset) \
|
||||||
declare_constant(FieldInfo::high_offset) \
|
declare_constant(FieldInfo::high_offset) \
|
||||||
declare_constant(FieldInfo::generic_signature_offset) \
|
|
||||||
declare_constant(FieldInfo::field_slots) \
|
declare_constant(FieldInfo::field_slots) \
|
||||||
\
|
\
|
||||||
/************************************************/ \
|
/************************************************/ \
|
||||||
|
|
|
@ -80,10 +80,12 @@ enum {
|
||||||
JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000, // field access is watched by JVMTI
|
JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000, // field access is watched by JVMTI
|
||||||
JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000, // field modification is watched by JVMTI
|
JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000, // field modification is watched by JVMTI
|
||||||
JVM_ACC_FIELD_INTERNAL = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT
|
JVM_ACC_FIELD_INTERNAL = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT
|
||||||
|
JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800, // field has generic signature
|
||||||
|
|
||||||
JVM_ACC_FIELD_INTERNAL_FLAGS = JVM_ACC_FIELD_ACCESS_WATCHED |
|
JVM_ACC_FIELD_INTERNAL_FLAGS = JVM_ACC_FIELD_ACCESS_WATCHED |
|
||||||
JVM_ACC_FIELD_MODIFICATION_WATCHED |
|
JVM_ACC_FIELD_MODIFICATION_WATCHED |
|
||||||
JVM_ACC_FIELD_INTERNAL,
|
JVM_ACC_FIELD_INTERNAL |
|
||||||
|
JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE,
|
||||||
|
|
||||||
// flags accepted by set_field_flags()
|
// flags accepted by set_field_flags()
|
||||||
JVM_ACC_FIELD_FLAGS = JVM_RECOGNIZED_FIELD_MODIFIERS | JVM_ACC_FIELD_INTERNAL_FLAGS
|
JVM_ACC_FIELD_FLAGS = JVM_RECOGNIZED_FIELD_MODIFIERS | JVM_ACC_FIELD_INTERNAL_FLAGS
|
||||||
|
@ -156,6 +158,8 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
|
||||||
bool is_field_modification_watched() const
|
bool is_field_modification_watched() const
|
||||||
{ return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
|
{ return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
|
||||||
bool is_internal() const { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; }
|
bool is_internal() const { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; }
|
||||||
|
bool field_has_generic_signature() const
|
||||||
|
{ return (_flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) != 0; }
|
||||||
|
|
||||||
// get .class file flags
|
// get .class file flags
|
||||||
jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); }
|
jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); }
|
||||||
|
@ -225,6 +229,10 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
|
||||||
atomic_clear_bits(JVM_ACC_FIELD_MODIFICATION_WATCHED);
|
atomic_clear_bits(JVM_ACC_FIELD_MODIFICATION_WATCHED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void set_field_has_generic_signature()
|
||||||
|
{
|
||||||
|
atomic_set_bits(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Conversion
|
// Conversion
|
||||||
jshort as_short() const { return (jshort)_flags; }
|
jshort as_short() const { return (jshort)_flags; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue