Mercurial > hg > truffle
annotate src/share/vm/opto/addnode.hpp @ 452:00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery.
Reviewed-by: apetrusenko, jcoomes
author | ysr |
---|---|
date | Thu, 20 Nov 2008 12:27:41 -0800 |
parents | ff5961f4c095 |
children | b5fdf39b9749 |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 // Portions of code courtesy of Clifford Click | |
26 | |
27 class PhaseTransform; | |
28 | |
29 //------------------------------AddNode---------------------------------------- | |
30 // Classic Add functionality. This covers all the usual 'add' behaviors for | |
31 // an algebraic ring. Add-integer, add-float, add-double, and binary-or are | |
32 // all inherited from this class. The various identity values are supplied | |
33 // by virtual functions. | |
34 class AddNode : public Node { | |
35 virtual uint hash() const; | |
36 public: | |
37 AddNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { | |
38 init_class_id(Class_Add); | |
39 } | |
40 | |
41 // Handle algebraic identities here. If we have an identity, return the Node | |
42 // we are equivalent to. We look for "add of zero" as an identity. | |
43 virtual Node *Identity( PhaseTransform *phase ); | |
44 | |
45 // We also canonicalize the Node, moving constants to the right input, | |
46 // and flatten expressions (so that 1+x+2 becomes x+3). | |
47 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
48 | |
49 // Compute a new Type for this node. Basically we just do the pre-check, | |
50 // then call the virtual add() to set the type. | |
51 virtual const Type *Value( PhaseTransform *phase ) const; | |
52 | |
53 // Check if this addition involves the additive identity | |
54 virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const; | |
55 | |
56 // Supplied function returns the sum of the inputs. | |
57 // This also type-checks the inputs for sanity. Guaranteed never to | |
58 // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. | |
59 virtual const Type *add_ring( const Type *, const Type * ) const = 0; | |
60 | |
61 // Supplied function to return the additive identity type | |
62 virtual const Type *add_id() const = 0; | |
63 | |
64 }; | |
65 | |
66 //------------------------------AddINode--------------------------------------- | |
67 // Add 2 integers | |
68 class AddINode : public AddNode { | |
69 public: | |
70 AddINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
71 virtual int Opcode() const; | |
72 virtual const Type *add_ring( const Type *, const Type * ) const; | |
73 virtual const Type *add_id() const { return TypeInt::ZERO; } | |
74 virtual const Type *bottom_type() const { return TypeInt::INT; } | |
75 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
76 virtual Node *Identity( PhaseTransform *phase ); | |
77 virtual uint ideal_reg() const { return Op_RegI; } | |
78 }; | |
79 | |
80 //------------------------------AddLNode--------------------------------------- | |
81 // Add 2 longs | |
82 class AddLNode : public AddNode { | |
83 public: | |
84 AddLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
85 virtual int Opcode() const; | |
86 virtual const Type *add_ring( const Type *, const Type * ) const; | |
87 virtual const Type *add_id() const { return TypeLong::ZERO; } | |
88 virtual const Type *bottom_type() const { return TypeLong::LONG; } | |
89 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
90 virtual Node *Identity( PhaseTransform *phase ); | |
91 virtual uint ideal_reg() const { return Op_RegL; } | |
92 }; | |
93 | |
94 //------------------------------AddFNode--------------------------------------- | |
95 // Add 2 floats | |
96 class AddFNode : public AddNode { | |
97 public: | |
98 AddFNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
99 virtual int Opcode() const; | |
100 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
101 virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const; | |
102 virtual const Type *add_ring( const Type *, const Type * ) const; | |
103 virtual const Type *add_id() const { return TypeF::ZERO; } | |
104 virtual const Type *bottom_type() const { return Type::FLOAT; } | |
105 virtual Node *Identity( PhaseTransform *phase ) { return this; } | |
106 virtual uint ideal_reg() const { return Op_RegF; } | |
107 }; | |
108 | |
109 //------------------------------AddDNode--------------------------------------- | |
110 // Add 2 doubles | |
111 class AddDNode : public AddNode { | |
112 public: | |
113 AddDNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
114 virtual int Opcode() const; | |
115 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
116 virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const; | |
117 virtual const Type *add_ring( const Type *, const Type * ) const; | |
118 virtual const Type *add_id() const { return TypeD::ZERO; } | |
119 virtual const Type *bottom_type() const { return Type::DOUBLE; } | |
120 virtual Node *Identity( PhaseTransform *phase ) { return this; } | |
121 virtual uint ideal_reg() const { return Op_RegD; } | |
122 }; | |
123 | |
124 //------------------------------AddPNode--------------------------------------- | |
125 // Add pointer plus integer to get pointer. NOT commutative, really. | |
126 // So not really an AddNode. Lives here, because people associate it with | |
127 // an add. | |
128 class AddPNode : public Node { | |
129 public: | |
130 enum { Control, // When is it safe to do this add? | |
131 Base, // Base oop, for GC purposes | |
132 Address, // Actually address, derived from base | |
133 Offset } ; // Offset added to address | |
134 AddPNode( Node *base, Node *ptr, Node *off ) : Node(0,base,ptr,off) { | |
135 init_class_id(Class_AddP); | |
136 } | |
137 virtual int Opcode() const; | |
138 virtual Node *Identity( PhaseTransform *phase ); | |
139 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
140 virtual const Type *Value( PhaseTransform *phase ) const; | |
141 virtual const Type *bottom_type() const; | |
142 virtual uint ideal_reg() const { return Op_RegP; } | |
143 Node *base_node() { assert( req() > Base, "Missing base"); return in(Base); } | |
144 static Node* Ideal_base_and_offset(Node* ptr, PhaseTransform* phase, | |
145 // second return value: | |
146 intptr_t& offset); | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
147 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
148 // Collect the AddP offset values into the elements array, giving up |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
149 // if there are more than length. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
150 int unpack_offsets(Node* elements[], int length); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
151 |
0 | 152 // Do not match base-ptr edge |
153 virtual uint match_edge(uint idx) const; | |
154 static const Type *mach_bottom_type(const MachNode* n); // used by ad_<arch>.hpp | |
155 }; | |
156 | |
157 //------------------------------OrINode---------------------------------------- | |
158 // Logically OR 2 integers. Included with the ADD nodes because it inherits | |
159 // all the behavior of addition on a ring. | |
160 class OrINode : public AddNode { | |
161 public: | |
162 OrINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
163 virtual int Opcode() const; | |
164 virtual const Type *add_ring( const Type *, const Type * ) const; | |
165 virtual const Type *add_id() const { return TypeInt::ZERO; } | |
166 virtual const Type *bottom_type() const { return TypeInt::INT; } | |
167 virtual Node *Identity( PhaseTransform *phase ); | |
168 virtual uint ideal_reg() const { return Op_RegI; } | |
169 }; | |
170 | |
171 //------------------------------OrLNode---------------------------------------- | |
172 // Logically OR 2 longs. Included with the ADD nodes because it inherits | |
173 // all the behavior of addition on a ring. | |
174 class OrLNode : public AddNode { | |
175 public: | |
176 OrLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
177 virtual int Opcode() const; | |
178 virtual const Type *add_ring( const Type *, const Type * ) const; | |
179 virtual const Type *add_id() const { return TypeLong::ZERO; } | |
180 virtual const Type *bottom_type() const { return TypeLong::LONG; } | |
181 virtual Node *Identity( PhaseTransform *phase ); | |
182 virtual uint ideal_reg() const { return Op_RegL; } | |
183 }; | |
184 | |
185 //------------------------------XorINode--------------------------------------- | |
186 // XOR'ing 2 integers | |
187 class XorINode : public AddNode { | |
188 public: | |
189 XorINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
190 virtual int Opcode() const; | |
191 virtual const Type *add_ring( const Type *, const Type * ) const; | |
192 virtual const Type *add_id() const { return TypeInt::ZERO; } | |
193 virtual const Type *bottom_type() const { return TypeInt::INT; } | |
194 virtual uint ideal_reg() const { return Op_RegI; } | |
195 }; | |
196 | |
197 //------------------------------XorINode--------------------------------------- | |
198 // XOR'ing 2 longs | |
199 class XorLNode : public AddNode { | |
200 public: | |
201 XorLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
202 virtual int Opcode() const; | |
203 virtual const Type *add_ring( const Type *, const Type * ) const; | |
204 virtual const Type *add_id() const { return TypeLong::ZERO; } | |
205 virtual const Type *bottom_type() const { return TypeLong::LONG; } | |
206 virtual uint ideal_reg() const { return Op_RegL; } | |
207 }; | |
208 | |
209 //------------------------------MaxNode---------------------------------------- | |
210 // Max (or min) of 2 values. Included with the ADD nodes because it inherits | |
211 // all the behavior of addition on a ring. Only new thing is that we allow | |
212 // 2 equal inputs to be equal. | |
213 class MaxNode : public AddNode { | |
214 public: | |
215 MaxNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} | |
216 virtual int Opcode() const = 0; | |
217 }; | |
218 | |
219 //------------------------------MaxINode--------------------------------------- | |
220 // Maximum of 2 integers. Included with the ADD nodes because it inherits | |
221 // all the behavior of addition on a ring. | |
222 class MaxINode : public MaxNode { | |
223 public: | |
224 MaxINode( Node *in1, Node *in2 ) : MaxNode(in1,in2) {} | |
225 virtual int Opcode() const; | |
226 virtual const Type *add_ring( const Type *, const Type * ) const; | |
227 virtual const Type *add_id() const { return TypeInt::make(min_jint); } | |
228 virtual const Type *bottom_type() const { return TypeInt::INT; } | |
229 virtual uint ideal_reg() const { return Op_RegI; } | |
230 }; | |
231 | |
232 //------------------------------MinINode--------------------------------------- | |
233 // MINimum of 2 integers. Included with the ADD nodes because it inherits | |
234 // all the behavior of addition on a ring. | |
235 class MinINode : public MaxNode { | |
236 public: | |
237 MinINode( Node *in1, Node *in2 ) : MaxNode(in1,in2) {} | |
238 virtual int Opcode() const; | |
239 virtual const Type *add_ring( const Type *, const Type * ) const; | |
240 virtual const Type *add_id() const { return TypeInt::make(max_jint); } | |
241 virtual const Type *bottom_type() const { return TypeInt::INT; } | |
242 virtual uint ideal_reg() const { return Op_RegI; } | |
243 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
244 }; |