Skip to content

Commit fdac9ab

Browse files
Quan Anh MaiTobiHartmann
authored andcommitted
8353432: [lworld] Deoptimization needs to handle nullable, flat fields in non-value class holders
Reviewed-by: thartmann
1 parent 64ee2e2 commit fdac9ab

File tree

7 files changed

+243
-193
lines changed

7 files changed

+243
-193
lines changed

src/hotspot/share/opto/inlinetypenode.cpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -277,15 +277,16 @@ int InlineTypeNode::field_null_marker_offset(uint index) const {
277277
return field->null_marker_offset();
278278
}
279279

280-
uint InlineTypeNode::add_fields_to_safepoint(Unique_Node_List& worklist, Node_List& null_markers, SafePointNode* sfpt) {
280+
uint InlineTypeNode::add_fields_to_safepoint(Unique_Node_List& worklist, SafePointNode* sfpt) {
281281
uint cnt = 0;
282282
for (uint i = 0; i < field_count(); ++i) {
283283
Node* value = field_value(i);
284284
if (field_is_flat(i)) {
285285
InlineTypeNode* vt = value->as_InlineType();
286-
cnt += vt->add_fields_to_safepoint(worklist, null_markers, sfpt);
286+
cnt += vt->add_fields_to_safepoint(worklist, sfpt);
287287
if (!field_is_null_free(i)) {
288-
null_markers.push(vt->get_is_init());
288+
// The null marker of a flat field is added right after we scalarize that field
289+
sfpt->add_req(vt->get_is_init());
289290
cnt++;
290291
}
291292
continue;
@@ -308,18 +309,8 @@ void InlineTypeNode::make_scalar_in_safepoint(PhaseIterGVN* igvn, Unique_Node_Li
308309
// Iterate over the inline type fields in order of increasing offset and add the
309310
// field values to the safepoint. Nullable inline types have an IsInit field that
310311
// needs to be checked before using the field values.
311-
const TypeInt* tinit = igvn->type(get_is_init())->isa_int();
312-
if (tinit != nullptr && !tinit->is_con(1)) {
313-
sfpt->add_req(get_is_init());
314-
} else {
315-
sfpt->add_req(igvn->C->top());
316-
}
317-
Node_List null_markers;
318-
uint nfields = add_fields_to_safepoint(worklist, null_markers, sfpt);
319-
// Add null markers after the field values
320-
for (uint i = 0; i < null_markers.size(); ++i) {
321-
sfpt->add_req(null_markers.at(i));
322-
}
312+
sfpt->add_req(get_is_init());
313+
uint nfields = add_fields_to_safepoint(worklist, sfpt);
323314
jvms->set_endoff(sfpt->req());
324315
// Replace safepoint edge by SafePointScalarObjectNode
325316
SafePointScalarObjectNode* sobj = new SafePointScalarObjectNode(type()->isa_instptr(),
@@ -1606,7 +1597,7 @@ InlineTypeNode* InlineTypeNode::make_null(PhaseGVN& gvn, ciInlineKlass* vk, bool
16061597
InlineTypeNode* InlineTypeNode::make_null_impl(PhaseGVN& gvn, ciInlineKlass* vk, GrowableArray<ciType*>& visited, bool transform) {
16071598
InlineTypeNode* vt = new InlineTypeNode(vk, gvn.zerocon(T_OBJECT), /* null_free= */ false);
16081599
vt->set_is_buffered(gvn);
1609-
vt->set_is_init(gvn, false);
1600+
vt->set_is_init(gvn, gvn.intcon(0));
16101601
for (uint i = 0; i < vt->field_count(); i++) {
16111602
ciType* ft = vt->field_type(i);
16121603
Node* value = gvn.zerocon(ft->basic_type());

src/hotspot/share/opto/inlinetypenode.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class InlineTypeNode : public TypeNode {
5757
ciInlineKlass* inline_klass() const { return type()->inline_klass(); }
5858

5959
void make_scalar_in_safepoint(PhaseIterGVN* igvn, Unique_Node_List& worklist, SafePointNode* sfpt);
60-
uint add_fields_to_safepoint(Unique_Node_List& worklist, Node_List& null_markers, SafePointNode* sfpt);
60+
uint add_fields_to_safepoint(Unique_Node_List& worklist, SafePointNode* sfpt);
6161

6262
// Checks if the inline type is loaded from memory and if so returns the oop
6363
Node* is_loaded(PhaseGVN* phase, ciInlineKlass* vk = nullptr, Node* base = nullptr, int holder_offset = 0);
@@ -106,7 +106,8 @@ class InlineTypeNode : public TypeNode {
106106
Node* get_oop() const { return in(Oop); }
107107
void set_oop(PhaseGVN& gvn, Node* oop) { set_req_X(Oop, oop, &gvn); }
108108
Node* get_is_init() const { return in(IsInit); }
109-
void set_is_init(PhaseGVN& gvn, bool init = true) { set_req_X(IsInit, gvn.intcon(init ? 1 : 0), &gvn); }
109+
void set_is_init(PhaseGVN& gvn, Node* init) { set_req_X(IsInit, init, &gvn); }
110+
void set_is_init(PhaseGVN& gvn) { set_is_init(gvn, gvn.intcon(1)); }
110111
Node* get_is_buffered() const { return in(IsBuffered); }
111112
void set_is_buffered(PhaseGVN& gvn, bool buffered = true) { set_req_X(IsBuffered, gvn.intcon(buffered ? 1 : 0), &gvn); }
112113

0 commit comments

Comments
 (0)