8312495: assert(0 <= i && i < _len) failed: illegal index after JDK-8287061 on big endian platforms
Reviewed-by: clanger, kvn, dlong
This commit is contained in:
parent
486c7844f9
commit
8661b8e115
@ -242,7 +242,7 @@ void ObjectValue::print_fields_on(outputStream* st) const {
|
||||
// of the object.
|
||||
ObjectValue* ObjectMergeValue::select(frame& fr, RegisterMap& reg_map) {
|
||||
StackValue* sv_selector = StackValue::create_stack_value(&fr, ®_map, _selector);
|
||||
jint selector = sv_selector->get_int();
|
||||
jint selector = sv_selector->get_jint();
|
||||
|
||||
// If the selector is '-1' it means that execution followed the path
|
||||
// where no scalar replacement happened.
|
||||
|
@ -331,9 +331,9 @@ objArrayHandle LiveFrameStream::values_to_object_array(StackValueCollection* val
|
||||
int index = i;
|
||||
#ifdef _LP64
|
||||
if (type != T_OBJECT && type != T_CONFLICT) {
|
||||
intptr_t ret = st->get_int(); // read full 64-bit slot
|
||||
type = T_LONG; // treat as long
|
||||
index--; // undo +1 in StackValueCollection::long_at
|
||||
intptr_t ret = st->get_intptr(); // read full 64-bit slot
|
||||
type = T_LONG; // treat as long
|
||||
index--; // undo +1 in StackValueCollection::long_at
|
||||
}
|
||||
#endif
|
||||
oop obj = create_primitive_slot_instance(values, index, type, CHECK_(empty));
|
||||
|
@ -1186,12 +1186,12 @@ oop Deoptimization::get_cached_box(AutoBoxObjectValue* bv, frame* fr, RegisterMa
|
||||
if (box_type != T_OBJECT) {
|
||||
StackValue* value = StackValue::create_stack_value(fr, reg_map, bv->field_at(box_type == T_LONG ? 1 : 0));
|
||||
switch(box_type) {
|
||||
case T_INT: return IntegerBoxCache::singleton(THREAD)->lookup_raw(value->get_int(), cache_init_error);
|
||||
case T_CHAR: return CharacterBoxCache::singleton(THREAD)->lookup_raw(value->get_int(), cache_init_error);
|
||||
case T_SHORT: return ShortBoxCache::singleton(THREAD)->lookup_raw(value->get_int(), cache_init_error);
|
||||
case T_BYTE: return ByteBoxCache::singleton(THREAD)->lookup_raw(value->get_int(), cache_init_error);
|
||||
case T_BOOLEAN: return BooleanBoxCache::singleton(THREAD)->lookup_raw(value->get_int(), cache_init_error);
|
||||
case T_LONG: return LongBoxCache::singleton(THREAD)->lookup_raw(value->get_int(), cache_init_error);
|
||||
case T_INT: return IntegerBoxCache::singleton(THREAD)->lookup_raw(value->get_intptr(), cache_init_error);
|
||||
case T_CHAR: return CharacterBoxCache::singleton(THREAD)->lookup_raw(value->get_intptr(), cache_init_error);
|
||||
case T_SHORT: return ShortBoxCache::singleton(THREAD)->lookup_raw(value->get_intptr(), cache_init_error);
|
||||
case T_BYTE: return ByteBoxCache::singleton(THREAD)->lookup_raw(value->get_intptr(), cache_init_error);
|
||||
case T_BOOLEAN: return BooleanBoxCache::singleton(THREAD)->lookup_raw(value->get_intptr(), cache_init_error);
|
||||
case T_LONG: return LongBoxCache::singleton(THREAD)->lookup_raw(value->get_intptr(), cache_init_error);
|
||||
default:;
|
||||
}
|
||||
}
|
||||
@ -1313,19 +1313,19 @@ static jbyte* check_alignment_get_addr(typeArrayOop obj, int index, int expected
|
||||
return res;
|
||||
}
|
||||
|
||||
static void byte_array_put(typeArrayOop obj, intptr_t val, int index, int byte_count) {
|
||||
static void byte_array_put(typeArrayOop obj, StackValue* value, int index, int byte_count) {
|
||||
switch (byte_count) {
|
||||
case 1:
|
||||
obj->byte_at_put(index, (jbyte) *((jint *) &val));
|
||||
obj->byte_at_put(index, (jbyte) value->get_jint());
|
||||
break;
|
||||
case 2:
|
||||
*((jshort *) check_alignment_get_addr(obj, index, 2)) = (jshort) *((jint *) &val);
|
||||
*((jshort *) check_alignment_get_addr(obj, index, 2)) = (jshort) value->get_jint();
|
||||
break;
|
||||
case 4:
|
||||
*((jint *) check_alignment_get_addr(obj, index, 4)) = (jint) *((jint *) &val);
|
||||
*((jint *) check_alignment_get_addr(obj, index, 4)) = value->get_jint();
|
||||
break;
|
||||
case 8:
|
||||
*((jlong *) check_alignment_get_addr(obj, index, 8)) = (jlong) *((jlong *) &val);
|
||||
*((jlong *) check_alignment_get_addr(obj, index, 8)) = (jlong) value->get_intptr();
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -1337,7 +1337,6 @@ static void byte_array_put(typeArrayOop obj, intptr_t val, int index, int byte_c
|
||||
// restore elements of an eliminated type array
|
||||
void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) {
|
||||
int index = 0;
|
||||
intptr_t val;
|
||||
|
||||
for (int i = 0; i < sv->field_size(); i++) {
|
||||
StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
|
||||
@ -1347,15 +1346,14 @@ void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_ma
|
||||
StackValue* low =
|
||||
StackValue::create_stack_value(fr, reg_map, sv->field_at(++i));
|
||||
#ifdef _LP64
|
||||
jlong res = (jlong)low->get_int();
|
||||
jlong res = (jlong)low->get_intptr();
|
||||
#else
|
||||
jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
|
||||
jlong res = jlong_from(value->get_jint(), low->get_jint());
|
||||
#endif
|
||||
obj->long_at_put(index, 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.");
|
||||
bool big_value = false;
|
||||
@ -1376,53 +1374,48 @@ void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_ma
|
||||
if (big_value) {
|
||||
StackValue* low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++i));
|
||||
#ifdef _LP64
|
||||
jlong res = (jlong)low->get_int();
|
||||
jlong res = (jlong)low->get_intptr();
|
||||
#else
|
||||
jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
|
||||
jlong res = jlong_from(value->get_jint(), low->get_jint());
|
||||
#endif
|
||||
obj->int_at_put(index, (jint)*((jint*)&res));
|
||||
obj->int_at_put(++index, (jint)*(((jint*)&res) + 1));
|
||||
obj->int_at_put(index, *(jint*)&res);
|
||||
obj->int_at_put(++index, *((jint*)&res + 1));
|
||||
} else {
|
||||
val = value->get_int();
|
||||
obj->int_at_put(index, (jint)*((jint*)&val));
|
||||
obj->int_at_put(index, value->get_jint());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case T_SHORT:
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
val = value->get_int();
|
||||
obj->short_at_put(index, (jshort)*((jint*)&val));
|
||||
obj->short_at_put(index, (jshort)value->get_jint());
|
||||
break;
|
||||
|
||||
case T_CHAR:
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
val = value->get_int();
|
||||
obj->char_at_put(index, (jchar)*((jint*)&val));
|
||||
obj->char_at_put(index, (jchar)value->get_jint());
|
||||
break;
|
||||
|
||||
case T_BYTE: {
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
// The value we get is erased as a regular int. We will need to find its actual byte count 'by hand'.
|
||||
val = value->get_int();
|
||||
#if INCLUDE_JVMCI
|
||||
// The value we get is erased as a regular int. We will need to find its actual byte count 'by hand'.
|
||||
int byte_count = count_number_of_bytes_for_entry(sv, i);
|
||||
byte_array_put(obj, val, index, byte_count);
|
||||
byte_array_put(obj, value, index, byte_count);
|
||||
// According to byte_count contract, the values from i + 1 to i + byte_count are illegal values. Skip.
|
||||
i += byte_count - 1; // Balance the loop counter.
|
||||
index += byte_count;
|
||||
// index has been updated so continue at top of loop
|
||||
continue;
|
||||
#else
|
||||
obj->byte_at_put(index, (jbyte)*((jint*)&val));
|
||||
obj->byte_at_put(index, (jbyte)value->get_jint());
|
||||
break;
|
||||
#endif // INCLUDE_JVMCI
|
||||
}
|
||||
|
||||
case T_BOOLEAN: {
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
val = value->get_int();
|
||||
obj->bool_at_put(index, (jboolean)*((jint*)&val));
|
||||
obj->bool_at_put(index, (jboolean)value->get_jint());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1475,7 +1468,6 @@ static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap
|
||||
}
|
||||
fields->sort(compare);
|
||||
for (int i = 0; i < fields->length(); i++) {
|
||||
intptr_t val;
|
||||
ScopeValue* scope_field = sv->field_at(svIndex);
|
||||
StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field);
|
||||
int offset = fields->at(i)._offset;
|
||||
@ -1486,7 +1478,6 @@ static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap
|
||||
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;
|
||||
@ -1510,8 +1501,7 @@ static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap
|
||||
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));
|
||||
obj->int_field_put(offset, value->get_jint());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1521,9 +1511,9 @@ static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
StackValue* low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++svIndex));
|
||||
#ifdef _LP64
|
||||
jlong res = (jlong)low->get_int();
|
||||
jlong res = (jlong)low->get_intptr();
|
||||
#else
|
||||
jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
|
||||
jlong res = jlong_from(value->get_jint(), low->get_jint());
|
||||
#endif
|
||||
obj->long_field_put(offset, res);
|
||||
break;
|
||||
@ -1531,26 +1521,22 @@ static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap
|
||||
|
||||
case T_SHORT:
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
val = value->get_int();
|
||||
obj->short_field_put(offset, (jshort)*((jint*)&val));
|
||||
obj->short_field_put(offset, (jshort)value->get_jint());
|
||||
break;
|
||||
|
||||
case T_CHAR:
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
val = value->get_int();
|
||||
obj->char_field_put(offset, (jchar)*((jint*)&val));
|
||||
obj->char_field_put(offset, (jchar)value->get_jint());
|
||||
break;
|
||||
|
||||
case T_BYTE:
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
val = value->get_int();
|
||||
obj->byte_field_put(offset, (jbyte)*((jint*)&val));
|
||||
obj->byte_field_put(offset, (jbyte)value->get_jint());
|
||||
break;
|
||||
|
||||
case T_BOOLEAN:
|
||||
assert(value->type() == T_INT, "Agreement.");
|
||||
val = value->get_int();
|
||||
obj->bool_field_put(offset, (jboolean)*((jint*)&val));
|
||||
obj->bool_field_put(offset, (jboolean)value->get_jint());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -79,22 +79,34 @@ class StackValue : public ResourceObj {
|
||||
_handle_value = value;
|
||||
}
|
||||
|
||||
intptr_t get_int() const {
|
||||
intptr_t get_intptr() const {
|
||||
assert(type() == T_INT, "type check");
|
||||
return _integer_value;
|
||||
}
|
||||
|
||||
// For special case in deopt.
|
||||
intptr_t get_int(BasicType t) const {
|
||||
intptr_t get_intptr(BasicType t) const {
|
||||
assert(t == T_OBJECT && type() == T_OBJECT, "type check");
|
||||
return _integer_value;
|
||||
}
|
||||
|
||||
void set_int(intptr_t value) {
|
||||
void set_intptr(intptr_t value) {
|
||||
assert(type() == T_INT, "type check");
|
||||
_integer_value = value;
|
||||
}
|
||||
|
||||
// The jint value is always at offset 0 of the stack slot. On big endian platforms
|
||||
// this is the location of the high word therefore we cannot just cast to jint.
|
||||
jint get_jint() const {
|
||||
assert(type() == T_INT, "type check");
|
||||
return *(jint*)&_integer_value;
|
||||
}
|
||||
|
||||
void set_jint(jint value) {
|
||||
assert(type() == T_INT, "type check");
|
||||
*(jint*)&_integer_value = value;
|
||||
}
|
||||
|
||||
BasicType type() const { return _type; }
|
||||
|
||||
bool equal(StackValue *value) {
|
||||
|
@ -26,14 +26,12 @@
|
||||
#include "runtime/stackValueCollection.hpp"
|
||||
|
||||
jint StackValueCollection::int_at(int slot) const {
|
||||
intptr_t val = at(slot)->get_int();
|
||||
jint ival = *((jint*) (&val));
|
||||
return ival;
|
||||
return at(slot)->get_jint();
|
||||
}
|
||||
|
||||
jlong StackValueCollection::long_at(int slot) const {
|
||||
#ifdef _LP64
|
||||
return at(slot+1)->get_int();
|
||||
return at(slot+1)->get_intptr();
|
||||
#else
|
||||
union {
|
||||
jlong jl;
|
||||
@ -41,8 +39,8 @@ jlong StackValueCollection::long_at(int slot) const {
|
||||
} value;
|
||||
// Interpreter stack is reversed in memory:
|
||||
// low memory location is in higher java local slot.
|
||||
value.array[0] = at(slot+1)->get_int();
|
||||
value.array[1] = at(slot )->get_int();
|
||||
value.array[0] = at(slot+1)->get_intptr();
|
||||
value.array[1] = at(slot )->get_intptr();
|
||||
return value.jl;
|
||||
#endif
|
||||
}
|
||||
@ -52,13 +50,13 @@ Handle StackValueCollection::obj_at(int slot) const {
|
||||
}
|
||||
|
||||
jfloat StackValueCollection::float_at(int slot) const {
|
||||
intptr_t res = at(slot)->get_int();
|
||||
intptr_t res = at(slot)->get_intptr();
|
||||
return *((jfloat*) (&res));
|
||||
}
|
||||
|
||||
jdouble StackValueCollection::double_at(int slot) const {
|
||||
#ifdef _LP64
|
||||
intptr_t res = at(slot+1)->get_int();
|
||||
intptr_t res = at(slot+1)->get_intptr();
|
||||
return *((jdouble*) (&res));
|
||||
#else
|
||||
union {
|
||||
@ -67,21 +65,19 @@ jdouble StackValueCollection::double_at(int slot) const {
|
||||
} value;
|
||||
// Interpreter stack is reversed in memory:
|
||||
// low memory location is in higher java local slot.
|
||||
value.array[0] = at(slot+1)->get_int();
|
||||
value.array[1] = at(slot )->get_int();
|
||||
value.array[0] = at(slot+1)->get_intptr();
|
||||
value.array[1] = at(slot )->get_intptr();
|
||||
return value.jd;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StackValueCollection::set_int_at(int slot, jint value) {
|
||||
intptr_t val;
|
||||
*((jint*) (&val)) = value;
|
||||
at(slot)->set_int(val);
|
||||
at(slot)->set_jint(value);
|
||||
}
|
||||
|
||||
void StackValueCollection::set_long_at(int slot, jlong value) {
|
||||
#ifdef _LP64
|
||||
at(slot+1)->set_int(value);
|
||||
at(slot+1)->set_intptr(value);
|
||||
#else
|
||||
union {
|
||||
jlong jl;
|
||||
@ -90,8 +86,8 @@ void StackValueCollection::set_long_at(int slot, jlong value) {
|
||||
// Interpreter stack is reversed in memory:
|
||||
// low memory location is in higher java local slot.
|
||||
x.jl = value;
|
||||
at(slot+1)->set_int(x.array[0]);
|
||||
at(slot+0)->set_int(x.array[1]);
|
||||
at(slot+1)->set_intptr(x.array[0]);
|
||||
at(slot+0)->set_intptr(x.array[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -108,15 +104,15 @@ void StackValueCollection::set_float_at(int slot, jfloat value) {
|
||||
// Interpreter stores 32 bit floats in first half of 64 bit word.
|
||||
val.array[0] = *(jint*)(&value);
|
||||
val.array[1] = 0;
|
||||
at(slot)->set_int(val.jd);
|
||||
at(slot)->set_intptr(val.jd);
|
||||
#else
|
||||
at(slot)->set_int(*(jint*)(&value));
|
||||
at(slot)->set_intptr(*(jint*)(&value));
|
||||
#endif
|
||||
}
|
||||
|
||||
void StackValueCollection::set_double_at(int slot, jdouble value) {
|
||||
#ifdef _LP64
|
||||
at(slot+1)->set_int(*(intptr_t*)(&value));
|
||||
at(slot+1)->set_intptr(*(intptr_t*)(&value));
|
||||
#else
|
||||
union {
|
||||
jdouble jd;
|
||||
@ -125,8 +121,8 @@ void StackValueCollection::set_double_at(int slot, jdouble value) {
|
||||
// Interpreter stack is reversed in memory:
|
||||
// low memory location is in higher java local slot.
|
||||
x.jd = value;
|
||||
at(slot+1)->set_int(x.array[0]);
|
||||
at(slot+0)->set_int(x.array[1]);
|
||||
at(slot+1)->set_intptr(x.array[0]);
|
||||
at(slot+0)->set_intptr(x.array[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -453,7 +453,7 @@ void interpretedVFrame::set_locals(StackValueCollection* values) const {
|
||||
if (sv->type() == T_OBJECT) {
|
||||
*(oop *) addr = (sv->get_obj())();
|
||||
} else { // integer
|
||||
*addr = sv->get_int();
|
||||
*addr = sv->get_intptr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) {
|
||||
_locals->add( new StackValue());
|
||||
break;
|
||||
case T_INT:
|
||||
_locals->add( new StackValue(value->get_int()));
|
||||
_locals->add( new StackValue(value->get_intptr()));
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -160,7 +160,7 @@ void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) {
|
||||
_expressions->add( new StackValue());
|
||||
break;
|
||||
case T_INT:
|
||||
_expressions->add( new StackValue(value->get_int()));
|
||||
_expressions->add( new StackValue(value->get_intptr()));
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -342,7 +342,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
||||
assert(!is_bottom_frame || !(caller->is_compiled_caller() && addr >= caller->unextended_sp()), "overwriting caller frame!");
|
||||
switch(value->type()) {
|
||||
case T_INT:
|
||||
*addr = value->get_int();
|
||||
*addr = value->get_intptr();
|
||||
#ifndef PRODUCT
|
||||
if (PrintDeoptimizationDetails) {
|
||||
tty->print_cr(" - Reconstructed expression %d (INT): %d", i, (int)(*addr));
|
||||
@ -350,7 +350,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
||||
#endif // !PRODUCT
|
||||
break;
|
||||
case T_OBJECT:
|
||||
*addr = value->get_int(T_OBJECT);
|
||||
*addr = value->get_intptr(T_OBJECT);
|
||||
#ifndef PRODUCT
|
||||
if (PrintDeoptimizationDetails) {
|
||||
tty->print(" - Reconstructed expression %d (OBJECT): ", i);
|
||||
@ -386,7 +386,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
||||
assert(!is_bottom_frame || !(caller->is_compiled_caller() && addr >= caller->unextended_sp()), "overwriting caller frame!");
|
||||
switch(value->type()) {
|
||||
case T_INT:
|
||||
*addr = value->get_int();
|
||||
*addr = value->get_intptr();
|
||||
#ifndef PRODUCT
|
||||
if (PrintDeoptimizationDetails) {
|
||||
tty->print_cr(" - Reconstructed local %d (INT): %d", i, (int)(*addr));
|
||||
@ -394,7 +394,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
||||
#endif // !PRODUCT
|
||||
break;
|
||||
case T_OBJECT:
|
||||
*addr = value->get_int(T_OBJECT);
|
||||
*addr = value->get_intptr(T_OBJECT);
|
||||
#ifndef PRODUCT
|
||||
if (PrintDeoptimizationDetails) {
|
||||
tty->print(" - Reconstructed local %d (OBJECT): ", i);
|
||||
|
Loading…
Reference in New Issue
Block a user