< prev index next >
src/hotspot/share/c1/c1_LIRGenerator.cpp
Print this page
@@ -1657,16 +1657,36 @@
__ 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);
}
+bool LIRGenerator::needs_flattened_array_store_check(StoreIndexed* x) {
+ if (ValueArrayFlatten && x->elt_type() == T_OBJECT && x->array()->maybe_flattened_array()) {
+ ciType* type = x->value()->declared_type();
+ if (type != NULL && type->is_klass()) {
+ ciKlass* klass = type->as_klass();
+ if (klass->is_loaded() &&
+ !(klass->is_valuetype() && klass->as_value_klass()->flatten_array()) &&
+ !klass->is_java_lang_Object() &&
+ !klass->is_interface()) {
+ // This is known to be a non-flattenable object. If the array is flattened,
+ // it will be caught by the code generated by array_store_check().
+ return false;
+ }
+ }
+ // We're not 100% sure, so let's do the flattened_array_store_check.
+ return true;
+ }
+ return false;
+}
+
void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
assert(x->is_pinned(),"");
bool is_loaded_flattened_array = x->array()->is_loaded_flattened_array();
bool needs_range_check = x->compute_needs_range_check();
bool use_length = x->length() != NULL;
- bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT;
+ bool obj_store = x->elt_type() == T_OBJECT; assert(x->elt_type() != T_ARRAY, "never used");
bool needs_store_check = obj_store && !is_loaded_flattened_array &&
(x->value()->as_Constant() == NULL ||
!get_jobject_constant(x->value())->is_null_object() ||
x->should_profile());
@@ -1682,11 +1702,11 @@
length.set_instruction(x->length());
length.load_item();
}
if (needs_store_check || x->check_boolean()
- || is_loaded_flattened_array || x->array()->maybe_flattened_array()) {
+ || is_loaded_flattened_array || needs_flattened_array_store_check(x)) {
value.load_item();
} else {
value.load_for_store(x->elt_type());
}
@@ -1727,11 +1747,11 @@
}
access_flattened_array(false, array, index, value);
} else {
StoreFlattenedArrayStub* slow_path = NULL;
- if (x->array()->maybe_flattened_array()) {
+ if (needs_flattened_array_store_check(x)) {
// Check if we indeed have a flattened array
index.load_item();
slow_path = new StoreFlattenedArrayStub(array.result(), index.result(), value.result(), state_for(x));
check_flattened_array(array, slow_path);
}
@@ -2044,13 +2064,13 @@
set_no_result(x);
} else {
LIR_Opr result = rlock_result(x, x->elt_type());
LoadFlattenedArrayStub* slow_path = NULL;
- if (x->array()->maybe_flattened_array()) {
+ if (x->elt_type() == T_OBJECT && x->array()->maybe_flattened_array()) {
index.load_item();
- // Check if we indeed have a flattened array
+ // if we are loading from flattened array, load it using a runtime call
slow_path = new LoadFlattenedArrayStub(array.result(), index.result(), result, state_for(x));
check_flattened_array(array, slow_path);
}
DecoratorSet decorators = IN_HEAP | IS_ARRAY;
< prev index next >