Mercurial > hg > truffle
diff src/share/vm/runtime/deoptimization.cpp @ 12617:bca33c3135de
PEA: support for unsafe stores of mismatching sizes, cleanup, documentation
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Mon, 28 Oct 2013 13:01:16 +0100 |
parents | d1f8d0538b79 |
children | 38b84d5a66fd |
line wrap: on
line diff
--- a/src/share/vm/runtime/deoptimization.cpp Mon Oct 28 13:10:10 2013 +0200 +++ b/src/share/vm/runtime/deoptimization.cpp Mon Oct 28 13:01:16 2013 +0100 @@ -914,7 +914,8 @@ fields->sort(compare); for (int i = 0; i < fields->length(); i++) { intptr_t val; - StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(svIndex)); + ScopeValue* scope_field = sv->field_at(svIndex); + StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field); int offset = fields->at(i)._offset; BasicType type = fields->at(i)._type; switch (type) { @@ -923,6 +924,37 @@ obj->obj_field_put(offset, value->get_obj()()); break; + // 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."); + bool big_value = false; + if (i+1 < fields->length() && fields->at(i+1)._type == T_INT) { + if (scope_field->is_location()) { + Location::Type type = ((LocationValue*) scope_field)->location().type(); + if (type == Location::dbl || type == Location::lng) { + big_value = true; + } + } + if (scope_field->is_constant_int()) { + ScopeValue* next_scope_field = sv->field_at(svIndex + 1); + if (next_scope_field->is_constant_long() || next_scope_field->is_constant_double()) { + big_value = true; + } + } + } + + if (big_value) { + i++; + assert(i < fields->length(), "second T_INT field needed"); + assert(fields->at(i)._type == T_INT, "T_INT field needed"); + } else { + val = value->get_int(); + obj->int_field_put(offset, (jint)*((jint*)&val)); + break; + } + } + /* no break */ + case T_LONG: case T_DOUBLE: { assert(value->type() == T_INT, "Agreement."); StackValue* low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++svIndex)); @@ -939,12 +971,6 @@ obj->long_field_put(offset, res); break; } - // 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."); - val = value->get_int(); - obj->int_field_put(offset, (jint)*((jint*)&val)); - break; case T_SHORT: case T_CHAR: // 2 bytes assert(value->type() == T_INT, "Agreement.");