Skip to content

Commit 714930e

Browse files
Quan Anh MaiTobiHartmann
authored andcommitted
8355397: [lworld] Parse::array_load fails with "array can't be flat" assert
Reviewed-by: thartmann
1 parent 99de2e7 commit 714930e

File tree

16 files changed

+49
-31
lines changed

16 files changed

+49
-31
lines changed

src/hotspot/share/c1/c1_Instruction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ bool Instruction::maybe_flat_array() {
140140
if (type->is_obj_array_klass()) {
141141
// Due to array covariance, the runtime type might be a flat array.
142142
ciKlass* element_klass = type->as_obj_array_klass()->element_klass();
143-
if (element_klass->can_be_inline_klass() && (!element_klass->is_inlinetype() || element_klass->as_inline_klass()->flat_in_array())) {
143+
if (element_klass->can_be_inline_klass() && (!element_klass->is_inlinetype() || element_klass->as_inline_klass()->maybe_flat_in_array())) {
144144
return true;
145145
}
146146
} else if (type->is_flat_array_klass()) {

src/hotspot/share/c1/c1_LIRGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1827,7 +1827,7 @@ bool LIRGenerator::needs_flat_array_store_check(StoreIndexed* x) {
18271827
ciType* type = x->value()->declared_type();
18281828
if (type != nullptr && type->is_klass()) {
18291829
ciKlass* klass = type->as_klass();
1830-
if (!klass->can_be_inline_klass() || (klass->is_inlinetype() && !klass->as_inline_klass()->flat_in_array())) {
1830+
if (!klass->can_be_inline_klass() || (klass->is_inlinetype() && !klass->as_inline_klass()->maybe_flat_in_array())) {
18311831
// This is known to be a non-flat object. If the array is a flat array,
18321832
// it will be caught by the code generated by array_store_check().
18331833
return false;

src/hotspot/share/ci/ciArrayKlass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ ciArrayKlass* ciArrayKlass::make(ciType* element_type, bool flat, bool null_free
114114
EXCEPTION_CONTEXT;
115115
Klass* ak = nullptr;
116116
InlineKlass* vk = InlineKlass::cast(klass->get_Klass());
117-
if (flat && vk->flat_array()) {
117+
if (flat && vk->maybe_flat_in_array()) {
118118
LayoutKind lk;
119119
if (null_free) {
120120
if (vk->is_naturally_atomic()) {

src/hotspot/share/ci/ciInlineKlass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ int ciInlineKlass::payload_offset() const {
3333
}
3434

3535
// Are arrays containing this inline type flat arrays?
36-
bool ciInlineKlass::flat_in_array() const {
37-
GUARDED_VM_ENTRY(return to_InlineKlass()->flat_array();)
36+
bool ciInlineKlass::maybe_flat_in_array() const {
37+
GUARDED_VM_ENTRY(return to_InlineKlass()->maybe_flat_in_array();)
3838
}
3939

4040
// Can this inline type be passed as multiple values?

src/hotspot/share/ci/ciInlineKlass.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class ciInlineKlass : public ciInstanceKlass {
6060
// Inline type fields
6161
int payload_offset() const;
6262

63-
bool flat_in_array() const;
63+
bool maybe_flat_in_array() const;
6464
bool can_be_passed_as_fields() const;
6565
bool can_be_returned_as_fields() const;
6666
bool is_empty();

src/hotspot/share/ci/ciMetadata.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class ciMetadata: public ciBaseObject {
6161
virtual bool is_obj_array_klass() const { return false; }
6262
virtual bool is_type_array_klass() const { return false; }
6363
virtual bool is_wrapper() const { return false; }
64-
virtual bool flat_in_array() const { return false; }
64+
virtual bool maybe_flat_in_array() const { return false; }
6565
virtual void dump_replay_data(outputStream* st) { /* do nothing */ }
6666

6767
ciMethod* as_method() {

src/hotspot/share/oops/inlineKlass.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,22 +284,14 @@ void InlineKlass::write_value_to_addr(oop src, void* dst, LayoutKind lk, bool de
284284

285285
// Arrays of...
286286

287-
bool InlineKlass::flat_array() {
287+
bool InlineKlass::maybe_flat_in_array() {
288288
if (!UseArrayFlattening) {
289289
return false;
290290
}
291291
// Too many embedded oops
292292
if ((FlatArrayElementMaxOops >= 0) && (nonstatic_oop_count() > FlatArrayElementMaxOops)) {
293293
return false;
294294
}
295-
// Declared atomic but not naturally atomic.
296-
if (must_be_atomic() && !is_naturally_atomic()) {
297-
return false;
298-
}
299-
// VM enforcing AlwaysAtomicAccess only...
300-
if (AlwaysAtomicAccesses && (!is_naturally_atomic())) {
301-
return false;
302-
}
303295
// No flat layout?
304296
if (!has_nullable_atomic_layout() && !has_atomic_layout() && !has_non_atomic_layout()) {
305297
return false;

src/hotspot/share/oops/inlineKlass.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ class InlineKlass: public InstanceKlass {
254254

255255
address payload_addr(oop o) const;
256256

257-
bool flat_array();
257+
bool maybe_flat_in_array();
258258

259259
bool contains_oops() const { return nonstatic_oop_map_count() > 0; }
260260
int nonstatic_oop_count();

src/hotspot/share/opto/graphKit.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3663,7 +3663,7 @@ Node* GraphKit::gen_checkcast(Node* obj, Node* superklass, Node* *failure_contro
36633663
record_for_igvn(region);
36643664

36653665
bool not_inline = !toop->can_be_inline_type();
3666-
bool not_flat_in_array = !UseArrayFlattening || not_inline || (toop->is_inlinetypeptr() && !toop->inline_klass()->flat_in_array());
3666+
bool not_flat_in_array = !UseArrayFlattening || not_inline || (toop->is_inlinetypeptr() && !toop->inline_klass()->maybe_flat_in_array());
36673667
if (EnableValhalla && (not_inline || not_flat_in_array)) {
36683668
// Check if obj has been loaded from an array
36693669
obj = obj->isa_DecodeN() ? obj->in(1) : obj;
@@ -4008,7 +4008,7 @@ Node* GraphKit::get_layout_helper(Node* klass_node, jint& constant_value) {
40084008
if (UseArrayFlattening && !xklass && ary_type != nullptr && !ary_type->is_null_free()) {
40094009
// Don't constant fold if the runtime type might be a flat array but the static type is not.
40104010
const TypeOopPtr* elem = ary_type->elem()->make_oopptr();
4011-
can_be_flat = ary_type->can_be_inline_array() && (!elem->is_inlinetypeptr() || elem->inline_klass()->flat_in_array());
4011+
can_be_flat = ary_type->can_be_inline_array() && (!elem->is_inlinetypeptr() || elem->inline_klass()->maybe_flat_in_array());
40124012
}
40134013
if (!can_be_flat && (xklass || (klass_t->isa_aryklassptr() && klass_t->is_aryklassptr()->elem() != Type::BOTTOM))) {
40144014
jint lhelper;

src/hotspot/share/opto/library_call.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4582,7 +4582,7 @@ bool LibraryCallKit::inline_newArray(bool null_free, bool atomic) {
45824582
ciType* t = tp->java_mirror_type();
45834583
if (t != nullptr && t->is_inlinetype()) {
45844584
ciInlineKlass* vk = t->as_inline_klass();
4585-
bool flat = vk->flat_in_array();
4585+
bool flat = vk->maybe_flat_in_array();
45864586
if (flat && atomic) {
45874587
// Only flat if we have a corresponding atomic layout
45884588
flat = null_free ? vk->has_atomic_layout() : vk->has_nullable_atomic_layout();

src/hotspot/share/opto/macro.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,7 @@ SafePointScalarObjectNode* PhaseMacroExpand::create_scalarized_object_descriptio
954954
const TypeOopPtr* field_addr_type = res_type->add_offset(offset)->isa_oopptr();
955955
if (res_type->is_flat()) {
956956
ciInlineKlass* inline_klass = res_type->is_aryptr()->elem()->inline_klass();
957-
assert(inline_klass->flat_in_array(), "must be flat in array");
957+
assert(inline_klass->maybe_flat_in_array(), "must be flat in array");
958958
field_val = inline_type_from_mem(sfpt->memory(), sfpt->control(), inline_klass, field_addr_type->isa_aryptr(), 0, alloc);
959959
} else {
960960
field_val = value_from_mem(sfpt->memory(), sfpt->control(), basic_elem_type, field_type, field_addr_type, alloc);

src/hotspot/share/opto/parse2.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void Parse::array_load(BasicType bt) {
8585
if (!array_type->is_not_flat()) {
8686
// Cannot statically determine if array is a flat array, emit runtime check
8787
assert(UseArrayFlattening && is_reference_type(bt) && element_ptr->can_be_inline_type() &&
88-
(!element_ptr->is_inlinetypeptr() || element_ptr->inline_klass()->flat_in_array()), "array can't be flat");
88+
(!element_ptr->is_inlinetypeptr() || element_ptr->inline_klass()->maybe_flat_in_array()), "array can't be flat");
8989
IdealKit ideal(this);
9090
IdealVariable res(ideal);
9191
ideal.declarations_done();
@@ -228,7 +228,7 @@ void Parse::array_store(BasicType bt) {
228228
bool not_inline = !stored_value_casted_type->maybe_null() && !stored_value_casted_type->is_oopptr()->can_be_inline_type();
229229
bool not_null_free = not_inline;
230230
bool not_flat = not_inline || ( stored_value_casted_type->is_inlinetypeptr() &&
231-
!stored_value_casted_type->inline_klass()->flat_in_array());
231+
!stored_value_casted_type->inline_klass()->maybe_flat_in_array());
232232
if (!array_type->is_not_null_free() && not_null_free) {
233233
// Storing a non-inline type, mark array as not null-free.
234234
array_type = array_type->cast_to_not_null_free();

src/hotspot/share/opto/type.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4077,7 +4077,7 @@ const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_
40774077
}
40784078
bool not_inline = !exact_etype->can_be_inline_type();
40794079
bool not_null_free = not_inline;
4080-
bool not_flat = !UseArrayFlattening || not_inline || (exact_etype->is_inlinetypeptr() && !exact_etype->inline_klass()->flat_in_array());
4080+
bool not_flat = !UseArrayFlattening || not_inline || (exact_etype->is_inlinetypeptr() && !exact_etype->inline_klass()->maybe_flat_in_array());
40814081
// Even though MyValue is final, [LMyValue is not exact because null-free [LMyValue is a subtype.
40824082
bool xk = etype->klass_is_exact() && !etype->is_inlinetypeptr();
40834083
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS, /* stable= */ false, /* flat= */ false, not_flat, not_null_free);
@@ -4387,7 +4387,7 @@ TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, const TypeInterfaces* interfaces,
43874387
assert(k != nullptr &&
43884388
(k->is_loaded() || o == nullptr),
43894389
"cannot have constants with non-loaded klass");
4390-
assert(!klass()->flat_in_array() || flat_in_array, "Should be flat in array");
4390+
assert(!klass()->maybe_flat_in_array() || flat_in_array, "Should be flat in array");
43914391
assert(!flat_in_array || can_be_inline_type(), "Only inline types can be flat in array");
43924392
};
43934393

@@ -4421,7 +4421,7 @@ const TypeInstPtr *TypeInstPtr::make(PTR ptr,
44214421
}
44224422

44234423
// Check if this type is known to be flat in arrays
4424-
flat_in_array = flat_in_array || k->flat_in_array();
4424+
flat_in_array = flat_in_array || k->maybe_flat_in_array();
44254425

44264426
// Now hash this baby
44274427
TypeInstPtr *result =
@@ -6447,7 +6447,7 @@ uint TypeInstKlassPtr::hash(void) const {
64476447
}
64486448

64496449
const TypeInstKlassPtr *TypeInstKlassPtr::make(PTR ptr, ciKlass* k, const TypeInterfaces* interfaces, Offset offset, bool flat_in_array) {
6450-
flat_in_array = flat_in_array || k->flat_in_array();
6450+
flat_in_array = flat_in_array || k->maybe_flat_in_array();
64516451

64526452
TypeInstKlassPtr *r =
64536453
(TypeInstKlassPtr*)(new TypeInstKlassPtr(ptr, k, interfaces, offset, flat_in_array))->hashcons();
@@ -6820,7 +6820,7 @@ const TypeAryKlassPtr* TypeAryKlassPtr::make(PTR ptr, ciKlass* k, Offset offset,
68206820
bool not_flat = (ptr == Constant) ? !flat : (!UseArrayFlattening || not_inline ||
68216821
(k->as_array_klass()->element_klass() != nullptr &&
68226822
k->as_array_klass()->element_klass()->is_inlinetype() &&
6823-
!k->as_array_klass()->element_klass()->flat_in_array()));
6823+
!k->as_array_klass()->element_klass()->maybe_flat_in_array()));
68246824

68256825
return TypeAryKlassPtr::make(ptr, k, offset, interface_handling, not_flat, not_null_free, flat, null_free);
68266826
}
@@ -6998,7 +6998,7 @@ const TypeKlassPtr *TypeAryKlassPtr::cast_to_exactness(bool klass_is_exact) cons
69986998
const TypeOopPtr* exact_etype = TypeOopPtr::make_from_klass_unique(_elem->is_instklassptr()->instance_klass());
69996999
bool not_inline = !exact_etype->can_be_inline_type();
70007000
not_null_free = not_inline;
7001-
not_flat = !UseArrayFlattening || not_inline || (exact_etype->is_inlinetypeptr() && !exact_etype->inline_klass()->flat_in_array());
7001+
not_flat = !UseArrayFlattening || not_inline || (exact_etype->is_inlinetypeptr() && !exact_etype->inline_klass()->maybe_flat_in_array());
70027002
}
70037003
}
70047004
return make(klass_is_exact ? Constant : NotNull, elem, k, _offset, not_flat, not_null_free, _flat, _null_free);

src/hotspot/share/prims/jvm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ JVM_ENTRY(jarray, JVM_NewNullRestrictedNonAtomicArray(JNIEnv *env, jclass elmCla
486486
validate_array_arguments(klass, len, CHECK_NULL);
487487
InlineKlass* vk = InlineKlass::cast(klass);
488488
oop array = nullptr;
489-
if (vk->flat_array() && vk->has_non_atomic_layout()) {
489+
if (vk->maybe_flat_in_array() && vk->has_non_atomic_layout()) {
490490
array = oopFactory::new_flatArray(vk, len, LayoutKind::NON_ATOMIC_FLAT, CHECK_NULL);
491491
for (int i = 0; i < len; i++) {
492492
((flatArrayOop)array)->write_value_to_flat_array(init_h(), i, CHECK_NULL);

src/hotspot/share/runtime/deoptimization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1661,7 +1661,7 @@ static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap
16611661
// restore fields of an eliminated inline type array
16621662
void Deoptimization::reassign_flat_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, flatArrayOop obj, FlatArrayKlass* vak, bool is_jvmci, TRAPS) {
16631663
InlineKlass* vk = vak->element_klass();
1664-
assert(vk->flat_array(), "should only be used for flat inline type arrays");
1664+
assert(vk->maybe_flat_in_array(), "should only be used for flat inline type arrays");
16651665
// Adjust offset to omit oop header
16661666
int base_offset = arrayOopDesc::base_offset_in_bytes(T_FLAT_ELEMENT) - InlineKlass::cast(vk)->payload_offset();
16671667
// Initialize all elements of the flat inline type array

test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3625,4 +3625,30 @@ static String test150(String s) {
36253625
public void test150_verifier() {
36263626
Asserts.assertEquals(test150("bla"), "bla");
36273627
}
3628+
3629+
static value class Test151Value {
3630+
byte b;
3631+
String s;
3632+
3633+
Test151Value(byte b, String s) {
3634+
this.b = b;
3635+
this.s = s;
3636+
}
3637+
3638+
static final Test151Value DEFAULT = new Test151Value((byte) 1, "hello");
3639+
3640+
static final Test151Value[] ARRAY = (Test151Value[]) ValueClass.newNullRestrictedAtomicArray(Test151Value.class, 100, DEFAULT);
3641+
}
3642+
3643+
@Test
3644+
@IR(applyIf = {"InlineTypeReturnedAsFields", "true"},
3645+
failOn = {ALLOC})
3646+
static Test151Value test151(int i) {
3647+
return Test151Value.ARRAY[i];
3648+
}
3649+
3650+
@Run(test = "test151")
3651+
public void test151_verifier() {
3652+
Asserts.assertEquals(Test151Value.DEFAULT, test151(rI & 15));
3653+
}
36283654
}

0 commit comments

Comments
 (0)