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

8260283: [lworld] C1's EliminateFieldAccess optimization fails with "wrong types" #311

Closed
wants to merge 3 commits 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
@@ -1820,7 +1820,7 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
}
}

const int offset = !needs_patching ? field->offset() : -1;
int offset = !needs_patching ? field->offset() : -1;
switch (code) {
case Bytecodes::_getstatic: {
// check for compile-time constants, i.e., initialized static final fields
@@ -1907,12 +1907,12 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
state_before = copy_state_for_exception();
}
if (!field->is_flattened()) {
LoadField* load;
if (has_pending_field_access()) {
assert(!needs_patching, "Can't patch delayed field access");
load = new LoadField(pending_field_access()->obj(),
pending_field_access()->offset() + offset - field->holder()->as_inline_klass()->first_field_offset(),
field, false, state_before, needs_patching);
obj = pending_field_access()->obj();
offset += pending_field_access()->offset() - field->holder()->as_inline_klass()->first_field_offset();
field = pending_field_access()->holder()->get_field_by_offset(offset, false);
assert(field != NULL, "field not found");
set_pending_field_access(NULL);
} else if (has_pending_load_indexed()) {
assert(!needs_patching, "Can't patch delayed field access");
@@ -1922,9 +1922,8 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
push(type, append(li));
set_pending_load_indexed(NULL);
break;
} else {
load = new LoadField(obj, offset, field, false, state_before, needs_patching);
}
LoadField* load = new LoadField(obj, offset, field, false, state_before, needs_patching);
Value replacement = !needs_patching ? _memory->load(load) : load;
if (replacement != load) {
assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
@@ -1965,10 +1964,10 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
if (has_pending_load_indexed()) {
pending_load_indexed()->update(field, offset - field->holder()->as_inline_klass()->first_field_offset());
} else if (has_pending_field_access()) {
pending_field_access()->update(field, offset - field->holder()->as_inline_klass()->first_field_offset());
pending_field_access()->inc_offset(offset - field->holder()->as_inline_klass()->first_field_offset());
} else {
null_check(obj);
DelayedFieldAccess* dfa = new DelayedFieldAccess(obj, field, field->offset());
DelayedFieldAccess* dfa = new DelayedFieldAccess(obj, field->holder(), field->offset());
set_pending_field_access(dfa);
}
} else {
@@ -37,22 +37,17 @@ class MemoryBuffer;

class DelayedFieldAccess : public CompilationResourceObj {
private:
Value _obj;
ciField* _field;
int _offset;
Value _obj;
ciInstanceKlass* _holder;
int _offset;
public:
DelayedFieldAccess(Value obj, ciField* field, int offset)
: _obj(obj)
, _field(field)
, _offset(offset) { }

void update(ciField* field, int offset) {
_field = field;
_offset += offset;
}
Value obj() { return _obj; }
ciField* field() { return _field; }
int offset() { return _offset; }
DelayedFieldAccess(Value obj, ciInstanceKlass* holder, int offset)
: _obj(obj), _holder(holder) , _offset(offset) { }

Value obj() const { return _obj; }
ciInstanceKlass* holder() const { return _holder; }
int offset() const { return _offset; }
void inc_offset(int offset) { _offset += offset; }
};

class GraphBuilder {
@@ -23,7 +23,7 @@

/**
* @test
* @bug 8260034 8260225
* @bug 8260034 8260225 8260283
* @summary Generated inline type tests.
* @run main/othervm -Xbatch compiler.valhalla.inlinetypes.TestGenerated
*/
@@ -78,6 +78,17 @@ int test5(MyValue1[] array) {
return array[0].array[0];
}

long f3;
MyValue1 f4 = new MyValue1();

void test6() {
f3 = 123L;
int res = f4.x;
if (res != 42) {
throw new RuntimeException("test6 failed");
}
}

public static void main(String[] args) {
TestGenerated t = new TestGenerated();
EmptyValue[] array1 = { new EmptyValue() };
@@ -90,6 +101,7 @@ public static void main(String[] args) {
t.test3(array2);
t.test4(array3);
t.test5(array3);
t.test6();
}
}
}