Mercurial > hg > graal-compiler
annotate src/share/vm/opto/vectornode.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | c7b60b601eb4 |
children | 8c92982cbbc4 |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2007, 2010, 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:
579
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
579
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:
579
diff
changeset
|
21 * questions. |
0 | 22 */ |
23 | |
1972 | 24 #include "precompiled.hpp" |
25 #include "memory/allocation.inline.hpp" | |
26 #include "opto/connode.hpp" | |
27 #include "opto/vectornode.hpp" | |
0 | 28 |
29 //------------------------------VectorNode-------------------------------------- | |
30 | |
31 // Return vector type for an element type and vector length. | |
32 const Type* VectorNode::vect_type(BasicType elt_bt, uint len) { | |
33 assert(len <= VectorNode::max_vlen(elt_bt), "len in range"); | |
34 switch(elt_bt) { | |
35 case T_BOOLEAN: | |
36 case T_BYTE: | |
37 switch(len) { | |
38 case 2: return TypeInt::CHAR; | |
39 case 4: return TypeInt::INT; | |
40 case 8: return TypeLong::LONG; | |
41 } | |
42 break; | |
43 case T_CHAR: | |
44 case T_SHORT: | |
45 switch(len) { | |
46 case 2: return TypeInt::INT; | |
47 case 4: return TypeLong::LONG; | |
48 } | |
49 break; | |
50 case T_INT: | |
51 switch(len) { | |
52 case 2: return TypeLong::LONG; | |
53 } | |
54 break; | |
55 case T_LONG: | |
56 break; | |
57 case T_FLOAT: | |
58 switch(len) { | |
59 case 2: return Type::DOUBLE; | |
60 } | |
61 break; | |
62 case T_DOUBLE: | |
63 break; | |
64 } | |
65 ShouldNotReachHere(); | |
66 return NULL; | |
67 } | |
68 | |
69 // Scalar promotion | |
70 VectorNode* VectorNode::scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t) { | |
71 BasicType bt = opd_t->array_element_basic_type(); | |
72 assert(vlen <= VectorNode::max_vlen(bt), "vlen in range"); | |
73 switch (bt) { | |
74 case T_BOOLEAN: | |
75 case T_BYTE: | |
76 if (vlen == 16) return new (C, 2) Replicate16BNode(s); | |
77 if (vlen == 8) return new (C, 2) Replicate8BNode(s); | |
78 if (vlen == 4) return new (C, 2) Replicate4BNode(s); | |
79 break; | |
80 case T_CHAR: | |
81 if (vlen == 8) return new (C, 2) Replicate8CNode(s); | |
82 if (vlen == 4) return new (C, 2) Replicate4CNode(s); | |
83 if (vlen == 2) return new (C, 2) Replicate2CNode(s); | |
84 break; | |
85 case T_SHORT: | |
86 if (vlen == 8) return new (C, 2) Replicate8SNode(s); | |
87 if (vlen == 4) return new (C, 2) Replicate4SNode(s); | |
88 if (vlen == 2) return new (C, 2) Replicate2SNode(s); | |
89 break; | |
90 case T_INT: | |
91 if (vlen == 4) return new (C, 2) Replicate4INode(s); | |
92 if (vlen == 2) return new (C, 2) Replicate2INode(s); | |
93 break; | |
94 case T_LONG: | |
95 if (vlen == 2) return new (C, 2) Replicate2LNode(s); | |
96 break; | |
97 case T_FLOAT: | |
98 if (vlen == 4) return new (C, 2) Replicate4FNode(s); | |
99 if (vlen == 2) return new (C, 2) Replicate2FNode(s); | |
100 break; | |
101 case T_DOUBLE: | |
102 if (vlen == 2) return new (C, 2) Replicate2DNode(s); | |
103 break; | |
104 } | |
105 ShouldNotReachHere(); | |
106 return NULL; | |
107 } | |
108 | |
109 // Return initial Pack node. Additional operands added with add_opd() calls. | |
110 PackNode* PackNode::make(Compile* C, Node* s, const Type* opd_t) { | |
111 BasicType bt = opd_t->array_element_basic_type(); | |
112 switch (bt) { | |
113 case T_BOOLEAN: | |
114 case T_BYTE: | |
115 return new (C, 2) PackBNode(s); | |
116 case T_CHAR: | |
117 return new (C, 2) PackCNode(s); | |
118 case T_SHORT: | |
119 return new (C, 2) PackSNode(s); | |
120 case T_INT: | |
121 return new (C, 2) PackINode(s); | |
122 case T_LONG: | |
123 return new (C, 2) PackLNode(s); | |
124 case T_FLOAT: | |
125 return new (C, 2) PackFNode(s); | |
126 case T_DOUBLE: | |
127 return new (C, 2) PackDNode(s); | |
128 } | |
129 ShouldNotReachHere(); | |
130 return NULL; | |
131 } | |
132 | |
133 // Create a binary tree form for Packs. [lo, hi) (half-open) range | |
134 Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) { | |
135 int ct = hi - lo; | |
136 assert(is_power_of_2(ct), "power of 2"); | |
137 int mid = lo + ct/2; | |
138 Node* n1 = ct == 2 ? in(lo) : binaryTreePack(C, lo, mid); | |
139 Node* n2 = ct == 2 ? in(lo+1) : binaryTreePack(C, mid, hi ); | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
140 int rslt_bsize = ct * type2aelembytes(elt_basic_type()); |
0 | 141 if (bottom_type()->is_floatingpoint()) { |
142 switch (rslt_bsize) { | |
143 case 8: return new (C, 3) PackFNode(n1, n2); | |
144 case 16: return new (C, 3) PackDNode(n1, n2); | |
145 } | |
146 } else { | |
147 assert(bottom_type()->isa_int() || bottom_type()->isa_long(), "int or long"); | |
148 switch (rslt_bsize) { | |
149 case 2: return new (C, 3) Pack2x1BNode(n1, n2); | |
150 case 4: return new (C, 3) Pack2x2BNode(n1, n2); | |
151 case 8: return new (C, 3) PackINode(n1, n2); | |
152 case 16: return new (C, 3) PackLNode(n1, n2); | |
153 } | |
154 } | |
155 ShouldNotReachHere(); | |
156 return NULL; | |
157 } | |
158 | |
159 // Return the vector operator for the specified scalar operation | |
160 // and vector length. One use is to check if the code generator | |
161 // supports the vector operation. | |
162 int VectorNode::opcode(int sopc, uint vlen, const Type* opd_t) { | |
163 BasicType bt = opd_t->array_element_basic_type(); | |
164 if (!(is_power_of_2(vlen) && vlen <= max_vlen(bt))) | |
165 return 0; // unimplemented | |
166 switch (sopc) { | |
167 case Op_AddI: | |
168 switch (bt) { | |
169 case T_BOOLEAN: | |
170 case T_BYTE: return Op_AddVB; | |
171 case T_CHAR: return Op_AddVC; | |
172 case T_SHORT: return Op_AddVS; | |
173 case T_INT: return Op_AddVI; | |
174 } | |
175 ShouldNotReachHere(); | |
176 case Op_AddL: | |
177 assert(bt == T_LONG, "must be"); | |
178 return Op_AddVL; | |
179 case Op_AddF: | |
180 assert(bt == T_FLOAT, "must be"); | |
181 return Op_AddVF; | |
182 case Op_AddD: | |
183 assert(bt == T_DOUBLE, "must be"); | |
184 return Op_AddVD; | |
185 case Op_SubI: | |
186 switch (bt) { | |
187 case T_BOOLEAN: | |
188 case T_BYTE: return Op_SubVB; | |
189 case T_CHAR: return Op_SubVC; | |
190 case T_SHORT: return Op_SubVS; | |
191 case T_INT: return Op_SubVI; | |
192 } | |
193 ShouldNotReachHere(); | |
194 case Op_SubL: | |
195 assert(bt == T_LONG, "must be"); | |
196 return Op_SubVL; | |
197 case Op_SubF: | |
198 assert(bt == T_FLOAT, "must be"); | |
199 return Op_SubVF; | |
200 case Op_SubD: | |
201 assert(bt == T_DOUBLE, "must be"); | |
202 return Op_SubVD; | |
203 case Op_MulF: | |
204 assert(bt == T_FLOAT, "must be"); | |
205 return Op_MulVF; | |
206 case Op_MulD: | |
207 assert(bt == T_DOUBLE, "must be"); | |
208 return Op_MulVD; | |
209 case Op_DivF: | |
210 assert(bt == T_FLOAT, "must be"); | |
211 return Op_DivVF; | |
212 case Op_DivD: | |
213 assert(bt == T_DOUBLE, "must be"); | |
214 return Op_DivVD; | |
215 case Op_LShiftI: | |
216 switch (bt) { | |
217 case T_BOOLEAN: | |
218 case T_BYTE: return Op_LShiftVB; | |
219 case T_CHAR: return Op_LShiftVC; | |
220 case T_SHORT: return Op_LShiftVS; | |
221 case T_INT: return Op_LShiftVI; | |
222 } | |
223 ShouldNotReachHere(); | |
224 case Op_URShiftI: | |
225 switch (bt) { | |
226 case T_BOOLEAN: | |
227 case T_BYTE: return Op_URShiftVB; | |
228 case T_CHAR: return Op_URShiftVC; | |
229 case T_SHORT: return Op_URShiftVS; | |
230 case T_INT: return Op_URShiftVI; | |
231 } | |
232 ShouldNotReachHere(); | |
233 case Op_AndI: | |
234 case Op_AndL: | |
235 return Op_AndV; | |
236 case Op_OrI: | |
237 case Op_OrL: | |
238 return Op_OrV; | |
239 case Op_XorI: | |
240 case Op_XorL: | |
241 return Op_XorV; | |
242 | |
243 case Op_LoadB: | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
196
diff
changeset
|
244 case Op_LoadUS: |
0 | 245 case Op_LoadS: |
246 case Op_LoadI: | |
247 case Op_LoadL: | |
248 case Op_LoadF: | |
249 case Op_LoadD: | |
250 return VectorLoadNode::opcode(sopc, vlen); | |
251 | |
252 case Op_StoreB: | |
253 case Op_StoreC: | |
254 case Op_StoreI: | |
255 case Op_StoreL: | |
256 case Op_StoreF: | |
257 case Op_StoreD: | |
258 return VectorStoreNode::opcode(sopc, vlen); | |
259 } | |
260 return 0; // Unimplemented | |
261 } | |
262 | |
263 // Helper for above. | |
264 int VectorLoadNode::opcode(int sopc, uint vlen) { | |
265 switch (sopc) { | |
266 case Op_LoadB: | |
267 switch (vlen) { | |
268 case 2: return 0; // Unimplemented | |
269 case 4: return Op_Load4B; | |
270 case 8: return Op_Load8B; | |
271 case 16: return Op_Load16B; | |
272 } | |
273 break; | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
196
diff
changeset
|
274 case Op_LoadUS: |
0 | 275 switch (vlen) { |
276 case 2: return Op_Load2C; | |
277 case 4: return Op_Load4C; | |
278 case 8: return Op_Load8C; | |
279 } | |
280 break; | |
281 case Op_LoadS: | |
282 switch (vlen) { | |
283 case 2: return Op_Load2S; | |
284 case 4: return Op_Load4S; | |
285 case 8: return Op_Load8S; | |
286 } | |
287 break; | |
288 case Op_LoadI: | |
289 switch (vlen) { | |
290 case 2: return Op_Load2I; | |
291 case 4: return Op_Load4I; | |
292 } | |
293 break; | |
294 case Op_LoadL: | |
295 if (vlen == 2) return Op_Load2L; | |
296 break; | |
297 case Op_LoadF: | |
298 switch (vlen) { | |
299 case 2: return Op_Load2F; | |
300 case 4: return Op_Load4F; | |
301 } | |
302 break; | |
303 case Op_LoadD: | |
304 if (vlen == 2) return Op_Load2D; | |
305 break; | |
306 } | |
307 return 0; // Unimplemented | |
308 } | |
309 | |
310 // Helper for above | |
311 int VectorStoreNode::opcode(int sopc, uint vlen) { | |
312 switch (sopc) { | |
313 case Op_StoreB: | |
314 switch (vlen) { | |
315 case 2: return 0; // Unimplemented | |
316 case 4: return Op_Store4B; | |
317 case 8: return Op_Store8B; | |
318 case 16: return Op_Store16B; | |
319 } | |
320 break; | |
321 case Op_StoreC: | |
322 switch (vlen) { | |
323 case 2: return Op_Store2C; | |
324 case 4: return Op_Store4C; | |
325 case 8: return Op_Store8C; | |
326 } | |
327 break; | |
328 case Op_StoreI: | |
329 switch (vlen) { | |
330 case 2: return Op_Store2I; | |
331 case 4: return Op_Store4I; | |
332 } | |
333 break; | |
334 case Op_StoreL: | |
335 if (vlen == 2) return Op_Store2L; | |
336 break; | |
337 case Op_StoreF: | |
338 switch (vlen) { | |
339 case 2: return Op_Store2F; | |
340 case 4: return Op_Store4F; | |
341 } | |
342 break; | |
343 case Op_StoreD: | |
344 if (vlen == 2) return Op_Store2D; | |
345 break; | |
346 } | |
347 return 0; // Unimplemented | |
348 } | |
349 | |
350 // Return the vector version of a scalar operation node. | |
351 VectorNode* VectorNode::make(Compile* C, int sopc, Node* n1, Node* n2, uint vlen, const Type* opd_t) { | |
352 int vopc = opcode(sopc, vlen, opd_t); | |
353 | |
354 switch (vopc) { | |
355 case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vlen); | |
356 case Op_AddVC: return new (C, 3) AddVCNode(n1, n2, vlen); | |
357 case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vlen); | |
358 case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vlen); | |
359 case Op_AddVL: return new (C, 3) AddVLNode(n1, n2, vlen); | |
360 case Op_AddVF: return new (C, 3) AddVFNode(n1, n2, vlen); | |
361 case Op_AddVD: return new (C, 3) AddVDNode(n1, n2, vlen); | |
362 | |
363 case Op_SubVB: return new (C, 3) SubVBNode(n1, n2, vlen); | |
364 case Op_SubVC: return new (C, 3) SubVCNode(n1, n2, vlen); | |
365 case Op_SubVS: return new (C, 3) SubVSNode(n1, n2, vlen); | |
366 case Op_SubVI: return new (C, 3) SubVINode(n1, n2, vlen); | |
367 case Op_SubVL: return new (C, 3) SubVLNode(n1, n2, vlen); | |
368 case Op_SubVF: return new (C, 3) SubVFNode(n1, n2, vlen); | |
369 case Op_SubVD: return new (C, 3) SubVDNode(n1, n2, vlen); | |
370 | |
371 case Op_MulVF: return new (C, 3) MulVFNode(n1, n2, vlen); | |
372 case Op_MulVD: return new (C, 3) MulVDNode(n1, n2, vlen); | |
373 | |
374 case Op_DivVF: return new (C, 3) DivVFNode(n1, n2, vlen); | |
375 case Op_DivVD: return new (C, 3) DivVDNode(n1, n2, vlen); | |
376 | |
377 case Op_LShiftVB: return new (C, 3) LShiftVBNode(n1, n2, vlen); | |
378 case Op_LShiftVC: return new (C, 3) LShiftVCNode(n1, n2, vlen); | |
379 case Op_LShiftVS: return new (C, 3) LShiftVSNode(n1, n2, vlen); | |
380 case Op_LShiftVI: return new (C, 3) LShiftVINode(n1, n2, vlen); | |
381 | |
382 case Op_URShiftVB: return new (C, 3) URShiftVBNode(n1, n2, vlen); | |
383 case Op_URShiftVC: return new (C, 3) URShiftVCNode(n1, n2, vlen); | |
384 case Op_URShiftVS: return new (C, 3) URShiftVSNode(n1, n2, vlen); | |
385 case Op_URShiftVI: return new (C, 3) URShiftVINode(n1, n2, vlen); | |
386 | |
387 case Op_AndV: return new (C, 3) AndVNode(n1, n2, vlen, opd_t->array_element_basic_type()); | |
388 case Op_OrV: return new (C, 3) OrVNode (n1, n2, vlen, opd_t->array_element_basic_type()); | |
389 case Op_XorV: return new (C, 3) XorVNode(n1, n2, vlen, opd_t->array_element_basic_type()); | |
390 } | |
391 ShouldNotReachHere(); | |
392 return NULL; | |
393 } | |
394 | |
395 // Return the vector version of a scalar load node. | |
396 VectorLoadNode* VectorLoadNode::make(Compile* C, int opc, Node* ctl, Node* mem, | |
397 Node* adr, const TypePtr* atyp, uint vlen) { | |
398 int vopc = opcode(opc, vlen); | |
399 | |
400 switch(vopc) { | |
401 case Op_Load16B: return new (C, 3) Load16BNode(ctl, mem, adr, atyp); | |
402 case Op_Load8B: return new (C, 3) Load8BNode(ctl, mem, adr, atyp); | |
403 case Op_Load4B: return new (C, 3) Load4BNode(ctl, mem, adr, atyp); | |
404 | |
405 case Op_Load8C: return new (C, 3) Load8CNode(ctl, mem, adr, atyp); | |
406 case Op_Load4C: return new (C, 3) Load4CNode(ctl, mem, adr, atyp); | |
407 case Op_Load2C: return new (C, 3) Load2CNode(ctl, mem, adr, atyp); | |
408 | |
409 case Op_Load8S: return new (C, 3) Load8SNode(ctl, mem, adr, atyp); | |
410 case Op_Load4S: return new (C, 3) Load4SNode(ctl, mem, adr, atyp); | |
411 case Op_Load2S: return new (C, 3) Load2SNode(ctl, mem, adr, atyp); | |
412 | |
413 case Op_Load4I: return new (C, 3) Load4INode(ctl, mem, adr, atyp); | |
414 case Op_Load2I: return new (C, 3) Load2INode(ctl, mem, adr, atyp); | |
415 | |
416 case Op_Load2L: return new (C, 3) Load2LNode(ctl, mem, adr, atyp); | |
417 | |
418 case Op_Load4F: return new (C, 3) Load4FNode(ctl, mem, adr, atyp); | |
419 case Op_Load2F: return new (C, 3) Load2FNode(ctl, mem, adr, atyp); | |
420 | |
421 case Op_Load2D: return new (C, 3) Load2DNode(ctl, mem, adr, atyp); | |
422 } | |
423 ShouldNotReachHere(); | |
424 return NULL; | |
425 } | |
426 | |
427 // Return the vector version of a scalar store node. | |
428 VectorStoreNode* VectorStoreNode::make(Compile* C, int opc, Node* ctl, Node* mem, | |
3842 | 429 Node* adr, const TypePtr* atyp, Node* val, |
0 | 430 uint vlen) { |
431 int vopc = opcode(opc, vlen); | |
432 | |
433 switch(vopc) { | |
434 case Op_Store16B: return new (C, 4) Store16BNode(ctl, mem, adr, atyp, val); | |
435 case Op_Store8B: return new (C, 4) Store8BNode(ctl, mem, adr, atyp, val); | |
436 case Op_Store4B: return new (C, 4) Store4BNode(ctl, mem, adr, atyp, val); | |
437 | |
438 case Op_Store8C: return new (C, 4) Store8CNode(ctl, mem, adr, atyp, val); | |
439 case Op_Store4C: return new (C, 4) Store4CNode(ctl, mem, adr, atyp, val); | |
440 case Op_Store2C: return new (C, 4) Store2CNode(ctl, mem, adr, atyp, val); | |
441 | |
442 case Op_Store4I: return new (C, 4) Store4INode(ctl, mem, adr, atyp, val); | |
443 case Op_Store2I: return new (C, 4) Store2INode(ctl, mem, adr, atyp, val); | |
444 | |
445 case Op_Store2L: return new (C, 4) Store2LNode(ctl, mem, adr, atyp, val); | |
446 | |
447 case Op_Store4F: return new (C, 4) Store4FNode(ctl, mem, adr, atyp, val); | |
448 case Op_Store2F: return new (C, 4) Store2FNode(ctl, mem, adr, atyp, val); | |
449 | |
450 case Op_Store2D: return new (C, 4) Store2DNode(ctl, mem, adr, atyp, val); | |
451 } | |
452 ShouldNotReachHere(); | |
453 return NULL; | |
454 } | |
455 | |
456 // Extract a scalar element of vector. | |
457 Node* ExtractNode::make(Compile* C, Node* v, uint position, const Type* opd_t) { | |
458 BasicType bt = opd_t->array_element_basic_type(); | |
459 assert(position < VectorNode::max_vlen(bt), "pos in range"); | |
460 ConINode* pos = ConINode::make(C, (int)position); | |
461 switch (bt) { | |
462 case T_BOOLEAN: | |
463 case T_BYTE: | |
464 return new (C, 3) ExtractBNode(v, pos); | |
465 case T_CHAR: | |
466 return new (C, 3) ExtractCNode(v, pos); | |
467 case T_SHORT: | |
468 return new (C, 3) ExtractSNode(v, pos); | |
469 case T_INT: | |
470 return new (C, 3) ExtractINode(v, pos); | |
471 case T_LONG: | |
472 return new (C, 3) ExtractLNode(v, pos); | |
473 case T_FLOAT: | |
474 return new (C, 3) ExtractFNode(v, pos); | |
475 case T_DOUBLE: | |
476 return new (C, 3) ExtractDNode(v, pos); | |
477 } | |
478 ShouldNotReachHere(); | |
479 return NULL; | |
480 } |