Skip to content

Commit c3c2b9f

Browse files
committed
8303737: C2: Load can bypass subtype check that enforces it's from the right object type
Backport-of: 52983ed529182901db4e33857bfeab2727e235df
1 parent ae5b92c commit c3c2b9f

File tree

8 files changed

+496
-49
lines changed

8 files changed

+496
-49
lines changed

src/hotspot/share/opto/castnode.cpp

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@
3636
//=============================================================================
3737
// If input is already higher or equal to cast type, then this is an identity.
3838
Node* ConstraintCastNode::Identity(PhaseGVN* phase) {
39+
if (_dependency == UnconditionalDependency) {
40+
return this;
41+
}
3942
Node* dom = dominating_cast(phase, phase);
4043
if (dom != nullptr) {
4144
return dom;
4245
}
43-
if (_dependency != RegularDependency) {
44-
return this;
45-
}
46-
return phase->type(in(1))->higher_equal_speculative(_type) ? in(1) : this;
46+
return higher_equal_types(phase, in(1)) ? in(1) : this;
4747
}
4848

4949
//------------------------------Value------------------------------------------
@@ -100,47 +100,62 @@ Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape) {
100100
return (in(0) && remove_dead_region(phase, can_reshape)) ? this : nullptr;
101101
}
102102

103+
uint ConstraintCastNode::hash() const {
104+
return TypeNode::hash() + (int)_dependency + (_extra_types != nullptr ? _extra_types->hash() : 0);
105+
}
106+
103107
bool ConstraintCastNode::cmp(const Node &n) const {
104-
return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._dependency == _dependency;
108+
if (!TypeNode::cmp(n)) {
109+
return false;
110+
}
111+
ConstraintCastNode& cast = (ConstraintCastNode&) n;
112+
if (cast._dependency != _dependency) {
113+
return false;
114+
}
115+
if (_extra_types == nullptr || cast._extra_types == nullptr) {
116+
return _extra_types == cast._extra_types;
117+
}
118+
return _extra_types->eq(cast._extra_types);
105119
}
106120

107121
uint ConstraintCastNode::size_of() const {
108122
return sizeof(*this);
109123
}
110124

111-
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency) {
125+
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency,
126+
const TypeTuple* extra_types) {
112127
switch(opcode) {
113128
case Op_CastII: {
114-
Node* cast = new CastIINode(n, t, dependency);
129+
Node* cast = new CastIINode(n, t, dependency, false, extra_types);
115130
cast->set_req(0, c);
116131
return cast;
117132
}
118133
case Op_CastLL: {
119-
Node* cast = new CastLLNode(n, t, dependency);
134+
Node* cast = new CastLLNode(n, t, dependency, extra_types);
120135
cast->set_req(0, c);
121136
return cast;
122137
}
123138
case Op_CastPP: {
124-
Node* cast = new CastPPNode(n, t, dependency);
139+
Node* cast = new CastPPNode(n, t, dependency, extra_types);
125140
cast->set_req(0, c);
126141
return cast;
127142
}
128143
case Op_CastFF: {
129-
Node* cast = new CastFFNode(n, t, dependency);
144+
Node* cast = new CastFFNode(n, t, dependency, extra_types);
130145
cast->set_req(0, c);
131146
return cast;
132147
}
133148
case Op_CastDD: {
134-
Node* cast = new CastDDNode(n, t, dependency);
149+
Node* cast = new CastDDNode(n, t, dependency, extra_types);
135150
cast->set_req(0, c);
136151
return cast;
137152
}
138153
case Op_CastVV: {
139-
Node* cast = new CastVVNode(n, t, dependency);
154+
Node* cast = new CastVVNode(n, t, dependency, extra_types);
140155
cast->set_req(0, c);
141156
return cast;
142157
}
143-
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency);
158+
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency, extra_types);
144159
default:
145160
fatal("Bad opcode %d", opcode);
146161
}
@@ -150,10 +165,10 @@ Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t,
150165
Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt) {
151166
switch(bt) {
152167
case T_INT: {
153-
return make_cast(Op_CastII, c, n, t, dependency);
168+
return make_cast(Op_CastII, c, n, t, dependency, nullptr);
154169
}
155170
case T_LONG: {
156-
return make_cast(Op_CastLL, c, n, t, dependency);
171+
return make_cast(Op_CastLL, c, n, t, dependency, nullptr);
157172
}
158173
default:
159174
fatal("Bad basic type %s", type2name(bt));
@@ -186,7 +201,7 @@ TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt)
186201
u->outcnt() > 0 &&
187202
u->Opcode() == opc &&
188203
u->in(0) != nullptr &&
189-
u->bottom_type()->higher_equal(type())) {
204+
higher_equal_types(gvn, u)) {
190205
if (pt->is_dominator(u->in(0), ctl)) {
191206
return u->as_Type();
192207
}
@@ -202,9 +217,28 @@ TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt)
202217
return nullptr;
203218
}
204219

220+
bool ConstraintCastNode::higher_equal_types(PhaseGVN* phase, const Node* other) const {
221+
const Type* t = phase->type(other);
222+
if (!t->higher_equal_speculative(type())) {
223+
return false;
224+
}
225+
if (_extra_types != nullptr) {
226+
for (uint i = 0; i < _extra_types->cnt(); ++i) {
227+
if (!t->higher_equal_speculative(_extra_types->field_at(i))) {
228+
return false;
229+
}
230+
}
231+
}
232+
return true;
233+
}
234+
205235
#ifndef PRODUCT
206236
void ConstraintCastNode::dump_spec(outputStream *st) const {
207237
TypeNode::dump_spec(st);
238+
if (_extra_types != nullptr) {
239+
st->print(" extra types: ");
240+
_extra_types->dump_on(st);
241+
}
208242
if (_dependency != RegularDependency) {
209243
st->print(" %s dependency", _dependency == StrongDependency ? "strong" : "unconditional");
210244
}
@@ -523,20 +557,21 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
523557
return this;
524558
}
525559

526-
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency) {
560+
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency,
561+
const TypeTuple* types) {
527562
Node* cast= nullptr;
528563
if (type->isa_int()) {
529-
cast = make_cast(Op_CastII, c, in, type, dependency);
564+
cast = make_cast(Op_CastII, c, in, type, dependency, types);
530565
} else if (type->isa_long()) {
531-
cast = make_cast(Op_CastLL, c, in, type, dependency);
566+
cast = make_cast(Op_CastLL, c, in, type, dependency, types);
532567
} else if (type->isa_float()) {
533-
cast = make_cast(Op_CastFF, c, in, type, dependency);
568+
cast = make_cast(Op_CastFF, c, in, type, dependency, types);
534569
} else if (type->isa_double()) {
535-
cast = make_cast(Op_CastDD, c, in, type, dependency);
570+
cast = make_cast(Op_CastDD, c, in, type, dependency, types);
536571
} else if (type->isa_vect()) {
537-
cast = make_cast(Op_CastVV, c, in, type, dependency);
572+
cast = make_cast(Op_CastVV, c, in, type, dependency, types);
538573
} else if (type->isa_ptr()) {
539-
cast = make_cast(Op_CastPP, c, in, type, dependency);
574+
cast = make_cast(Op_CastPP, c, in, type, dependency, types);
540575
}
541576
return cast;
542577
}

src/hotspot/share/opto/castnode.hpp

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,20 @@ class ConstraintCastNode: public TypeNode {
4343
const DependencyType _dependency;
4444
virtual bool cmp( const Node &n ) const;
4545
virtual uint size_of() const;
46+
virtual uint hash() const; // Check the type
4647
const Type* widen_type(const PhaseGVN* phase, const Type* res, BasicType bt) const;
4748

49+
private:
50+
// PhiNode::Ideal() transforms a Phi that merges a single uncasted value into a single cast pinned at the region.
51+
// The types of cast nodes eliminated as a consequence of this transformation are collected and stored here so the
52+
// type dependencies carried by the cast are known. The cast can then be eliminated if the type of its input is
53+
// narrower (or equal) than all the types it carries.
54+
const TypeTuple* _extra_types;
55+
4856
public:
49-
ConstraintCastNode(Node *n, const Type *t, DependencyType dependency)
50-
: TypeNode(t,2), _dependency(dependency) {
57+
ConstraintCastNode(Node* n, const Type* t, ConstraintCastNode::DependencyType dependency,
58+
const TypeTuple* extra_types)
59+
: TypeNode(t,2), _dependency(dependency), _extra_types(extra_types) {
5160
init_class_id(Class_ConstraintCast);
5261
init_req(1, n);
5362
}
@@ -59,14 +68,15 @@ class ConstraintCastNode: public TypeNode {
5968
virtual bool depends_only_on_test() const { return _dependency == RegularDependency; }
6069
bool carry_dependency() const { return _dependency != RegularDependency; }
6170
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
62-
static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency);
71+
static Node* make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency, const TypeTuple* extra_types);
6372
static Node* make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt);
6473

6574
#ifndef PRODUCT
6675
virtual void dump_spec(outputStream *st) const;
6776
#endif
6877

69-
static Node* make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency);
78+
static Node* make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency,
79+
const TypeTuple* types);
7080

7181
Node* optimize_integer_cast(PhaseGVN* phase, BasicType bt);
7282

@@ -91,6 +101,16 @@ class ConstraintCastNode: public TypeNode {
91101
}
92102
}
93103
}
104+
105+
bool higher_equal_types(PhaseGVN* phase, const Node* other) const;
106+
107+
int extra_types_count() const {
108+
return _extra_types == nullptr ? 0 : _extra_types->cnt();
109+
}
110+
111+
const Type* extra_type_at(int i) const {
112+
return _extra_types->field_at(i);
113+
}
94114
};
95115

96116
//------------------------------CastIINode-------------------------------------
@@ -103,12 +123,12 @@ class CastIINode: public ConstraintCastNode {
103123
virtual uint size_of() const;
104124

105125
public:
106-
CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
107-
: ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) {
126+
CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
127+
: ConstraintCastNode(n, t, dependency, types), _range_check_dependency(range_check_dependency) {
108128
init_class_id(Class_CastII);
109129
}
110130
CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
111-
: ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) {
131+
: ConstraintCastNode(n, t, dependency, nullptr), _range_check_dependency(range_check_dependency) {
112132
init_class_id(Class_CastII);
113133
init_req(0, ctrl);
114134
}
@@ -134,12 +154,12 @@ class CastIINode: public ConstraintCastNode {
134154
class CastLLNode: public ConstraintCastNode {
135155
public:
136156
CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency)
137-
: ConstraintCastNode(n, t, dependency) {
157+
: ConstraintCastNode(n, t, dependency, nullptr) {
138158
init_class_id(Class_CastLL);
139159
init_req(0, ctrl);
140160
}
141-
CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
142-
: ConstraintCastNode(n, t, dependency){
161+
CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
162+
: ConstraintCastNode(n, t, dependency, types) {
143163
init_class_id(Class_CastLL);
144164
}
145165

@@ -151,8 +171,8 @@ class CastLLNode: public ConstraintCastNode {
151171

152172
class CastFFNode: public ConstraintCastNode {
153173
public:
154-
CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
155-
: ConstraintCastNode(n, t, dependency){
174+
CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
175+
: ConstraintCastNode(n, t, dependency, types) {
156176
init_class_id(Class_CastFF);
157177
}
158178
virtual int Opcode() const;
@@ -161,8 +181,8 @@ class CastFFNode: public ConstraintCastNode {
161181

162182
class CastDDNode: public ConstraintCastNode {
163183
public:
164-
CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
165-
: ConstraintCastNode(n, t, dependency){
184+
CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
185+
: ConstraintCastNode(n, t, dependency, types) {
166186
init_class_id(Class_CastDD);
167187
}
168188
virtual int Opcode() const;
@@ -171,8 +191,8 @@ class CastDDNode: public ConstraintCastNode {
171191

172192
class CastVVNode: public ConstraintCastNode {
173193
public:
174-
CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
175-
: ConstraintCastNode(n, t, dependency){
194+
CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
195+
: ConstraintCastNode(n, t, dependency, types) {
176196
init_class_id(Class_CastVV);
177197
}
178198
virtual int Opcode() const;
@@ -184,8 +204,8 @@ class CastVVNode: public ConstraintCastNode {
184204
// cast pointer to pointer (different type)
185205
class CastPPNode: public ConstraintCastNode {
186206
public:
187-
CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency)
188-
: ConstraintCastNode(n, t, dependency) {
207+
CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
208+
: ConstraintCastNode(n, t, dependency, types) {
189209
}
190210
virtual int Opcode() const;
191211
virtual uint ideal_reg() const { return Op_RegP; }
@@ -195,8 +215,8 @@ class CastPPNode: public ConstraintCastNode {
195215
// for _checkcast, cast pointer to pointer (different type), without JOIN,
196216
class CheckCastPPNode: public ConstraintCastNode {
197217
public:
198-
CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency)
199-
: ConstraintCastNode(n, t, dependency) {
218+
CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
219+
: ConstraintCastNode(n, t, dependency, types) {
200220
init_class_id(Class_CheckCastPP);
201221
init_req(0, c);
202222
}

0 commit comments

Comments
 (0)