# HG changeset patch # User Andreas Woess # Date 1413851492 -7200 # Node ID 5c1bd485c54b5347d5d9c3b9ea5ebc44b94a6410 # Parent b00fc4dc6dc2da386fcedbbe39c26ca790c9d6b2 Truffle: fix deoptimization of int[] with double/long values diff -r b00fc4dc6dc2 -r 5c1bd485c54b src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Mon Oct 20 16:22:18 2014 -0700 +++ b/src/share/vm/runtime/deoptimization.cpp Tue Oct 21 02:31:32 2014 +0200 @@ -832,11 +832,43 @@ } // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. - case T_INT: case T_FLOAT: // 4 bytes. + case T_INT: case T_FLOAT: { // 4 bytes. assert(value->type() == T_INT, "Agreement."); - val = value->get_int(); - obj->int_at_put(index, (jint)*((jint*)&val)); + bool big_value = false; + if (i + 1 < sv->field_size() && type == T_INT) { + if (sv->field_at(i)->is_location()) { + Location::Type type = ((LocationValue*) sv->field_at(i))->location().type(); + if (type == Location::dbl || type == Location::lng) { + big_value = true; + } + } else if (sv->field_at(i)->is_constant_int()) { + ScopeValue* next_scope_field = sv->field_at(i + 1); + if (next_scope_field->is_constant_long() || next_scope_field->is_constant_double()) { + big_value = true; + } + } + } + + if (big_value) { + StackValue* low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++i)); + #ifdef _LP64 + jlong res = (jlong)low->get_int(); + #else + #ifdef SPARC + // For SPARC we have to swap high and low words. + jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int()); + #else + jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int()); + #endif //SPARC + #endif + obj->int_at_put(index, (jint)*((jint*)&res)); + obj->int_at_put(++index, (jint)*(((jint*)&res) + 1)); + } else { + val = value->get_int(); + obj->int_at_put(index, (jint)*((jint*)&val)); + } break; + } case T_SHORT: case T_CHAR: // 2 bytes assert(value->type() == T_INT, "Agreement.");