Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8261647: [lworld] Missing default initialization of non-flattened field of empty inline type #335

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -52,20 +52,16 @@ inline oop flatArrayOopDesc::value_alloc_copy_from_index(flatArrayHandle vah, in
return vklass->default_value();
} else {
oop buf = vklass->allocate_instance_buffer(CHECK_NULL);
vklass->inline_copy_payload_to_new_oop(vah->value_at_addr(index, vaklass->layout_helper()) ,buf);
vklass->inline_copy_payload_to_new_oop(vah->value_at_addr(index, vaklass->layout_helper()), buf);
return buf;
}
}

inline void flatArrayOopDesc::value_copy_from_index(int index, oop dst) const {
FlatArrayKlass* vaklass = FlatArrayKlass::cast(klass());
InlineKlass* vklass = vaklass->element_klass();
if (vklass->is_empty_inline_type()) {
return; // Assumes dst was a new and clean buffer (OptoRuntime::load_unknown_inline())
} else {
void* src = value_at_addr(index, vaklass->layout_helper());
return vklass->inline_copy_payload_to_new_oop(src ,dst);
}
void* src = value_at_addr(index, vaklass->layout_helper());
return vklass->inline_copy_payload_to_new_oop(src, dst);
}

inline void flatArrayOopDesc::value_copy_to_index(oop src, int index) const {
@@ -1332,10 +1332,6 @@ int compare(ReassignedField* left, ReassignedField* right) {
// Restore fields of an eliminated instance object using the same field order
// returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true)
static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj, bool skip_internal, int base_offset, TRAPS) {
if (svIndex >= sv->field_size()) {
// No fields left to re-assign.
return svIndex;
}
GrowableArray<ReassignedField>* fields = new GrowableArray<ReassignedField>();
InstanceKlass* ik = klass;
while (ik != NULL) {
@@ -1345,13 +1341,12 @@ static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap
field._offset = fs.offset();
field._type = Signature::basic_type(fs.signature());
if (field._type == T_INLINE_TYPE) {
field._type = T_OBJECT;
}
if (fs.is_inlined()) {
// Resolve klass of flattened inline type field
Klass* vk = klass->get_inline_type_field_klass(fs.index());
field._klass = InlineKlass::cast(vk);
field._type = T_INLINE_TYPE;
if (fs.is_inlined()) {
// Resolve klass of flattened inline type field
field._klass = InlineKlass::cast(klass->get_inline_type_field_klass(fs.index()));
} else {
field._type = T_OBJECT;
}
}
fields->append(field);
}
@@ -1360,27 +1355,27 @@ static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap
}
fields->sort(compare);
for (int i = 0; i < fields->length(); i++) {
BasicType type = fields->at(i)._type;
int offset = base_offset + fields->at(i)._offset;
// Check for flattened inline type field before accessing the ScopeValue because it might not have any fields
if (type == T_INLINE_TYPE) {
// Recursively re-assign flattened inline type fields
InstanceKlass* vk = fields->at(i)._klass;
assert(vk != NULL, "must be resolved");
offset -= InlineKlass::cast(vk)->first_field_offset(); // Adjust offset to omit oop header
svIndex = reassign_fields_by_klass(vk, fr, reg_map, sv, svIndex, obj, skip_internal, offset, CHECK_0);
continue; // Continue because we don't need to increment svIndex
}
intptr_t val;
ScopeValue* scope_field = sv->field_at(svIndex);
StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field);
int offset = base_offset + fields->at(i)._offset;
BasicType type = fields->at(i)._type;
switch (type) {
case T_OBJECT:
case T_ARRAY:
assert(value->type() == T_OBJECT, "Agreement.");
obj->obj_field_put(offset, value->get_obj()());
break;

case T_INLINE_TYPE: {
// Recursively re-assign flattened inline type fields
InstanceKlass* vk = fields->at(i)._klass;
assert(vk != NULL, "must be resolved");
offset -= InlineKlass::cast(vk)->first_field_offset(); // Adjust offset to omit oop header
svIndex = reassign_fields_by_klass(vk, fr, reg_map, sv, svIndex, obj, skip_internal, offset, CHECK_0);
continue; // Continue because we don't need to increment svIndex
}

// Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
case T_INT: case T_FLOAT: { // 4 bytes.
assert(value->type() == T_INT, "Agreement.");
@@ -3018,8 +3018,6 @@ public void test130_verifier(boolean warmup) {
MyValueEmpty empty = MyValueEmpty.default;
}

// TODO disabled until JDK-8253893 is fixed
/*
// Empty inline type container array access
@Test(failOn = ALLOC + ALLOCA + LOAD + STORE)
public MyValueEmpty test131(EmptyContainer[] array) {
@@ -3034,7 +3032,6 @@ public void test131_verifier(boolean warmup) {
Asserts.assertEquals(array[0], EmptyContainer.default);
Asserts.assertEquals(empty, MyValueEmpty.default);
}
*/

// Empty inline type array access with unknown array type
@Test()
@@ -3055,8 +3052,6 @@ public void test132_verifier(boolean warmup) {
Asserts.assertEquals(empty, null);
}

// TODO disabled until JDK-8253893 is fixed
/*
// Empty inline type container array access with unknown array type
@Test()
public Object test133(Object[] array) {
@@ -3075,7 +3070,6 @@ public void test133_verifier(boolean warmup) {
Asserts.assertEquals(array[0], EmptyContainer.default);
Asserts.assertEquals(empty, null);
}
*/

// Non-escaping empty inline type array access
@Test(failOn = ALLOC + ALLOCA + LOAD + STORE)
@@ -3358,4 +3352,17 @@ public void test144() {
public void test144_verifier(boolean warmup) {
test144();
}

// Test that array load slow path correctly initializes non-flattened field of empty inline type
@Test()
public Object test145(Object[] array) {
return array[0];
}

@DontCompile
public void test145_verifier(boolean warmup) {
Object[] array = new EmptyContainer[1];
EmptyContainer empty = (EmptyContainer)test145(array);
Asserts.assertEquals(empty, EmptyContainer.default);
}
}
@@ -3301,17 +3301,15 @@ public void test118_verifier(boolean warmup) {
@Test
public void test119(boolean deopt) {
MyValueEmpty[] array1 = new MyValueEmpty[]{MyValueEmpty.default};
// TODO disabled until JDK-8253893 is fixed
// EmptyContainer[] array2 = new EmptyContainer[]{EmptyContainer.default};
// MixedContainer[] array3 = new MixedContainer[]{MixedContainer.default};
EmptyContainer[] array2 = new EmptyContainer[]{EmptyContainer.default};
MixedContainer[] array3 = new MixedContainer[]{MixedContainer.default};
if (deopt) {
// uncommon trap
WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test119"));
}
Asserts.assertEquals(array1[0], MyValueEmpty.default);
// TODO disabled until JDK-8253893 is fixed
// Asserts.assertEquals(array2[0], EmptyContainer.default);
// Asserts.assertEquals(array3[0], MixedContainer.default);
Asserts.assertEquals(array2[0], EmptyContainer.default);
Asserts.assertEquals(array3[0], MixedContainer.default);
}

@DontCompile