< prev index next >
src/share/vm/ci/ciInstanceKlass.cpp
Print this page
@@ -395,10 +395,33 @@
ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
return field;
}
// ------------------------------------------------------------------
+// ciInstanceKlass::get_field_type_by_offset
+ciType* ciInstanceKlass::get_field_type_by_offset(int field_offset) {
+ ASSERT_IN_VM;
+ fieldDescriptor fd;
+ InstanceKlass* klass = get_instanceKlass();
+ // Important: We cannot get the field type via get_field_by_offset() because if the field
+ // is another value type, the offset would refer to the first field of that value type due
+ // to flattening. Instead, do a SystemDictionary lookup for the type of the declared field.
+ bool found = klass->find_field_from_offset(field_offset, false, &fd);
+ assert(found, "field not found");
+ BasicType field_type = fd.field_type();
+ if (is_java_primitive(field_type)) {
+ // Primitive type
+ return ciType::make(field_type);
+ } else {
+ // Do a SystemDictionary lookup for the type
+ ciEnv* env = CURRENT_ENV;
+ ciSymbol* signature = env->get_symbol(fd.signature());
+ return env->get_klass_by_name_impl(this, constantPoolHandle(), signature, false);
+ }
+}
+
+// ------------------------------------------------------------------
// ciInstanceKlass::get_field_by_name
ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {
VM_ENTRY_MARK;
InstanceKlass* k = get_instanceKlass();
fieldDescriptor fd;
@@ -498,13 +521,30 @@
}
for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) continue;
fieldDescriptor& fd = fs.field_descriptor();
+ if (fd.field_type() == T_VALUETYPE) {
+ // Value type fields are embedded
+ int field_offset = fd.offset();
+ // Get ValueKlass and adjust number of fields
+ ciValueKlass* vk = get_field_type_by_offset(field_offset)->as_value_klass();
+ flen += vk->get_field_count() - 1;
+ // Iterate over fields of flattened value type and copy them to 'this'
+ for (int i = 0; i < vk->nof_nonstatic_fields(); ++i) {
+ ciField* flattened_field = vk->nonstatic_field_at(i);
+ // Adjust offset to account for missing oop header
+ int offset = field_offset + (flattened_field->offset() - vk->get_first_field_offset());
+ bool is_final = is_valuetype(); // flattened fields are final if holder is a value type
+ ciField* field = new (arena) ciField(flattened_field, this, offset, is_final);
+ fields->append(field);
+ }
+ } else {
ciField* field = new (arena) ciField(&fd);
fields->append(field);
}
+ }
assert(fields->length() == flen, "sanity");
return fields;
}
bool ciInstanceKlass::compute_injected_fields_helper() {
< prev index next >