Mercurial > hg > truffle
annotate src/share/vm/opto/mulnode.hpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | 8c92982cbbc4 |
children |
rev | line source |
---|---|
0 | 1 /* |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
3842
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_MULNODE_HPP |
26 #define SHARE_VM_OPTO_MULNODE_HPP | |
27 | |
28 #include "opto/node.hpp" | |
29 #include "opto/opcodes.hpp" | |
30 #include "opto/type.hpp" | |
31 | |
0 | 32 // Portions of code courtesy of Clifford Click |
33 | |
34 class PhaseTransform; | |
35 | |
36 //------------------------------MulNode---------------------------------------- | |
37 // Classic MULTIPLY functionality. This covers all the usual 'multiply' | |
38 // behaviors for an algebraic ring. Multiply-integer, multiply-float, | |
39 // multiply-double, and binary-and are all inherited from this class. The | |
40 // various identity values are supplied by virtual functions. | |
41 class MulNode : public Node { | |
42 virtual uint hash() const; | |
43 public: | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
3842
diff
changeset
|
44 MulNode( Node *in1, Node *in2 ): Node(0,in1,in2) { |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
3842
diff
changeset
|
45 init_class_id(Class_Mul); |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
3842
diff
changeset
|
46 } |
0 | 47 |
48 // Handle algebraic identities here. If we have an identity, return the Node | |
49 // we are equivalent to. We look for "add of zero" as an identity. | |
50 virtual Node *Identity( PhaseTransform *phase ); | |
51 | |
52 // We also canonicalize the Node, moving constants to the right input, | |
53 // and flatten expressions (so that 1+x+2 becomes x+3). | |
54 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
55 | |
56 // Compute a new Type for this node. Basically we just do the pre-check, | |
57 // then call the virtual add() to set the type. | |
58 virtual const Type *Value( PhaseTransform *phase ) const; | |
59 | |
60 // Supplied function returns the product of the inputs. | |
61 // This also type-checks the inputs for sanity. Guaranteed never to | |
62 // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. | |
63 // This call recognizes the multiplicative zero type. | |
64 virtual const Type *mul_ring( const Type *, const Type * ) const = 0; | |
65 | |
66 // Supplied function to return the multiplicative identity type | |
67 virtual const Type *mul_id() const = 0; | |
68 | |
69 // Supplied function to return the additive identity type | |
70 virtual const Type *add_id() const = 0; | |
71 | |
72 // Supplied function to return the additive opcode | |
73 virtual int add_opcode() const = 0; | |
74 | |
75 // Supplied function to return the multiplicative opcode | |
76 virtual int mul_opcode() const = 0; | |
77 | |
78 }; | |
79 | |
80 //------------------------------MulINode--------------------------------------- | |
81 // Multiply 2 integers | |
82 class MulINode : public MulNode { | |
83 public: | |
84 MulINode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} | |
85 virtual int Opcode() const; | |
86 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
87 virtual const Type *mul_ring( const Type *, const Type * ) const; | |
88 const Type *mul_id() const { return TypeInt::ONE; } | |
89 const Type *add_id() const { return TypeInt::ZERO; } | |
90 int add_opcode() const { return Op_AddI; } | |
91 int mul_opcode() const { return Op_MulI; } | |
92 const Type *bottom_type() const { return TypeInt::INT; } | |
93 virtual uint ideal_reg() const { return Op_RegI; } | |
94 }; | |
95 | |
96 //------------------------------MulLNode--------------------------------------- | |
97 // Multiply 2 longs | |
98 class MulLNode : public MulNode { | |
99 public: | |
100 MulLNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} | |
101 virtual int Opcode() const; | |
102 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
103 virtual const Type *mul_ring( const Type *, const Type * ) const; | |
104 const Type *mul_id() const { return TypeLong::ONE; } | |
105 const Type *add_id() const { return TypeLong::ZERO; } | |
106 int add_opcode() const { return Op_AddL; } | |
107 int mul_opcode() const { return Op_MulL; } | |
108 const Type *bottom_type() const { return TypeLong::LONG; } | |
109 virtual uint ideal_reg() const { return Op_RegL; } | |
110 }; | |
111 | |
112 | |
113 //------------------------------MulFNode--------------------------------------- | |
114 // Multiply 2 floats | |
115 class MulFNode : public MulNode { | |
116 public: | |
117 MulFNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} | |
118 virtual int Opcode() const; | |
119 virtual const Type *mul_ring( const Type *, const Type * ) const; | |
120 const Type *mul_id() const { return TypeF::ONE; } | |
121 const Type *add_id() const { return TypeF::ZERO; } | |
122 int add_opcode() const { return Op_AddF; } | |
123 int mul_opcode() const { return Op_MulF; } | |
124 const Type *bottom_type() const { return Type::FLOAT; } | |
125 virtual uint ideal_reg() const { return Op_RegF; } | |
126 }; | |
127 | |
128 //------------------------------MulDNode--------------------------------------- | |
129 // Multiply 2 doubles | |
130 class MulDNode : public MulNode { | |
131 public: | |
132 MulDNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {} | |
133 virtual int Opcode() const; | |
134 virtual const Type *mul_ring( const Type *, const Type * ) const; | |
135 const Type *mul_id() const { return TypeD::ONE; } | |
136 const Type *add_id() const { return TypeD::ZERO; } | |
137 int add_opcode() const { return Op_AddD; } | |
138 int mul_opcode() const { return Op_MulD; } | |
139 const Type *bottom_type() const { return Type::DOUBLE; } | |
140 virtual uint ideal_reg() const { return Op_RegD; } | |
141 }; | |
142 | |
145 | 143 //-------------------------------MulHiLNode------------------------------------ |
144 // Upper 64 bits of a 64 bit by 64 bit multiply | |
145 class MulHiLNode : public Node { | |
146 public: | |
147 MulHiLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} | |
148 virtual int Opcode() const; | |
149 virtual const Type *Value( PhaseTransform *phase ) const; | |
150 const Type *bottom_type() const { return TypeLong::LONG; } | |
151 virtual uint ideal_reg() const { return Op_RegL; } | |
152 }; | |
0 | 153 |
154 //------------------------------AndINode--------------------------------------- | |
155 // Logically AND 2 integers. Included with the MUL nodes because it inherits | |
156 // all the behavior of multiplication on a ring. | |
157 class AndINode : public MulINode { | |
158 public: | |
159 AndINode( Node *in1, Node *in2 ) : MulINode(in1,in2) {} | |
160 virtual int Opcode() const; | |
161 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
162 virtual Node *Identity( PhaseTransform *phase ); | |
163 virtual const Type *mul_ring( const Type *, const Type * ) const; | |
164 const Type *mul_id() const { return TypeInt::MINUS_1; } | |
165 const Type *add_id() const { return TypeInt::ZERO; } | |
166 int add_opcode() const { return Op_OrI; } | |
167 int mul_opcode() const { return Op_AndI; } | |
168 virtual uint ideal_reg() const { return Op_RegI; } | |
169 }; | |
170 | |
171 //------------------------------AndINode--------------------------------------- | |
172 // Logically AND 2 longs. Included with the MUL nodes because it inherits | |
173 // all the behavior of multiplication on a ring. | |
174 class AndLNode : public MulLNode { | |
175 public: | |
176 AndLNode( Node *in1, Node *in2 ) : MulLNode(in1,in2) {} | |
177 virtual int Opcode() const; | |
178 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
179 virtual Node *Identity( PhaseTransform *phase ); | |
180 virtual const Type *mul_ring( const Type *, const Type * ) const; | |
181 const Type *mul_id() const { return TypeLong::MINUS_1; } | |
182 const Type *add_id() const { return TypeLong::ZERO; } | |
183 int add_opcode() const { return Op_OrL; } | |
184 int mul_opcode() const { return Op_AndL; } | |
185 virtual uint ideal_reg() const { return Op_RegL; } | |
186 }; | |
187 | |
188 //------------------------------LShiftINode------------------------------------ | |
189 // Logical shift left | |
190 class LShiftINode : public Node { | |
191 public: | |
192 LShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} | |
193 virtual int Opcode() const; | |
194 virtual Node *Identity( PhaseTransform *phase ); | |
195 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
196 virtual const Type *Value( PhaseTransform *phase ) const; | |
197 const Type *bottom_type() const { return TypeInt::INT; } | |
198 virtual uint ideal_reg() const { return Op_RegI; } | |
199 }; | |
200 | |
201 //------------------------------LShiftLNode------------------------------------ | |
202 // Logical shift left | |
203 class LShiftLNode : public Node { | |
204 public: | |
205 LShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} | |
206 virtual int Opcode() const; | |
207 virtual Node *Identity( PhaseTransform *phase ); | |
208 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
209 virtual const Type *Value( PhaseTransform *phase ) const; | |
210 const Type *bottom_type() const { return TypeLong::LONG; } | |
211 virtual uint ideal_reg() const { return Op_RegL; } | |
212 }; | |
213 | |
214 //------------------------------RShiftINode------------------------------------ | |
215 // Signed shift right | |
216 class RShiftINode : public Node { | |
217 public: | |
218 RShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} | |
219 virtual int Opcode() const; | |
220 virtual Node *Identity( PhaseTransform *phase ); | |
221 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
222 virtual const Type *Value( PhaseTransform *phase ) const; | |
223 const Type *bottom_type() const { return TypeInt::INT; } | |
224 virtual uint ideal_reg() const { return Op_RegI; } | |
225 }; | |
226 | |
227 //------------------------------RShiftLNode------------------------------------ | |
228 // Signed shift right | |
229 class RShiftLNode : public Node { | |
230 public: | |
231 RShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} | |
232 virtual int Opcode() const; | |
233 virtual Node *Identity( PhaseTransform *phase ); | |
234 virtual const Type *Value( PhaseTransform *phase ) const; | |
235 const Type *bottom_type() const { return TypeLong::LONG; } | |
236 virtual uint ideal_reg() const { return Op_RegL; } | |
237 }; | |
238 | |
239 | |
240 //------------------------------URShiftINode----------------------------------- | |
241 // Logical shift right | |
242 class URShiftINode : public Node { | |
243 public: | |
244 URShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} | |
245 virtual int Opcode() const; | |
246 virtual Node *Identity( PhaseTransform *phase ); | |
247 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
248 virtual const Type *Value( PhaseTransform *phase ) const; | |
249 const Type *bottom_type() const { return TypeInt::INT; } | |
250 virtual uint ideal_reg() const { return Op_RegI; } | |
251 }; | |
252 | |
253 //------------------------------URShiftLNode----------------------------------- | |
254 // Logical shift right | |
255 class URShiftLNode : public Node { | |
256 public: | |
257 URShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {} | |
258 virtual int Opcode() const; | |
259 virtual Node *Identity( PhaseTransform *phase ); | |
260 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
261 virtual const Type *Value( PhaseTransform *phase ) const; | |
262 const Type *bottom_type() const { return TypeLong::LONG; } | |
263 virtual uint ideal_reg() const { return Op_RegL; } | |
264 }; | |
1972 | 265 |
266 #endif // SHARE_VM_OPTO_MULNODE_HPP |