< prev index next >
src/hotspot/share/c1/c1_LIRGenerator.cpp
Print this page
@@ -1985,11 +1985,12 @@
length.set_instruction(x->length());
length.load_item();
}
array.load_item();
- if (index.is_constant() && can_inline_as_constant(x->index())) {
+ if (index.is_constant() && can_inline_as_constant(x->index())
+ && !x->array()->maybe_flattened_array()) {
// let it be a constant
index.dont_load_item();
} else {
index.load_item();
}
@@ -2023,30 +2024,43 @@
// The range check performs the null check, so clear it out for the load
null_check_info = NULL;
}
}
- if (x->array()->is_flattened_array()) {
- if (x->array()->declared_type()->is_loaded()) {
+ if (x->array()->is_loaded_flattened_array()) {
// Find the destination address (of the NewValueTypeInstance)
LIR_Opr obj = x->vt()->operand();
LIRItem obj_item(x->vt(), this);
access_flattened_array(true, array, index, obj_item);
set_no_result(x);
- return;
} else {
- // If the array is indeed flattened, deopt. Otherwise access it as a normal object array.
- CodeEmitInfo* deopt_info = state_for(x, x->state_before());
- maybe_deopt_value_array_access(array, null_check_info, deopt_info);
- }
+ LIR_Opr result = rlock_result(x, x->elt_type());
+ LoadFlattenedArrayStub* slow_path = NULL;
+
+ if (x->array()->maybe_flattened_array()) {
+ // Check if we indeed have a flattened array
+ slow_path = new LoadFlattenedArrayStub(array.result(), index.result(), result, state_for(x));
+ LIR_Opr array_klass_reg = new_register(T_METADATA);
+
+ __ move(new LIR_Address(array.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), array_klass_reg);
+ LIR_Opr layout = new_register(T_INT);
+ __ move(new LIR_Address(array_klass_reg, in_bytes(Klass::layout_helper_offset()), T_INT), layout);
+ __ shift_right(layout, Klass::_lh_array_tag_shift, layout);
+ __ cmp(lir_cond_equal, layout, LIR_OprFact::intConst(Klass::_lh_array_tag_vt_value));
+ __ branch(lir_cond_equal, T_ILLEGAL, slow_path);
}
+
DecoratorSet decorators = IN_HEAP | IS_ARRAY;
- LIR_Opr result = rlock_result(x, x->elt_type());
access_load_at(decorators, x->elt_type(),
array, index.result(), result,
NULL, null_check_info);
+
+ if (slow_path != NULL) {
+ __ branch_destination(slow_path->continuation());
+ }
+ }
}
void LIRGenerator::do_NullCheck(NullCheck* x) {
if (x->can_trap()) {
< prev index next >