Mercurial > hg > truffle
annotate src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @ 15388:769fc3629f59
Add phase FlowSensitiveReductionPhase.
It is possible to remove GuardingPiNodes, CheckCastNodes, and FixedGuards during
HighTier under certain conditions (control-flow sensitive conditions).
The phase added in this commit (FlowSensitiveReductionPhase) does that,
and in addition replaces usages with "downcasting" PiNodes when possible
thus resulting in more precise object stamps (e.g., non-null).
Finally, usages of floating, side-effects free, expressions are also simplified
(as per control-flow sensitive conditions).
The newly added phase runs only during HighTier and can be deactivated
using Graal option FlowSensitiveReduction (it is active by default).
author | Miguel Garcia <miguel.m.garcia@oracle.com> |
---|---|
date | Fri, 25 Apr 2014 16:50:52 +0200 |
parents | 4ca6dc0799b6 |
children | 89152779163c |
rev | line source |
---|---|
0 | 1 /* |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
2 * Copyright (c) 2005, 2013, 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:
1060
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1060
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:
1060
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_Compilation.hpp" | |
27 #include "c1/c1_FrameMap.hpp" | |
28 #include "c1/c1_Instruction.hpp" | |
29 #include "c1/c1_LIRAssembler.hpp" | |
30 #include "c1/c1_LIRGenerator.hpp" | |
31 #include "c1/c1_Runtime1.hpp" | |
32 #include "c1/c1_ValueStack.hpp" | |
33 #include "ci/ciArray.hpp" | |
34 #include "ci/ciObjArrayKlass.hpp" | |
35 #include "ci/ciTypeArrayKlass.hpp" | |
36 #include "runtime/sharedRuntime.hpp" | |
37 #include "runtime/stubRoutines.hpp" | |
38 #include "vmreg_x86.inline.hpp" | |
0 | 39 |
40 #ifdef ASSERT | |
41 #define __ gen()->lir(__FILE__, __LINE__)-> | |
42 #else | |
43 #define __ gen()->lir()-> | |
44 #endif | |
45 | |
46 // Item will be loaded into a byte register; Intel only | |
47 void LIRItem::load_byte_item() { | |
48 load_item(); | |
49 LIR_Opr res = result(); | |
50 | |
51 if (!res->is_virtual() || !_gen->is_vreg_flag_set(res, LIRGenerator::byte_reg)) { | |
52 // make sure that it is a byte register | |
53 assert(!value()->type()->is_float() && !value()->type()->is_double(), | |
54 "can't load floats in byte register"); | |
55 LIR_Opr reg = _gen->rlock_byte(T_BYTE); | |
56 __ move(res, reg); | |
57 | |
58 _result = reg; | |
59 } | |
60 } | |
61 | |
62 | |
63 void LIRItem::load_nonconstant() { | |
64 LIR_Opr r = value()->operand(); | |
65 if (r->is_constant()) { | |
66 _result = r; | |
67 } else { | |
68 load_item(); | |
69 } | |
70 } | |
71 | |
72 //-------------------------------------------------------------- | |
73 // LIRGenerator | |
74 //-------------------------------------------------------------- | |
75 | |
76 | |
77 LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::rax_oop_opr; } | |
78 LIR_Opr LIRGenerator::exceptionPcOpr() { return FrameMap::rdx_opr; } | |
79 LIR_Opr LIRGenerator::divInOpr() { return FrameMap::rax_opr; } | |
80 LIR_Opr LIRGenerator::divOutOpr() { return FrameMap::rax_opr; } | |
81 LIR_Opr LIRGenerator::remOutOpr() { return FrameMap::rdx_opr; } | |
82 LIR_Opr LIRGenerator::shiftCountOpr() { return FrameMap::rcx_opr; } | |
83 LIR_Opr LIRGenerator::syncTempOpr() { return FrameMap::rax_opr; } | |
84 LIR_Opr LIRGenerator::getThreadTemp() { return LIR_OprFact::illegalOpr; } | |
85 | |
86 | |
87 LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { | |
88 LIR_Opr opr; | |
89 switch (type->tag()) { | |
90 case intTag: opr = FrameMap::rax_opr; break; | |
91 case objectTag: opr = FrameMap::rax_oop_opr; break; | |
304 | 92 case longTag: opr = FrameMap::long0_opr; break; |
0 | 93 case floatTag: opr = UseSSE >= 1 ? FrameMap::xmm0_float_opr : FrameMap::fpu0_float_opr; break; |
94 case doubleTag: opr = UseSSE >= 2 ? FrameMap::xmm0_double_opr : FrameMap::fpu0_double_opr; break; | |
95 | |
96 case addressTag: | |
97 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; | |
98 } | |
99 | |
100 assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch"); | |
101 return opr; | |
102 } | |
103 | |
104 | |
105 LIR_Opr LIRGenerator::rlock_byte(BasicType type) { | |
106 LIR_Opr reg = new_register(T_INT); | |
107 set_vreg_flag(reg, LIRGenerator::byte_reg); | |
108 return reg; | |
109 } | |
110 | |
111 | |
112 //--------- loading items into registers -------------------------------- | |
113 | |
114 | |
115 // i486 instructions can inline constants | |
116 bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { | |
117 if (type == T_SHORT || type == T_CHAR) { | |
118 // there is no immediate move of word values in asembler_i486.?pp | |
119 return false; | |
120 } | |
121 Constant* c = v->as_Constant(); | |
1819 | 122 if (c && c->state_before() == NULL) { |
0 | 123 // constants of any type can be stored directly, except for |
124 // unloaded object constants. | |
125 return true; | |
126 } | |
127 return false; | |
128 } | |
129 | |
130 | |
131 bool LIRGenerator::can_inline_as_constant(Value v) const { | |
304 | 132 if (v->type()->tag() == longTag) return false; |
0 | 133 return v->type()->tag() != objectTag || |
134 (v->type()->is_constant() && v->type()->as_ObjectType()->constant_value()->is_null_object()); | |
135 } | |
136 | |
137 | |
138 bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { | |
304 | 139 if (c->type() == T_LONG) return false; |
0 | 140 return c->type() != T_OBJECT || c->as_jobject() == NULL; |
141 } | |
142 | |
143 | |
144 LIR_Opr LIRGenerator::safepoint_poll_register() { | |
145 return LIR_OprFact::illegalOpr; | |
146 } | |
147 | |
148 | |
149 LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, | |
150 int shift, int disp, BasicType type) { | |
151 assert(base->is_register(), "must be"); | |
152 if (index->is_constant()) { | |
153 return new LIR_Address(base, | |
154 (index->as_constant_ptr()->as_jint() << shift) + disp, | |
155 type); | |
156 } else { | |
157 return new LIR_Address(base, index, (LIR_Address::Scale)shift, disp, type); | |
158 } | |
159 } | |
160 | |
161 | |
162 LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, | |
163 BasicType type, bool needs_card_mark) { | |
164 int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type); | |
165 | |
166 LIR_Address* addr; | |
167 if (index_opr->is_constant()) { | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
168 int elem_size = type2aelembytes(type); |
0 | 169 addr = new LIR_Address(array_opr, |
170 offset_in_bytes + index_opr->as_jint() * elem_size, type); | |
171 } else { | |
304 | 172 #ifdef _LP64 |
173 if (index_opr->type() == T_INT) { | |
174 LIR_Opr tmp = new_register(T_LONG); | |
175 __ convert(Bytecodes::_i2l, index_opr, tmp); | |
176 index_opr = tmp; | |
177 } | |
178 #endif // _LP64 | |
0 | 179 addr = new LIR_Address(array_opr, |
180 index_opr, | |
181 LIR_Address::scale(type), | |
182 offset_in_bytes, type); | |
183 } | |
184 if (needs_card_mark) { | |
185 // This store will need a precise card mark, so go ahead and | |
186 // compute the full adddres instead of computing once for the | |
187 // store and again for the card mark. | |
304 | 188 LIR_Opr tmp = new_pointer_register(); |
0 | 189 __ leal(LIR_OprFact::address(addr), tmp); |
1572 | 190 return new LIR_Address(tmp, type); |
0 | 191 } else { |
192 return addr; | |
193 } | |
194 } | |
195 | |
196 | |
1783 | 197 LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { |
198 LIR_Opr r; | |
199 if (type == T_LONG) { | |
200 r = LIR_OprFact::longConst(x); | |
201 } else if (type == T_INT) { | |
202 r = LIR_OprFact::intConst(x); | |
203 } else { | |
204 ShouldNotReachHere(); | |
205 } | |
206 return r; | |
207 } | |
208 | |
209 void LIRGenerator::increment_counter(address counter, BasicType type, int step) { | |
304 | 210 LIR_Opr pointer = new_pointer_register(); |
211 __ move(LIR_OprFact::intptrConst(counter), pointer); | |
1783 | 212 LIR_Address* addr = new LIR_Address(pointer, type); |
0 | 213 increment_counter(addr, step); |
214 } | |
215 | |
216 | |
217 void LIRGenerator::increment_counter(LIR_Address* addr, int step) { | |
218 __ add((LIR_Opr)addr, LIR_OprFact::intConst(step), (LIR_Opr)addr); | |
219 } | |
220 | |
221 void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) { | |
222 __ cmp_mem_int(condition, base, disp, c, info); | |
223 } | |
224 | |
225 | |
226 void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) { | |
227 __ cmp_reg_mem(condition, reg, new LIR_Address(base, disp, type), info); | |
228 } | |
229 | |
230 | |
231 void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info) { | |
232 __ cmp_reg_mem(condition, reg, new LIR_Address(base, disp, type), info); | |
233 } | |
234 | |
235 | |
236 bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) { | |
237 if (tmp->is_valid()) { | |
238 if (is_power_of_2(c + 1)) { | |
239 __ move(left, tmp); | |
240 __ shift_left(left, log2_intptr(c + 1), left); | |
241 __ sub(left, tmp, result); | |
242 return true; | |
243 } else if (is_power_of_2(c - 1)) { | |
244 __ move(left, tmp); | |
245 __ shift_left(left, log2_intptr(c - 1), left); | |
246 __ add(left, tmp, result); | |
247 return true; | |
248 } | |
249 } | |
250 return false; | |
251 } | |
252 | |
253 | |
254 void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) { | |
255 BasicType type = item->type(); | |
256 __ store(item, new LIR_Address(FrameMap::rsp_opr, in_bytes(offset_from_sp), type)); | |
257 } | |
258 | |
259 //---------------------------------------------------------------------- | |
260 // visitor functions | |
261 //---------------------------------------------------------------------- | |
262 | |
263 | |
264 void LIRGenerator::do_StoreIndexed(StoreIndexed* x) { | |
1819 | 265 assert(x->is_pinned(),""); |
8860 | 266 bool needs_range_check = x->compute_needs_range_check(); |
0 | 267 bool use_length = x->length() != NULL; |
268 bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT; | |
269 bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL || | |
3957 | 270 !get_jobject_constant(x->value())->is_null_object() || |
271 x->should_profile()); | |
0 | 272 |
273 LIRItem array(x->array(), this); | |
274 LIRItem index(x->index(), this); | |
275 LIRItem value(x->value(), this); | |
276 LIRItem length(this); | |
277 | |
278 array.load_item(); | |
279 index.load_nonconstant(); | |
280 | |
8860 | 281 if (use_length && needs_range_check) { |
282 length.set_instruction(x->length()); | |
283 length.load_item(); | |
284 | |
0 | 285 } |
286 if (needs_store_check) { | |
287 value.load_item(); | |
288 } else { | |
289 value.load_for_store(x->elt_type()); | |
290 } | |
291 | |
292 set_no_result(x); | |
293 | |
294 // the CodeEmitInfo must be duplicated for each different | |
295 // LIR-instruction because spilling can occur anywhere between two | |
296 // instructions and so the debug information must be different | |
297 CodeEmitInfo* range_check_info = state_for(x); | |
298 CodeEmitInfo* null_check_info = NULL; | |
299 if (x->needs_null_check()) { | |
300 null_check_info = new CodeEmitInfo(range_check_info); | |
301 } | |
302 | |
303 // emit array address setup early so it schedules better | |
304 LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store); | |
305 | |
306 if (GenerateRangeChecks && needs_range_check) { | |
307 if (use_length) { | |
308 __ cmp(lir_cond_belowEqual, length.result(), index.result()); | |
309 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); | |
310 } else { | |
311 array_range_check(array.result(), index.result(), null_check_info, range_check_info); | |
312 // range_check also does the null check | |
313 null_check_info = NULL; | |
314 } | |
315 } | |
316 | |
317 if (GenerateArrayStoreCheck && needs_store_check) { | |
318 LIR_Opr tmp1 = new_register(objectType); | |
319 LIR_Opr tmp2 = new_register(objectType); | |
320 LIR_Opr tmp3 = new_register(objectType); | |
321 | |
322 CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info); | |
3957 | 323 __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci()); |
0 | 324 } |
325 | |
326 if (obj_store) { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
327 // Needs GC write barriers. |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2169
diff
changeset
|
328 pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2169
diff
changeset
|
329 true /* do_load */, false /* patch */, NULL); |
0 | 330 __ move(value.result(), array_addr, null_check_info); |
331 // Seems to be a precise | |
332 post_barrier(LIR_OprFact::address(array_addr), value.result()); | |
333 } else { | |
334 __ move(value.result(), array_addr, null_check_info); | |
335 } | |
336 } | |
337 | |
338 | |
339 void LIRGenerator::do_MonitorEnter(MonitorEnter* x) { | |
1819 | 340 assert(x->is_pinned(),""); |
0 | 341 LIRItem obj(x->obj(), this); |
342 obj.load_item(); | |
343 | |
344 set_no_result(x); | |
345 | |
346 // "lock" stores the address of the monitor stack slot, so this is not an oop | |
347 LIR_Opr lock = new_register(T_INT); | |
348 // Need a scratch register for biased locking on x86 | |
349 LIR_Opr scratch = LIR_OprFact::illegalOpr; | |
350 if (UseBiasedLocking) { | |
351 scratch = new_register(T_INT); | |
352 } | |
353 | |
354 CodeEmitInfo* info_for_exception = NULL; | |
355 if (x->needs_null_check()) { | |
1819 | 356 info_for_exception = state_for(x); |
0 | 357 } |
358 // this CodeEmitInfo must not have the xhandlers because here the | |
359 // object is already locked (xhandlers expect object to be unlocked) | |
360 CodeEmitInfo* info = state_for(x, x->state(), true); | |
361 monitor_enter(obj.result(), lock, syncTempOpr(), scratch, | |
362 x->monitor_no(), info_for_exception, info); | |
363 } | |
364 | |
365 | |
366 void LIRGenerator::do_MonitorExit(MonitorExit* x) { | |
1819 | 367 assert(x->is_pinned(),""); |
0 | 368 |
369 LIRItem obj(x->obj(), this); | |
370 obj.dont_load_item(); | |
371 | |
372 LIR_Opr lock = new_register(T_INT); | |
373 LIR_Opr obj_temp = new_register(T_INT); | |
374 set_no_result(x); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
375 monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no()); |
0 | 376 } |
377 | |
378 | |
379 // _ineg, _lneg, _fneg, _dneg | |
380 void LIRGenerator::do_NegateOp(NegateOp* x) { | |
381 LIRItem value(x->x(), this); | |
382 value.set_destroys_register(); | |
383 value.load_item(); | |
384 LIR_Opr reg = rlock(x); | |
385 __ negate(value.result(), reg); | |
386 | |
387 set_result(x, round_item(reg)); | |
388 } | |
389 | |
390 | |
391 // for _fadd, _fmul, _fsub, _fdiv, _frem | |
392 // _dadd, _dmul, _dsub, _ddiv, _drem | |
393 void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { | |
394 LIRItem left(x->x(), this); | |
395 LIRItem right(x->y(), this); | |
396 LIRItem* left_arg = &left; | |
397 LIRItem* right_arg = &right; | |
398 assert(!left.is_stack() || !right.is_stack(), "can't both be memory operands"); | |
399 bool must_load_both = (x->op() == Bytecodes::_frem || x->op() == Bytecodes::_drem); | |
400 if (left.is_register() || x->x()->type()->is_constant() || must_load_both) { | |
401 left.load_item(); | |
402 } else { | |
403 left.dont_load_item(); | |
404 } | |
405 | |
406 // do not load right operand if it is a constant. only 0 and 1 are | |
407 // loaded because there are special instructions for loading them | |
408 // without memory access (not needed for SSE2 instructions) | |
409 bool must_load_right = false; | |
410 if (right.is_constant()) { | |
411 LIR_Const* c = right.result()->as_constant_ptr(); | |
412 assert(c != NULL, "invalid constant"); | |
413 assert(c->type() == T_FLOAT || c->type() == T_DOUBLE, "invalid type"); | |
414 | |
415 if (c->type() == T_FLOAT) { | |
416 must_load_right = UseSSE < 1 && (c->is_one_float() || c->is_zero_float()); | |
417 } else { | |
418 must_load_right = UseSSE < 2 && (c->is_one_double() || c->is_zero_double()); | |
419 } | |
420 } | |
421 | |
422 if (must_load_both) { | |
423 // frem and drem destroy also right operand, so move it to a new register | |
424 right.set_destroys_register(); | |
425 right.load_item(); | |
426 } else if (right.is_register() || must_load_right) { | |
427 right.load_item(); | |
428 } else { | |
429 right.dont_load_item(); | |
430 } | |
431 LIR_Opr reg = rlock(x); | |
432 LIR_Opr tmp = LIR_OprFact::illegalOpr; | |
433 if (x->is_strictfp() && (x->op() == Bytecodes::_dmul || x->op() == Bytecodes::_ddiv)) { | |
434 tmp = new_register(T_DOUBLE); | |
435 } | |
436 | |
437 if ((UseSSE >= 1 && x->op() == Bytecodes::_frem) || (UseSSE >= 2 && x->op() == Bytecodes::_drem)) { | |
438 // special handling for frem and drem: no SSE instruction, so must use FPU with temporary fpu stack slots | |
439 LIR_Opr fpu0, fpu1; | |
440 if (x->op() == Bytecodes::_frem) { | |
441 fpu0 = LIR_OprFact::single_fpu(0); | |
442 fpu1 = LIR_OprFact::single_fpu(1); | |
443 } else { | |
444 fpu0 = LIR_OprFact::double_fpu(0); | |
445 fpu1 = LIR_OprFact::double_fpu(1); | |
446 } | |
447 __ move(right.result(), fpu1); // order of left and right operand is important! | |
448 __ move(left.result(), fpu0); | |
449 __ rem (fpu0, fpu1, fpu0); | |
450 __ move(fpu0, reg); | |
451 | |
452 } else { | |
453 arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp(), tmp); | |
454 } | |
455 | |
456 set_result(x, round_item(reg)); | |
457 } | |
458 | |
459 | |
460 // for _ladd, _lmul, _lsub, _ldiv, _lrem | |
461 void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { | |
462 if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem ) { | |
463 // long division is implemented as a direct call into the runtime | |
464 LIRItem left(x->x(), this); | |
465 LIRItem right(x->y(), this); | |
466 | |
467 // the check for division by zero destroys the right operand | |
468 right.set_destroys_register(); | |
469 | |
470 BasicTypeList signature(2); | |
471 signature.append(T_LONG); | |
472 signature.append(T_LONG); | |
473 CallingConvention* cc = frame_map()->c_calling_convention(&signature); | |
474 | |
475 // check for division by zero (destroys registers of right operand!) | |
476 CodeEmitInfo* info = state_for(x); | |
477 | |
478 const LIR_Opr result_reg = result_register_for(x->type()); | |
479 left.load_item_force(cc->at(1)); | |
480 right.load_item(); | |
481 | |
482 __ move(right.result(), cc->at(0)); | |
483 | |
484 __ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0)); | |
485 __ branch(lir_cond_equal, T_LONG, new DivByZeroStub(info)); | |
486 | |
487 address entry; | |
488 switch (x->op()) { | |
489 case Bytecodes::_lrem: | |
490 entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem); | |
491 break; // check if dividend is 0 is done elsewhere | |
492 case Bytecodes::_ldiv: | |
493 entry = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv); | |
494 break; // check if dividend is 0 is done elsewhere | |
495 case Bytecodes::_lmul: | |
496 entry = CAST_FROM_FN_PTR(address, SharedRuntime::lmul); | |
497 break; | |
498 default: | |
499 ShouldNotReachHere(); | |
500 } | |
501 | |
502 LIR_Opr result = rlock_result(x); | |
503 __ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args()); | |
504 __ move(result_reg, result); | |
505 } else if (x->op() == Bytecodes::_lmul) { | |
506 // missing test if instr is commutative and if we should swap | |
507 LIRItem left(x->x(), this); | |
508 LIRItem right(x->y(), this); | |
509 | |
510 // right register is destroyed by the long mul, so it must be | |
511 // copied to a new register. | |
512 right.set_destroys_register(); | |
513 | |
514 left.load_item(); | |
515 right.load_item(); | |
516 | |
304 | 517 LIR_Opr reg = FrameMap::long0_opr; |
0 | 518 arithmetic_op_long(x->op(), reg, left.result(), right.result(), NULL); |
519 LIR_Opr result = rlock_result(x); | |
520 __ move(reg, result); | |
521 } else { | |
522 // missing test if instr is commutative and if we should swap | |
523 LIRItem left(x->x(), this); | |
524 LIRItem right(x->y(), this); | |
525 | |
526 left.load_item(); | |
605 | 527 // don't load constants to save register |
0 | 528 right.load_nonconstant(); |
529 rlock_result(x); | |
530 arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL); | |
531 } | |
532 } | |
533 | |
534 | |
535 | |
536 // for: _iadd, _imul, _isub, _idiv, _irem | |
537 void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) { | |
538 if (x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem) { | |
539 // The requirements for division and modulo | |
540 // input : rax,: dividend min_int | |
541 // reg: divisor (may not be rax,/rdx) -1 | |
542 // | |
543 // output: rax,: quotient (= rax, idiv reg) min_int | |
544 // rdx: remainder (= rax, irem reg) 0 | |
545 | |
546 // rax, and rdx will be destroyed | |
547 | |
548 // Note: does this invalidate the spec ??? | |
549 LIRItem right(x->y(), this); | |
550 LIRItem left(x->x() , this); // visit left second, so that the is_register test is valid | |
551 | |
552 // call state_for before load_item_force because state_for may | |
553 // force the evaluation of other instructions that are needed for | |
554 // correct debug info. Otherwise the live range of the fix | |
555 // register might be too long. | |
556 CodeEmitInfo* info = state_for(x); | |
557 | |
558 left.load_item_force(divInOpr()); | |
559 | |
560 right.load_item(); | |
561 | |
562 LIR_Opr result = rlock_result(x); | |
563 LIR_Opr result_reg; | |
564 if (x->op() == Bytecodes::_idiv) { | |
565 result_reg = divOutOpr(); | |
566 } else { | |
567 result_reg = remOutOpr(); | |
568 } | |
569 | |
570 if (!ImplicitDiv0Checks) { | |
571 __ cmp(lir_cond_equal, right.result(), LIR_OprFact::intConst(0)); | |
572 __ branch(lir_cond_equal, T_INT, new DivByZeroStub(info)); | |
573 } | |
574 LIR_Opr tmp = FrameMap::rdx_opr; // idiv and irem use rdx in their implementation | |
575 if (x->op() == Bytecodes::_irem) { | |
576 __ irem(left.result(), right.result(), result_reg, tmp, info); | |
577 } else if (x->op() == Bytecodes::_idiv) { | |
578 __ idiv(left.result(), right.result(), result_reg, tmp, info); | |
579 } else { | |
580 ShouldNotReachHere(); | |
581 } | |
582 | |
583 __ move(result_reg, result); | |
584 } else { | |
585 // missing test if instr is commutative and if we should swap | |
586 LIRItem left(x->x(), this); | |
587 LIRItem right(x->y(), this); | |
588 LIRItem* left_arg = &left; | |
589 LIRItem* right_arg = &right; | |
590 if (x->is_commutative() && left.is_stack() && right.is_register()) { | |
591 // swap them if left is real stack (or cached) and right is real register(not cached) | |
592 left_arg = &right; | |
593 right_arg = &left; | |
594 } | |
595 | |
596 left_arg->load_item(); | |
597 | |
598 // do not need to load right, as we can handle stack and constants | |
599 if (x->op() == Bytecodes::_imul ) { | |
600 // check if we can use shift instead | |
601 bool use_constant = false; | |
602 bool use_tmp = false; | |
603 if (right_arg->is_constant()) { | |
604 int iconst = right_arg->get_jint_constant(); | |
605 if (iconst > 0) { | |
606 if (is_power_of_2(iconst)) { | |
607 use_constant = true; | |
608 } else if (is_power_of_2(iconst - 1) || is_power_of_2(iconst + 1)) { | |
609 use_constant = true; | |
610 use_tmp = true; | |
611 } | |
612 } | |
613 } | |
614 if (use_constant) { | |
615 right_arg->dont_load_item(); | |
616 } else { | |
617 right_arg->load_item(); | |
618 } | |
619 LIR_Opr tmp = LIR_OprFact::illegalOpr; | |
620 if (use_tmp) { | |
621 tmp = new_register(T_INT); | |
622 } | |
623 rlock_result(x); | |
624 | |
625 arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), tmp); | |
626 } else { | |
627 right_arg->dont_load_item(); | |
628 rlock_result(x); | |
629 LIR_Opr tmp = LIR_OprFact::illegalOpr; | |
630 arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), tmp); | |
631 } | |
632 } | |
633 } | |
634 | |
635 | |
636 void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) { | |
637 // when an operand with use count 1 is the left operand, then it is | |
638 // likely that no move for 2-operand-LIR-form is necessary | |
639 if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) { | |
640 x->swap_operands(); | |
641 } | |
642 | |
643 ValueTag tag = x->type()->tag(); | |
644 assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters"); | |
645 switch (tag) { | |
646 case floatTag: | |
647 case doubleTag: do_ArithmeticOp_FPU(x); return; | |
648 case longTag: do_ArithmeticOp_Long(x); return; | |
649 case intTag: do_ArithmeticOp_Int(x); return; | |
650 } | |
651 ShouldNotReachHere(); | |
652 } | |
653 | |
654 | |
655 // _ishl, _lshl, _ishr, _lshr, _iushr, _lushr | |
656 void LIRGenerator::do_ShiftOp(ShiftOp* x) { | |
657 // count must always be in rcx | |
658 LIRItem value(x->x(), this); | |
659 LIRItem count(x->y(), this); | |
660 | |
661 ValueTag elemType = x->type()->tag(); | |
662 bool must_load_count = !count.is_constant() || elemType == longTag; | |
663 if (must_load_count) { | |
664 // count for long must be in register | |
665 count.load_item_force(shiftCountOpr()); | |
666 } else { | |
667 count.dont_load_item(); | |
668 } | |
669 value.load_item(); | |
670 LIR_Opr reg = rlock_result(x); | |
671 | |
672 shift_op(x->op(), reg, value.result(), count.result(), LIR_OprFact::illegalOpr); | |
673 } | |
674 | |
675 | |
676 // _iand, _land, _ior, _lor, _ixor, _lxor | |
677 void LIRGenerator::do_LogicOp(LogicOp* x) { | |
678 // when an operand with use count 1 is the left operand, then it is | |
679 // likely that no move for 2-operand-LIR-form is necessary | |
680 if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) { | |
681 x->swap_operands(); | |
682 } | |
683 | |
684 LIRItem left(x->x(), this); | |
685 LIRItem right(x->y(), this); | |
686 | |
687 left.load_item(); | |
688 right.load_nonconstant(); | |
689 LIR_Opr reg = rlock_result(x); | |
690 | |
691 logic_op(x->op(), reg, left.result(), right.result()); | |
692 } | |
693 | |
694 | |
695 | |
696 // _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg | |
697 void LIRGenerator::do_CompareOp(CompareOp* x) { | |
698 LIRItem left(x->x(), this); | |
699 LIRItem right(x->y(), this); | |
700 ValueTag tag = x->x()->type()->tag(); | |
701 if (tag == longTag) { | |
702 left.set_destroys_register(); | |
703 } | |
704 left.load_item(); | |
705 right.load_item(); | |
706 LIR_Opr reg = rlock_result(x); | |
707 | |
708 if (x->x()->type()->is_float_kind()) { | |
709 Bytecodes::Code code = x->op(); | |
710 __ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl)); | |
711 } else if (x->x()->type()->tag() == longTag) { | |
712 __ lcmp2int(left.result(), right.result(), reg); | |
713 } else { | |
714 Unimplemented(); | |
715 } | |
716 } | |
717 | |
718 | |
719 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { | |
720 assert(x->number_of_arguments() == 4, "wrong type"); | |
721 LIRItem obj (x->argument_at(0), this); // object | |
722 LIRItem offset(x->argument_at(1), this); // offset of field | |
723 LIRItem cmp (x->argument_at(2), this); // value to compare with field | |
724 LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp | |
725 | |
726 assert(obj.type()->tag() == objectTag, "invalid type"); | |
304 | 727 |
728 // In 64bit the type can be long, sparc doesn't have this assert | |
729 // assert(offset.type()->tag() == intTag, "invalid type"); | |
730 | |
0 | 731 assert(cmp.type()->tag() == type->tag(), "invalid type"); |
732 assert(val.type()->tag() == type->tag(), "invalid type"); | |
733 | |
734 // get address of field | |
735 obj.load_item(); | |
736 offset.load_nonconstant(); | |
737 | |
738 if (type == objectType) { | |
739 cmp.load_item_force(FrameMap::rax_oop_opr); | |
740 val.load_item(); | |
741 } else if (type == intType) { | |
742 cmp.load_item_force(FrameMap::rax_opr); | |
743 val.load_item(); | |
744 } else if (type == longType) { | |
304 | 745 cmp.load_item_force(FrameMap::long0_opr); |
746 val.load_item_force(FrameMap::long1_opr); | |
0 | 747 } else { |
748 ShouldNotReachHere(); | |
749 } | |
750 | |
1873 | 751 LIR_Opr addr = new_pointer_register(); |
1060 | 752 LIR_Address* a; |
753 if(offset.result()->is_constant()) { | |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
754 #ifdef _LP64 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
755 jlong c = offset.result()->as_jlong(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
756 if ((jlong)((jint)c) == c) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
757 a = new LIR_Address(obj.result(), |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
758 (jint)c, |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
759 as_BasicType(type)); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
760 } else { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
761 LIR_Opr tmp = new_register(T_LONG); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
762 __ move(offset.result(), tmp); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
763 a = new LIR_Address(obj.result(), |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
764 tmp, |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
765 as_BasicType(type)); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
766 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
767 #else |
1060 | 768 a = new LIR_Address(obj.result(), |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
769 offset.result()->as_jint(), |
1060 | 770 as_BasicType(type)); |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
771 #endif |
1060 | 772 } else { |
773 a = new LIR_Address(obj.result(), | |
774 offset.result(), | |
775 LIR_Address::times_1, | |
776 0, | |
777 as_BasicType(type)); | |
778 } | |
779 __ leal(LIR_OprFact::address(a), addr); | |
0 | 780 |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
781 if (type == objectType) { // Write-barrier needed for Object fields. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
782 // Do the pre-write barrier, if any. |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2169
diff
changeset
|
783 pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2169
diff
changeset
|
784 true /* do_load */, false /* patch */, NULL); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
785 } |
0 | 786 |
787 LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience | |
788 if (type == objectType) | |
789 __ cas_obj(addr, cmp.result(), val.result(), ill, ill); | |
790 else if (type == intType) | |
791 __ cas_int(addr, cmp.result(), val.result(), ill, ill); | |
792 else if (type == longType) | |
793 __ cas_long(addr, cmp.result(), val.result(), ill, ill); | |
794 else { | |
795 ShouldNotReachHere(); | |
796 } | |
797 | |
798 // generate conditional move of boolean result | |
799 LIR_Opr result = rlock_result(x); | |
2089
037c727f35fb
7009231: C1: Incorrect CAS code for longs on SPARC 32bit
iveresov
parents:
2005
diff
changeset
|
800 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), |
037c727f35fb
7009231: C1: Incorrect CAS code for longs on SPARC 32bit
iveresov
parents:
2005
diff
changeset
|
801 result, as_BasicType(type)); |
0 | 802 if (type == objectType) { // Write-barrier needed for Object fields. |
803 // Seems to be precise | |
804 post_barrier(addr, val.result()); | |
805 } | |
806 } | |
807 | |
808 | |
809 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
810 assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type"); |
0 | 811 LIRItem value(x->argument_at(0), this); |
812 | |
813 bool use_fpu = false; | |
814 if (UseSSE >= 2) { | |
815 switch(x->id()) { | |
816 case vmIntrinsics::_dsin: | |
817 case vmIntrinsics::_dcos: | |
818 case vmIntrinsics::_dtan: | |
819 case vmIntrinsics::_dlog: | |
820 case vmIntrinsics::_dlog10: | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
821 case vmIntrinsics::_dexp: |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
822 case vmIntrinsics::_dpow: |
0 | 823 use_fpu = true; |
824 } | |
825 } else { | |
826 value.set_destroys_register(); | |
827 } | |
828 | |
829 value.load_item(); | |
830 | |
831 LIR_Opr calc_input = value.result(); | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
832 LIR_Opr calc_input2 = NULL; |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
833 if (x->id() == vmIntrinsics::_dpow) { |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
834 LIRItem extra_arg(x->argument_at(1), this); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
835 if (UseSSE < 2) { |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
836 extra_arg.set_destroys_register(); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
837 } |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
838 extra_arg.load_item(); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
839 calc_input2 = extra_arg.result(); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
840 } |
0 | 841 LIR_Opr calc_result = rlock_result(x); |
842 | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
843 // sin, cos, pow and exp need two free fpu stack slots, so register |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
844 // two temporary operands |
0 | 845 LIR_Opr tmp1 = FrameMap::caller_save_fpu_reg_at(0); |
846 LIR_Opr tmp2 = FrameMap::caller_save_fpu_reg_at(1); | |
847 | |
848 if (use_fpu) { | |
849 LIR_Opr tmp = FrameMap::fpu0_double_opr; | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
850 int tmp_start = 1; |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
851 if (calc_input2 != NULL) { |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
852 __ move(calc_input2, tmp); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
853 tmp_start = 2; |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
854 calc_input2 = tmp; |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
855 } |
0 | 856 __ move(calc_input, tmp); |
857 | |
858 calc_input = tmp; | |
859 calc_result = tmp; | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
860 |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
861 tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
862 tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1); |
0 | 863 } |
864 | |
865 switch(x->id()) { | |
866 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; | |
867 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break; | |
868 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break; | |
869 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break; | |
870 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break; | |
953
ff1a29907b6c
6855215: Calculation error (NaN) after about 1500 calculations
never
parents:
933
diff
changeset
|
871 case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break; |
ff1a29907b6c
6855215: Calculation error (NaN) after about 1500 calculations
never
parents:
933
diff
changeset
|
872 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
873 case vmIntrinsics::_dexp: __ exp (calc_input, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
874 case vmIntrinsics::_dpow: __ pow (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; |
0 | 875 default: ShouldNotReachHere(); |
876 } | |
877 | |
878 if (use_fpu) { | |
879 __ move(calc_result, x->operand()); | |
880 } | |
881 } | |
882 | |
883 | |
884 void LIRGenerator::do_ArrayCopy(Intrinsic* x) { | |
885 assert(x->number_of_arguments() == 5, "wrong type"); | |
2005
0cb042fd2d4b
6875026: CTW failure jdk6_18/hotspot/src/share/vm/c1/c1_LinearScan.cpp:5486
never
parents:
2002
diff
changeset
|
886 |
0cb042fd2d4b
6875026: CTW failure jdk6_18/hotspot/src/share/vm/c1/c1_LinearScan.cpp:5486
never
parents:
2002
diff
changeset
|
887 // Make all state_for calls early since they can emit code |
0cb042fd2d4b
6875026: CTW failure jdk6_18/hotspot/src/share/vm/c1/c1_LinearScan.cpp:5486
never
parents:
2002
diff
changeset
|
888 CodeEmitInfo* info = state_for(x, x->state()); |
0cb042fd2d4b
6875026: CTW failure jdk6_18/hotspot/src/share/vm/c1/c1_LinearScan.cpp:5486
never
parents:
2002
diff
changeset
|
889 |
0 | 890 LIRItem src(x->argument_at(0), this); |
891 LIRItem src_pos(x->argument_at(1), this); | |
892 LIRItem dst(x->argument_at(2), this); | |
893 LIRItem dst_pos(x->argument_at(3), this); | |
894 LIRItem length(x->argument_at(4), this); | |
895 | |
896 // operands for arraycopy must use fixed registers, otherwise | |
897 // LinearScan will fail allocation (because arraycopy always needs a | |
898 // call) | |
304 | 899 |
900 #ifndef _LP64 | |
0 | 901 src.load_item_force (FrameMap::rcx_oop_opr); |
902 src_pos.load_item_force (FrameMap::rdx_opr); | |
903 dst.load_item_force (FrameMap::rax_oop_opr); | |
904 dst_pos.load_item_force (FrameMap::rbx_opr); | |
905 length.load_item_force (FrameMap::rdi_opr); | |
906 LIR_Opr tmp = (FrameMap::rsi_opr); | |
304 | 907 #else |
908 | |
909 // The java calling convention will give us enough registers | |
910 // so that on the stub side the args will be perfect already. | |
911 // On the other slow/special case side we call C and the arg | |
912 // positions are not similar enough to pick one as the best. | |
913 // Also because the java calling convention is a "shifted" version | |
914 // of the C convention we can process the java args trivially into C | |
915 // args without worry of overwriting during the xfer | |
916 | |
917 src.load_item_force (FrameMap::as_oop_opr(j_rarg0)); | |
918 src_pos.load_item_force (FrameMap::as_opr(j_rarg1)); | |
919 dst.load_item_force (FrameMap::as_oop_opr(j_rarg2)); | |
920 dst_pos.load_item_force (FrameMap::as_opr(j_rarg3)); | |
921 length.load_item_force (FrameMap::as_opr(j_rarg4)); | |
922 | |
923 LIR_Opr tmp = FrameMap::as_opr(j_rarg5); | |
924 #endif // LP64 | |
925 | |
0 | 926 set_no_result(x); |
927 | |
928 int flags; | |
929 ciArrayKlass* expected_type; | |
930 arraycopy_helper(x, &flags, &expected_type); | |
931 | |
932 __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint | |
933 } | |
934 | |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
935 void LIRGenerator::do_update_CRC32(Intrinsic* x) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
936 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
937 // Make all state_for calls early since they can emit code |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
938 LIR_Opr result = rlock_result(x); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
939 int flags = 0; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
940 switch (x->id()) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
941 case vmIntrinsics::_updateCRC32: { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
942 LIRItem crc(x->argument_at(0), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
943 LIRItem val(x->argument_at(1), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
944 crc.load_item(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
945 val.load_item(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
946 __ update_crc32(crc.result(), val.result(), result); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
947 break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
948 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
949 case vmIntrinsics::_updateBytesCRC32: |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
950 case vmIntrinsics::_updateByteBufferCRC32: { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
951 bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
952 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
953 LIRItem crc(x->argument_at(0), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
954 LIRItem buf(x->argument_at(1), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
955 LIRItem off(x->argument_at(2), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
956 LIRItem len(x->argument_at(3), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
957 buf.load_item(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
958 off.load_nonconstant(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
959 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
960 LIR_Opr index = off.result(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
961 int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
962 if(off.result()->is_constant()) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
963 index = LIR_OprFact::illegalOpr; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
964 offset += off.result()->as_jint(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
965 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
966 LIR_Opr base_op = buf.result(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
967 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
968 #ifndef _LP64 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
969 if (!is_updateBytes) { // long b raw address |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
970 base_op = new_register(T_INT); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
971 __ convert(Bytecodes::_l2i, buf.result(), base_op); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
972 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
973 #else |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
974 if (index->is_valid()) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
975 LIR_Opr tmp = new_register(T_LONG); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
976 __ convert(Bytecodes::_i2l, index, tmp); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
977 index = tmp; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
978 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
979 #endif |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
980 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
981 LIR_Address* a = new LIR_Address(base_op, |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
982 index, |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
983 LIR_Address::times_1, |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
984 offset, |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
985 T_BYTE); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
986 BasicTypeList signature(3); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
987 signature.append(T_INT); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
988 signature.append(T_ADDRESS); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
989 signature.append(T_INT); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
990 CallingConvention* cc = frame_map()->c_calling_convention(&signature); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
991 const LIR_Opr result_reg = result_register_for(x->type()); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
992 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
993 LIR_Opr addr = new_pointer_register(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
994 __ leal(LIR_OprFact::address(a), addr); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
995 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
996 crc.load_item_force(cc->at(0)); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
997 __ move(addr, cc->at(1)); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
998 len.load_item_force(cc->at(2)); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
999 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1000 __ call_runtime_leaf(StubRoutines::updateBytesCRC32(), getThreadTemp(), result_reg, cc->args()); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1001 __ move(result_reg, result); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1002 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1003 break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1004 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1005 default: { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1006 ShouldNotReachHere(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1007 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1008 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1009 } |
0 | 1010 |
1011 // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f | |
1012 // _i2b, _i2c, _i2s | |
1013 LIR_Opr fixed_register_for(BasicType type) { | |
1014 switch (type) { | |
1015 case T_FLOAT: return FrameMap::fpu0_float_opr; | |
1016 case T_DOUBLE: return FrameMap::fpu0_double_opr; | |
1017 case T_INT: return FrameMap::rax_opr; | |
304 | 1018 case T_LONG: return FrameMap::long0_opr; |
0 | 1019 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; |
1020 } | |
1021 } | |
1022 | |
1023 void LIRGenerator::do_Convert(Convert* x) { | |
1024 // flags that vary for the different operations and different SSE-settings | |
1025 bool fixed_input, fixed_result, round_result, needs_stub; | |
1026 | |
1027 switch (x->op()) { | |
1028 case Bytecodes::_i2l: // fall through | |
1029 case Bytecodes::_l2i: // fall through | |
1030 case Bytecodes::_i2b: // fall through | |
1031 case Bytecodes::_i2c: // fall through | |
1032 case Bytecodes::_i2s: fixed_input = false; fixed_result = false; round_result = false; needs_stub = false; break; | |
1033 | |
1034 case Bytecodes::_f2d: fixed_input = UseSSE == 1; fixed_result = false; round_result = false; needs_stub = false; break; | |
1035 case Bytecodes::_d2f: fixed_input = false; fixed_result = UseSSE == 1; round_result = UseSSE < 1; needs_stub = false; break; | |
1036 case Bytecodes::_i2f: fixed_input = false; fixed_result = false; round_result = UseSSE < 1; needs_stub = false; break; | |
1037 case Bytecodes::_i2d: fixed_input = false; fixed_result = false; round_result = false; needs_stub = false; break; | |
1038 case Bytecodes::_f2i: fixed_input = false; fixed_result = false; round_result = false; needs_stub = true; break; | |
1039 case Bytecodes::_d2i: fixed_input = false; fixed_result = false; round_result = false; needs_stub = true; break; | |
1040 case Bytecodes::_l2f: fixed_input = false; fixed_result = UseSSE >= 1; round_result = UseSSE < 1; needs_stub = false; break; | |
1041 case Bytecodes::_l2d: fixed_input = false; fixed_result = UseSSE >= 2; round_result = UseSSE < 2; needs_stub = false; break; | |
1042 case Bytecodes::_f2l: fixed_input = true; fixed_result = true; round_result = false; needs_stub = false; break; | |
1043 case Bytecodes::_d2l: fixed_input = true; fixed_result = true; round_result = false; needs_stub = false; break; | |
1044 default: ShouldNotReachHere(); | |
1045 } | |
1046 | |
1047 LIRItem value(x->value(), this); | |
1048 value.load_item(); | |
1049 LIR_Opr input = value.result(); | |
1050 LIR_Opr result = rlock(x); | |
1051 | |
1052 // arguments of lir_convert | |
1053 LIR_Opr conv_input = input; | |
1054 LIR_Opr conv_result = result; | |
1055 ConversionStub* stub = NULL; | |
1056 | |
1057 if (fixed_input) { | |
1058 conv_input = fixed_register_for(input->type()); | |
1059 __ move(input, conv_input); | |
1060 } | |
1061 | |
1062 assert(fixed_result == false || round_result == false, "cannot set both"); | |
1063 if (fixed_result) { | |
1064 conv_result = fixed_register_for(result->type()); | |
1065 } else if (round_result) { | |
1066 result = new_register(result->type()); | |
1067 set_vreg_flag(result, must_start_in_memory); | |
1068 } | |
1069 | |
1070 if (needs_stub) { | |
1071 stub = new ConversionStub(x->op(), conv_input, conv_result); | |
1072 } | |
1073 | |
1074 __ convert(x->op(), conv_input, conv_result, stub); | |
1075 | |
1076 if (result != conv_result) { | |
1077 __ move(conv_result, result); | |
1078 } | |
1079 | |
1080 assert(result->is_virtual(), "result must be virtual register"); | |
1081 set_result(x, result); | |
1082 } | |
1083 | |
1084 | |
1085 void LIRGenerator::do_NewInstance(NewInstance* x) { | |
1819 | 1086 #ifndef PRODUCT |
0 | 1087 if (PrintNotLoaded && !x->klass()->is_loaded()) { |
1819 | 1088 tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci()); |
0 | 1089 } |
1819 | 1090 #endif |
0 | 1091 CodeEmitInfo* info = state_for(x, x->state()); |
1092 LIR_Opr reg = result_register_for(x->type()); | |
1093 new_instance(reg, x->klass(), | |
1094 FrameMap::rcx_oop_opr, | |
1095 FrameMap::rdi_oop_opr, | |
1096 FrameMap::rsi_oop_opr, | |
1097 LIR_OprFact::illegalOpr, | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1098 FrameMap::rdx_metadata_opr, info); |
0 | 1099 LIR_Opr result = rlock_result(x); |
1100 __ move(reg, result); | |
1101 } | |
1102 | |
1103 | |
1104 void LIRGenerator::do_NewTypeArray(NewTypeArray* x) { | |
1105 CodeEmitInfo* info = state_for(x, x->state()); | |
1106 | |
1107 LIRItem length(x->length(), this); | |
1108 length.load_item_force(FrameMap::rbx_opr); | |
1109 | |
1110 LIR_Opr reg = result_register_for(x->type()); | |
1111 LIR_Opr tmp1 = FrameMap::rcx_oop_opr; | |
1112 LIR_Opr tmp2 = FrameMap::rsi_oop_opr; | |
1113 LIR_Opr tmp3 = FrameMap::rdi_oop_opr; | |
1114 LIR_Opr tmp4 = reg; | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1115 LIR_Opr klass_reg = FrameMap::rdx_metadata_opr; |
0 | 1116 LIR_Opr len = length.result(); |
1117 BasicType elem_type = x->elt_type(); | |
1118 | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1119 __ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg); |
0 | 1120 |
1121 CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info); | |
1122 __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path); | |
1123 | |
1124 LIR_Opr result = rlock_result(x); | |
1125 __ move(reg, result); | |
1126 } | |
1127 | |
1128 | |
1129 void LIRGenerator::do_NewObjectArray(NewObjectArray* x) { | |
1130 LIRItem length(x->length(), this); | |
1131 // in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction | |
1132 // and therefore provide the state before the parameters have been consumed | |
1133 CodeEmitInfo* patching_info = NULL; | |
1134 if (!x->klass()->is_loaded() || PatchALot) { | |
1135 patching_info = state_for(x, x->state_before()); | |
1136 } | |
1137 | |
1138 CodeEmitInfo* info = state_for(x, x->state()); | |
1139 | |
1140 const LIR_Opr reg = result_register_for(x->type()); | |
1141 LIR_Opr tmp1 = FrameMap::rcx_oop_opr; | |
1142 LIR_Opr tmp2 = FrameMap::rsi_oop_opr; | |
1143 LIR_Opr tmp3 = FrameMap::rdi_oop_opr; | |
1144 LIR_Opr tmp4 = reg; | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1145 LIR_Opr klass_reg = FrameMap::rdx_metadata_opr; |
0 | 1146 |
1147 length.load_item_force(FrameMap::rbx_opr); | |
1148 LIR_Opr len = length.result(); | |
1149 | |
1150 CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6145
diff
changeset
|
1151 ciKlass* obj = (ciKlass*) ciObjArrayKlass::make(x->klass()); |
0 | 1152 if (obj == ciEnv::unloaded_ciobjarrayklass()) { |
1153 BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error"); | |
1154 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6145
diff
changeset
|
1155 klass2reg_with_patching(klass_reg, obj, patching_info); |
0 | 1156 __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path); |
1157 | |
1158 LIR_Opr result = rlock_result(x); | |
1159 __ move(reg, result); | |
1160 } | |
1161 | |
1162 | |
1163 void LIRGenerator::do_NewMultiArray(NewMultiArray* x) { | |
1164 Values* dims = x->dims(); | |
1165 int i = dims->length(); | |
1166 LIRItemList* items = new LIRItemList(dims->length(), NULL); | |
1167 while (i-- > 0) { | |
1168 LIRItem* size = new LIRItem(dims->at(i), this); | |
1169 items->at_put(i, size); | |
1170 } | |
1171 | |
933
cdb8b7c37ac1
6875329: fix for 6795465 broke exception handler cloning
never
parents:
605
diff
changeset
|
1172 // Evaluate state_for early since it may emit code. |
0 | 1173 CodeEmitInfo* patching_info = NULL; |
1174 if (!x->klass()->is_loaded() || PatchALot) { | |
1175 patching_info = state_for(x, x->state_before()); | |
1176 | |
6145
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
6143
diff
changeset
|
1177 // Cannot re-use same xhandlers for multiple CodeEmitInfos, so |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
6143
diff
changeset
|
1178 // clone all handlers (NOTE: Usually this is handled transparently |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
6143
diff
changeset
|
1179 // by the CodeEmitInfo cloning logic in CodeStub constructors but |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
6143
diff
changeset
|
1180 // is done explicitly here because a stub isn't being used). |
0 | 1181 x->set_exception_handlers(new XHandlers(x->exception_handlers())); |
1182 } | |
1183 CodeEmitInfo* info = state_for(x, x->state()); | |
1184 | |
1185 i = dims->length(); | |
1186 while (i-- > 0) { | |
1187 LIRItem* size = items->at(i); | |
1188 size->load_nonconstant(); | |
1189 | |
1190 store_stack_parameter(size->result(), in_ByteSize(i*4)); | |
1191 } | |
1192 | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1193 LIR_Opr klass_reg = FrameMap::rax_metadata_opr; |
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1194 klass2reg_with_patching(klass_reg, x->klass(), patching_info); |
0 | 1195 |
1196 LIR_Opr rank = FrameMap::rbx_opr; | |
1197 __ move(LIR_OprFact::intConst(x->rank()), rank); | |
1198 LIR_Opr varargs = FrameMap::rcx_opr; | |
1199 __ move(FrameMap::rsp_opr, varargs); | |
1200 LIR_OprList* args = new LIR_OprList(3); | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1201 args->append(klass_reg); |
0 | 1202 args->append(rank); |
1203 args->append(varargs); | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1204 LIR_Opr reg = result_register_for(x->type()); |
0 | 1205 __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id), |
1206 LIR_OprFact::illegalOpr, | |
1207 reg, args, info); | |
1208 | |
1209 LIR_Opr result = rlock_result(x); | |
1210 __ move(reg, result); | |
1211 } | |
1212 | |
1213 | |
1214 void LIRGenerator::do_BlockBegin(BlockBegin* x) { | |
1215 // nothing to do for now | |
1216 } | |
1217 | |
1218 | |
1219 void LIRGenerator::do_CheckCast(CheckCast* x) { | |
1220 LIRItem obj(x->obj(), this); | |
1221 | |
1222 CodeEmitInfo* patching_info = NULL; | |
1223 if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check())) { | |
1224 // must do this before locking the destination register as an oop register, | |
1225 // and before the obj is loaded (the latter is for deoptimization) | |
1226 patching_info = state_for(x, x->state_before()); | |
1227 } | |
1228 obj.load_item(); | |
1229 | |
1230 // info for exceptions | |
1819 | 1231 CodeEmitInfo* info_for_exception = state_for(x); |
0 | 1232 |
1233 CodeStub* stub; | |
1234 if (x->is_incompatible_class_change_check()) { | |
1235 assert(patching_info == NULL, "can't patch this"); | |
1236 stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception); | |
1237 } else { | |
1238 stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); | |
1239 } | |
1240 LIR_Opr reg = rlock_result(x); | |
2002 | 1241 LIR_Opr tmp3 = LIR_OprFact::illegalOpr; |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
11080
diff
changeset
|
1242 if (!x->klass()->is_loaded() || UseCompressedClassPointers) { |
2002 | 1243 tmp3 = new_register(objectType); |
1244 } | |
0 | 1245 __ checkcast(reg, obj.result(), x->klass(), |
2002 | 1246 new_register(objectType), new_register(objectType), tmp3, |
0 | 1247 x->direct_compare(), info_for_exception, patching_info, stub, |
1248 x->profiled_method(), x->profiled_bci()); | |
1249 } | |
1250 | |
1251 | |
1252 void LIRGenerator::do_InstanceOf(InstanceOf* x) { | |
1253 LIRItem obj(x->obj(), this); | |
1254 | |
1255 // result and test object may not be in same register | |
1256 LIR_Opr reg = rlock_result(x); | |
1257 CodeEmitInfo* patching_info = NULL; | |
1258 if ((!x->klass()->is_loaded() || PatchALot)) { | |
1259 // must do this before locking the destination register as an oop register | |
1260 patching_info = state_for(x, x->state_before()); | |
1261 } | |
1262 obj.load_item(); | |
2002 | 1263 LIR_Opr tmp3 = LIR_OprFact::illegalOpr; |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
11080
diff
changeset
|
1264 if (!x->klass()->is_loaded() || UseCompressedClassPointers) { |
2002 | 1265 tmp3 = new_register(objectType); |
1266 } | |
0 | 1267 __ instanceof(reg, obj.result(), x->klass(), |
2002 | 1268 new_register(objectType), new_register(objectType), tmp3, |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1269 x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); |
0 | 1270 } |
1271 | |
1272 | |
1273 void LIRGenerator::do_If(If* x) { | |
1274 assert(x->number_of_sux() == 2, "inconsistency"); | |
1275 ValueTag tag = x->x()->type()->tag(); | |
1276 bool is_safepoint = x->is_safepoint(); | |
1277 | |
1278 If::Condition cond = x->cond(); | |
1279 | |
1280 LIRItem xitem(x->x(), this); | |
1281 LIRItem yitem(x->y(), this); | |
1282 LIRItem* xin = &xitem; | |
1283 LIRItem* yin = &yitem; | |
1284 | |
1285 if (tag == longTag) { | |
1286 // for longs, only conditions "eql", "neq", "lss", "geq" are valid; | |
1287 // mirror for other conditions | |
1288 if (cond == If::gtr || cond == If::leq) { | |
1289 cond = Instruction::mirror(cond); | |
1290 xin = &yitem; | |
1291 yin = &xitem; | |
1292 } | |
1293 xin->set_destroys_register(); | |
1294 } | |
1295 xin->load_item(); | |
1296 if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) { | |
1297 // inline long zero | |
1298 yin->dont_load_item(); | |
1299 } else if (tag == longTag || tag == floatTag || tag == doubleTag) { | |
1300 // longs cannot handle constants at right side | |
1301 yin->load_item(); | |
1302 } else { | |
1303 yin->dont_load_item(); | |
1304 } | |
1305 | |
1306 // add safepoint before generating condition code so it can be recomputed | |
1307 if (x->is_safepoint()) { | |
1308 // increment backedge counter if needed | |
1783 | 1309 increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci()); |
0 | 1310 __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before())); |
1311 } | |
1312 set_no_result(x); | |
1313 | |
1314 LIR_Opr left = xin->result(); | |
1315 LIR_Opr right = yin->result(); | |
1316 __ cmp(lir_cond(cond), left, right); | |
1783 | 1317 // Generate branch profiling. Profiling code doesn't kill flags. |
0 | 1318 profile_branch(x, cond); |
1319 move_to_phi(x->state()); | |
1320 if (x->x()->type()->is_float_kind()) { | |
1321 __ branch(lir_cond(cond), right->type(), x->tsux(), x->usux()); | |
1322 } else { | |
1323 __ branch(lir_cond(cond), right->type(), x->tsux()); | |
1324 } | |
1325 assert(x->default_sux() == x->fsux(), "wrong destination above"); | |
1326 __ jump(x->default_sux()); | |
1327 } | |
1328 | |
1329 | |
1330 LIR_Opr LIRGenerator::getThreadPointer() { | |
304 | 1331 #ifdef _LP64 |
1332 return FrameMap::as_pointer_opr(r15_thread); | |
1333 #else | |
0 | 1334 LIR_Opr result = new_register(T_INT); |
1335 __ get_thread(result); | |
1336 return result; | |
304 | 1337 #endif // |
0 | 1338 } |
1339 | |
1340 void LIRGenerator::trace_block_entry(BlockBegin* block) { | |
1341 store_stack_parameter(LIR_OprFact::intConst(block->block_id()), in_ByteSize(0)); | |
1342 LIR_OprList* args = new LIR_OprList(); | |
1343 address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry); | |
1344 __ call_runtime_leaf(func, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, args); | |
1345 } | |
1346 | |
1347 | |
1348 void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address, | |
1349 CodeEmitInfo* info) { | |
1350 if (address->type() == T_LONG) { | |
1351 address = new LIR_Address(address->base(), | |
1352 address->index(), address->scale(), | |
1353 address->disp(), T_DOUBLE); | |
1354 // Transfer the value atomically by using FP moves. This means | |
1355 // the value has to be moved between CPU and FPU registers. It | |
1356 // always has to be moved through spill slot since there's no | |
1357 // quick way to pack the value into an SSE register. | |
1358 LIR_Opr temp_double = new_register(T_DOUBLE); | |
1359 LIR_Opr spill = new_register(T_LONG); | |
1360 set_vreg_flag(spill, must_start_in_memory); | |
1361 __ move(value, spill); | |
1362 __ volatile_move(spill, temp_double, T_LONG); | |
1363 __ volatile_move(temp_double, LIR_OprFact::address(address), T_LONG, info); | |
1364 } else { | |
1365 __ store(value, address, info); | |
1366 } | |
1367 } | |
1368 | |
1369 | |
1370 | |
1371 void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result, | |
1372 CodeEmitInfo* info) { | |
1373 if (address->type() == T_LONG) { | |
1374 address = new LIR_Address(address->base(), | |
1375 address->index(), address->scale(), | |
1376 address->disp(), T_DOUBLE); | |
1377 // Transfer the value atomically by using FP moves. This means | |
1378 // the value has to be moved between CPU and FPU registers. In | |
1379 // SSE0 and SSE1 mode it has to be moved through spill slot but in | |
1380 // SSE2+ mode it can be moved directly. | |
1381 LIR_Opr temp_double = new_register(T_DOUBLE); | |
1382 __ volatile_move(LIR_OprFact::address(address), temp_double, T_LONG, info); | |
1383 __ volatile_move(temp_double, result, T_LONG); | |
1384 if (UseSSE < 2) { | |
1385 // no spill slot needed in SSE2 mode because xmm->cpu register move is possible | |
1386 set_vreg_flag(result, must_start_in_memory); | |
1387 } | |
1388 } else { | |
1389 __ load(address, result, info); | |
1390 } | |
1391 } | |
1392 | |
1393 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset, | |
1394 BasicType type, bool is_volatile) { | |
1395 if (is_volatile && type == T_LONG) { | |
1396 LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE); | |
1397 LIR_Opr tmp = new_register(T_DOUBLE); | |
1398 __ load(addr, tmp); | |
1399 LIR_Opr spill = new_register(T_LONG); | |
1400 set_vreg_flag(spill, must_start_in_memory); | |
1401 __ move(tmp, spill); | |
1402 __ move(spill, dst); | |
1403 } else { | |
1404 LIR_Address* addr = new LIR_Address(src, offset, type); | |
1405 __ load(addr, dst); | |
1406 } | |
1407 } | |
1408 | |
1409 | |
1410 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, | |
1411 BasicType type, bool is_volatile) { | |
1412 if (is_volatile && type == T_LONG) { | |
1413 LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE); | |
1414 LIR_Opr tmp = new_register(T_DOUBLE); | |
1415 LIR_Opr spill = new_register(T_DOUBLE); | |
1416 set_vreg_flag(spill, must_start_in_memory); | |
1417 __ move(data, spill); | |
1418 __ move(spill, tmp); | |
1419 __ move(tmp, addr); | |
1420 } else { | |
1421 LIR_Address* addr = new LIR_Address(src, offset, type); | |
1422 bool is_obj = (type == T_ARRAY || type == T_OBJECT); | |
1423 if (is_obj) { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
1424 // Do the pre-write barrier, if any. |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2169
diff
changeset
|
1425 pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2169
diff
changeset
|
1426 true /* do_load */, false /* patch */, NULL); |
0 | 1427 __ move(data, addr); |
1428 assert(src->is_register(), "must be register"); | |
1429 // Seems to be a precise address | |
1430 post_barrier(LIR_OprFact::address(addr), data); | |
1431 } else { | |
1432 __ move(data, addr); | |
1433 } | |
1434 } | |
1435 } | |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1436 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1437 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1438 BasicType type = x->basic_type(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1439 LIRItem src(x->object(), this); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1440 LIRItem off(x->offset(), this); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1441 LIRItem value(x->value(), this); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1442 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1443 src.load_item(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1444 value.load_item(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1445 off.load_nonconstant(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1446 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1447 LIR_Opr dst = rlock_result(x, type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1448 LIR_Opr data = value.result(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1449 bool is_obj = (type == T_ARRAY || type == T_OBJECT); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1450 LIR_Opr offset = off.result(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1451 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1452 assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type"); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1453 LIR_Address* addr; |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1454 if (offset->is_constant()) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1455 #ifdef _LP64 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1456 jlong c = offset->as_jlong(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1457 if ((jlong)((jint)c) == c) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1458 addr = new LIR_Address(src.result(), (jint)c, type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1459 } else { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1460 LIR_Opr tmp = new_register(T_LONG); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1461 __ move(offset, tmp); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1462 addr = new LIR_Address(src.result(), tmp, type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1463 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1464 #else |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1465 addr = new LIR_Address(src.result(), offset->as_jint(), type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1466 #endif |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1467 } else { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1468 addr = new LIR_Address(src.result(), offset, type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1469 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1470 |
13022
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1471 // Because we want a 2-arg form of xchg and xadd |
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1472 __ move(data, dst); |
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1473 |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1474 if (x->is_add()) { |
13022
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1475 __ xadd(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr); |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1476 } else { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1477 if (is_obj) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1478 // Do the pre-write barrier, if any. |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1479 pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */, |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1480 true /* do_load */, false /* patch */, NULL); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1481 } |
13022
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1482 __ xchg(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr); |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1483 if (is_obj) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1484 // Seems to be a precise address |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1485 post_barrier(LIR_OprFact::address(addr), data); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1486 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1487 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1488 } |