Skip to content

Commit 52983ed

Browse files
committed
8303737: C2: Load can bypass subtype check that enforces it's from the right object type
Reviewed-by: chagedorn, thartmann
1 parent 9e6cb62 commit 52983ed

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
@@ -37,14 +37,14 @@
3737
//=============================================================================
3838
// If input is already higher or equal to cast type, then this is an identity.
3939
Node* ConstraintCastNode::Identity(PhaseGVN* phase) {
40+
if (_dependency == UnconditionalDependency) {
41+
return this;
42+
}
4043
Node* dom = dominating_cast(phase, phase);
4144
if (dom != nullptr) {
4245
return dom;
4346
}
44-
if (_dependency != RegularDependency) {
45-
return this;
46-
}
47-
return phase->type(in(1))->higher_equal_speculative(_type) ? in(1) : this;
47+
return higher_equal_types(phase, in(1)) ? in(1) : this;
4848
}
4949

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

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

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

112-
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency) {
126+
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency,
127+
const TypeTuple* extra_types) {
113128
switch(opcode) {
114129
case Op_CastII: {
115-
Node* cast = new CastIINode(n, t, dependency);
130+
Node* cast = new CastIINode(n, t, dependency, false, extra_types);
116131
cast->set_req(0, c);
117132
return cast;
118133
}
119134
case Op_CastLL: {
120-
Node* cast = new CastLLNode(n, t, dependency);
135+
Node* cast = new CastLLNode(n, t, dependency, extra_types);
121136
cast->set_req(0, c);
122137
return cast;
123138
}
124139
case Op_CastPP: {
125-
Node* cast = new CastPPNode(n, t, dependency);
140+
Node* cast = new CastPPNode(n, t, dependency, extra_types);
126141
cast->set_req(0, c);
127142
return cast;
128143
}
129144
case Op_CastFF: {
130-
Node* cast = new CastFFNode(n, t, dependency);
145+
Node* cast = new CastFFNode(n, t, dependency, extra_types);
131146
cast->set_req(0, c);
132147
return cast;
133148
}
134149
case Op_CastDD: {
135-
Node* cast = new CastDDNode(n, t, dependency);
150+
Node* cast = new CastDDNode(n, t, dependency, extra_types);
136151
cast->set_req(0, c);
137152
return cast;
138153
}
139154
case Op_CastVV: {
140-
Node* cast = new CastVVNode(n, t, dependency);
155+
Node* cast = new CastVVNode(n, t, dependency, extra_types);
141156
cast->set_req(0, c);
142157
return cast;
143158
}
144-
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency);
159+
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency, extra_types);
145160
default:
146161
fatal("Bad opcode %d", opcode);
147162
}
@@ -151,10 +166,10 @@ Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t,
151166
Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt) {
152167
switch(bt) {
153168
case T_INT: {
154-
return make_cast(Op_CastII, c, n, t, dependency);
169+
return make_cast(Op_CastII, c, n, t, dependency, nullptr);
155170
}
156171
case T_LONG: {
157-
return make_cast(Op_CastLL, c, n, t, dependency);
172+
return make_cast(Op_CastLL, c, n, t, dependency, nullptr);
158173
}
159174
default:
160175
fatal("Bad basic type %s", type2name(bt));
@@ -187,7 +202,7 @@ TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt)
187202
u->outcnt() > 0 &&
188203
u->Opcode() == opc &&
189204
u->in(0) != nullptr &&
190-
u->bottom_type()->higher_equal(type())) {
205+
higher_equal_types(gvn, u)) {
191206
if (pt->is_dominator(u->in(0), ctl)) {
192207
return u->as_Type();
193208
}
@@ -203,9 +218,28 @@ TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt)
203218
return nullptr;
204219
}
205220

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

527-
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency) {
561+
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency,
562+
const TypeTuple* types) {
528563
Node* cast= nullptr;
529564
if (type->isa_int()) {
530-
cast = make_cast(Op_CastII, c, in, type, dependency);
565+
cast = make_cast(Op_CastII, c, in, type, dependency, types);
531566
} else if (type->isa_long()) {
532-
cast = make_cast(Op_CastLL, c, in, type, dependency);
567+
cast = make_cast(Op_CastLL, c, in, type, dependency, types);
533568
} else if (type->isa_float()) {
534-
cast = make_cast(Op_CastFF, c, in, type, dependency);
569+
cast = make_cast(Op_CastFF, c, in, type, dependency, types);
535570
} else if (type->isa_double()) {
536-
cast = make_cast(Op_CastDD, c, in, type, dependency);
571+
cast = make_cast(Op_CastDD, c, in, type, dependency, types);
537572
} else if (type->isa_vect()) {
538-
cast = make_cast(Op_CastVV, c, in, type, dependency);
573+
cast = make_cast(Op_CastVV, c, in, type, dependency, types);
539574
} else if (type->isa_ptr()) {
540-
cast = make_cast(Op_CastPP, c, in, type, dependency);
575+
cast = make_cast(Op_CastPP, c, in, type, dependency, types);
541576
}
542577
return cast;
543578
}

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)