Mercurial > hg > truffle
annotate src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @ 20304:a22acf6d7598
8048112: G1 Full GC needs to support the case when the very first region is not available
Summary: Refactor preparation for compaction during Full GC so that it lazily initializes the first compaction point. This also avoids problems later when the first region may not be committed. Also reviewed by K. Barrett.
Reviewed-by: brutisso
author | tschatzl |
---|---|
date | Mon, 21 Jul 2014 10:00:31 +0200 |
parents | 8b81451dc7f7 |
children | 4ca6dc0799b6 2fd0fd493045 |
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); |
17497
8b81451dc7f7
8022395: java.util.zip.ZipException: Not in GZIP format in JT_JDK/test/java/util/zip/GZIP tests
twisti
parents:
13022
diff
changeset
|
944 // val is destroyed by update_crc32 |
8b81451dc7f7
8022395: java.util.zip.ZipException: Not in GZIP format in JT_JDK/test/java/util/zip/GZIP tests
twisti
parents:
13022
diff
changeset
|
945 val.set_destroys_register(); |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
946 crc.load_item(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
947 val.load_item(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
948 __ update_crc32(crc.result(), val.result(), result); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
949 break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
950 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
951 case vmIntrinsics::_updateBytesCRC32: |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
952 case vmIntrinsics::_updateByteBufferCRC32: { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
953 bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
954 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
955 LIRItem crc(x->argument_at(0), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
956 LIRItem buf(x->argument_at(1), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
957 LIRItem off(x->argument_at(2), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
958 LIRItem len(x->argument_at(3), this); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
959 buf.load_item(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
960 off.load_nonconstant(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
961 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
962 LIR_Opr index = off.result(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
963 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
|
964 if(off.result()->is_constant()) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
965 index = LIR_OprFact::illegalOpr; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
966 offset += off.result()->as_jint(); |
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 LIR_Opr base_op = buf.result(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
969 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
970 #ifndef _LP64 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
971 if (!is_updateBytes) { // long b raw address |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
972 base_op = new_register(T_INT); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
973 __ convert(Bytecodes::_l2i, buf.result(), base_op); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
974 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
975 #else |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
976 if (index->is_valid()) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
977 LIR_Opr tmp = new_register(T_LONG); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
978 __ convert(Bytecodes::_i2l, index, tmp); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
979 index = tmp; |
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 #endif |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
982 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
983 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
|
984 index, |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
985 LIR_Address::times_1, |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
986 offset, |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
987 T_BYTE); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
988 BasicTypeList signature(3); |
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 signature.append(T_ADDRESS); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
991 signature.append(T_INT); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
992 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
|
993 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
|
994 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
995 LIR_Opr addr = new_pointer_register(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
996 __ leal(LIR_OprFact::address(a), addr); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
997 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
998 crc.load_item_force(cc->at(0)); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
999 __ move(addr, cc->at(1)); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1000 len.load_item_force(cc->at(2)); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1001 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1002 __ 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
|
1003 __ move(result_reg, result); |
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 break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1006 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1007 default: { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1008 ShouldNotReachHere(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1009 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1010 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
8860
diff
changeset
|
1011 } |
0 | 1012 |
1013 // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f | |
1014 // _i2b, _i2c, _i2s | |
1015 LIR_Opr fixed_register_for(BasicType type) { | |
1016 switch (type) { | |
1017 case T_FLOAT: return FrameMap::fpu0_float_opr; | |
1018 case T_DOUBLE: return FrameMap::fpu0_double_opr; | |
1019 case T_INT: return FrameMap::rax_opr; | |
304 | 1020 case T_LONG: return FrameMap::long0_opr; |
0 | 1021 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; |
1022 } | |
1023 } | |
1024 | |
1025 void LIRGenerator::do_Convert(Convert* x) { | |
1026 // flags that vary for the different operations and different SSE-settings | |
1027 bool fixed_input, fixed_result, round_result, needs_stub; | |
1028 | |
1029 switch (x->op()) { | |
1030 case Bytecodes::_i2l: // fall through | |
1031 case Bytecodes::_l2i: // fall through | |
1032 case Bytecodes::_i2b: // fall through | |
1033 case Bytecodes::_i2c: // fall through | |
1034 case Bytecodes::_i2s: fixed_input = false; fixed_result = false; round_result = false; needs_stub = false; break; | |
1035 | |
1036 case Bytecodes::_f2d: fixed_input = UseSSE == 1; fixed_result = false; round_result = false; needs_stub = false; break; | |
1037 case Bytecodes::_d2f: fixed_input = false; fixed_result = UseSSE == 1; round_result = UseSSE < 1; needs_stub = false; break; | |
1038 case Bytecodes::_i2f: fixed_input = false; fixed_result = false; round_result = UseSSE < 1; needs_stub = false; break; | |
1039 case Bytecodes::_i2d: fixed_input = false; fixed_result = false; round_result = false; needs_stub = false; break; | |
1040 case Bytecodes::_f2i: fixed_input = false; fixed_result = false; round_result = false; needs_stub = true; break; | |
1041 case Bytecodes::_d2i: fixed_input = false; fixed_result = false; round_result = false; needs_stub = true; break; | |
1042 case Bytecodes::_l2f: fixed_input = false; fixed_result = UseSSE >= 1; round_result = UseSSE < 1; needs_stub = false; break; | |
1043 case Bytecodes::_l2d: fixed_input = false; fixed_result = UseSSE >= 2; round_result = UseSSE < 2; needs_stub = false; break; | |
1044 case Bytecodes::_f2l: fixed_input = true; fixed_result = true; round_result = false; needs_stub = false; break; | |
1045 case Bytecodes::_d2l: fixed_input = true; fixed_result = true; round_result = false; needs_stub = false; break; | |
1046 default: ShouldNotReachHere(); | |
1047 } | |
1048 | |
1049 LIRItem value(x->value(), this); | |
1050 value.load_item(); | |
1051 LIR_Opr input = value.result(); | |
1052 LIR_Opr result = rlock(x); | |
1053 | |
1054 // arguments of lir_convert | |
1055 LIR_Opr conv_input = input; | |
1056 LIR_Opr conv_result = result; | |
1057 ConversionStub* stub = NULL; | |
1058 | |
1059 if (fixed_input) { | |
1060 conv_input = fixed_register_for(input->type()); | |
1061 __ move(input, conv_input); | |
1062 } | |
1063 | |
1064 assert(fixed_result == false || round_result == false, "cannot set both"); | |
1065 if (fixed_result) { | |
1066 conv_result = fixed_register_for(result->type()); | |
1067 } else if (round_result) { | |
1068 result = new_register(result->type()); | |
1069 set_vreg_flag(result, must_start_in_memory); | |
1070 } | |
1071 | |
1072 if (needs_stub) { | |
1073 stub = new ConversionStub(x->op(), conv_input, conv_result); | |
1074 } | |
1075 | |
1076 __ convert(x->op(), conv_input, conv_result, stub); | |
1077 | |
1078 if (result != conv_result) { | |
1079 __ move(conv_result, result); | |
1080 } | |
1081 | |
1082 assert(result->is_virtual(), "result must be virtual register"); | |
1083 set_result(x, result); | |
1084 } | |
1085 | |
1086 | |
1087 void LIRGenerator::do_NewInstance(NewInstance* x) { | |
1819 | 1088 #ifndef PRODUCT |
0 | 1089 if (PrintNotLoaded && !x->klass()->is_loaded()) { |
1819 | 1090 tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci()); |
0 | 1091 } |
1819 | 1092 #endif |
0 | 1093 CodeEmitInfo* info = state_for(x, x->state()); |
1094 LIR_Opr reg = result_register_for(x->type()); | |
1095 new_instance(reg, x->klass(), | |
1096 FrameMap::rcx_oop_opr, | |
1097 FrameMap::rdi_oop_opr, | |
1098 FrameMap::rsi_oop_opr, | |
1099 LIR_OprFact::illegalOpr, | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1100 FrameMap::rdx_metadata_opr, info); |
0 | 1101 LIR_Opr result = rlock_result(x); |
1102 __ move(reg, result); | |
1103 } | |
1104 | |
1105 | |
1106 void LIRGenerator::do_NewTypeArray(NewTypeArray* x) { | |
1107 CodeEmitInfo* info = state_for(x, x->state()); | |
1108 | |
1109 LIRItem length(x->length(), this); | |
1110 length.load_item_force(FrameMap::rbx_opr); | |
1111 | |
1112 LIR_Opr reg = result_register_for(x->type()); | |
1113 LIR_Opr tmp1 = FrameMap::rcx_oop_opr; | |
1114 LIR_Opr tmp2 = FrameMap::rsi_oop_opr; | |
1115 LIR_Opr tmp3 = FrameMap::rdi_oop_opr; | |
1116 LIR_Opr tmp4 = reg; | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1117 LIR_Opr klass_reg = FrameMap::rdx_metadata_opr; |
0 | 1118 LIR_Opr len = length.result(); |
1119 BasicType elem_type = x->elt_type(); | |
1120 | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1121 __ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg); |
0 | 1122 |
1123 CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info); | |
1124 __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path); | |
1125 | |
1126 LIR_Opr result = rlock_result(x); | |
1127 __ move(reg, result); | |
1128 } | |
1129 | |
1130 | |
1131 void LIRGenerator::do_NewObjectArray(NewObjectArray* x) { | |
1132 LIRItem length(x->length(), this); | |
1133 // in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction | |
1134 // and therefore provide the state before the parameters have been consumed | |
1135 CodeEmitInfo* patching_info = NULL; | |
1136 if (!x->klass()->is_loaded() || PatchALot) { | |
1137 patching_info = state_for(x, x->state_before()); | |
1138 } | |
1139 | |
1140 CodeEmitInfo* info = state_for(x, x->state()); | |
1141 | |
1142 const LIR_Opr reg = result_register_for(x->type()); | |
1143 LIR_Opr tmp1 = FrameMap::rcx_oop_opr; | |
1144 LIR_Opr tmp2 = FrameMap::rsi_oop_opr; | |
1145 LIR_Opr tmp3 = FrameMap::rdi_oop_opr; | |
1146 LIR_Opr tmp4 = reg; | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1147 LIR_Opr klass_reg = FrameMap::rdx_metadata_opr; |
0 | 1148 |
1149 length.load_item_force(FrameMap::rbx_opr); | |
1150 LIR_Opr len = length.result(); | |
1151 | |
1152 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
|
1153 ciKlass* obj = (ciKlass*) ciObjArrayKlass::make(x->klass()); |
0 | 1154 if (obj == ciEnv::unloaded_ciobjarrayklass()) { |
1155 BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error"); | |
1156 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6145
diff
changeset
|
1157 klass2reg_with_patching(klass_reg, obj, patching_info); |
0 | 1158 __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path); |
1159 | |
1160 LIR_Opr result = rlock_result(x); | |
1161 __ move(reg, result); | |
1162 } | |
1163 | |
1164 | |
1165 void LIRGenerator::do_NewMultiArray(NewMultiArray* x) { | |
1166 Values* dims = x->dims(); | |
1167 int i = dims->length(); | |
1168 LIRItemList* items = new LIRItemList(dims->length(), NULL); | |
1169 while (i-- > 0) { | |
1170 LIRItem* size = new LIRItem(dims->at(i), this); | |
1171 items->at_put(i, size); | |
1172 } | |
1173 | |
933
cdb8b7c37ac1
6875329: fix for 6795465 broke exception handler cloning
never
parents:
605
diff
changeset
|
1174 // Evaluate state_for early since it may emit code. |
0 | 1175 CodeEmitInfo* patching_info = NULL; |
1176 if (!x->klass()->is_loaded() || PatchALot) { | |
1177 patching_info = state_for(x, x->state_before()); | |
1178 | |
6145
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
6143
diff
changeset
|
1179 // 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
|
1180 // 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
|
1181 // 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
|
1182 // is done explicitly here because a stub isn't being used). |
0 | 1183 x->set_exception_handlers(new XHandlers(x->exception_handlers())); |
1184 } | |
1185 CodeEmitInfo* info = state_for(x, x->state()); | |
1186 | |
1187 i = dims->length(); | |
1188 while (i-- > 0) { | |
1189 LIRItem* size = items->at(i); | |
1190 size->load_nonconstant(); | |
1191 | |
1192 store_stack_parameter(size->result(), in_ByteSize(i*4)); | |
1193 } | |
1194 | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1195 LIR_Opr klass_reg = FrameMap::rax_metadata_opr; |
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1196 klass2reg_with_patching(klass_reg, x->klass(), patching_info); |
0 | 1197 |
1198 LIR_Opr rank = FrameMap::rbx_opr; | |
1199 __ move(LIR_OprFact::intConst(x->rank()), rank); | |
1200 LIR_Opr varargs = FrameMap::rcx_opr; | |
1201 __ move(FrameMap::rsp_opr, varargs); | |
1202 LIR_OprList* args = new LIR_OprList(3); | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1203 args->append(klass_reg); |
0 | 1204 args->append(rank); |
1205 args->append(varargs); | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1206 LIR_Opr reg = result_register_for(x->type()); |
0 | 1207 __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id), |
1208 LIR_OprFact::illegalOpr, | |
1209 reg, args, info); | |
1210 | |
1211 LIR_Opr result = rlock_result(x); | |
1212 __ move(reg, result); | |
1213 } | |
1214 | |
1215 | |
1216 void LIRGenerator::do_BlockBegin(BlockBegin* x) { | |
1217 // nothing to do for now | |
1218 } | |
1219 | |
1220 | |
1221 void LIRGenerator::do_CheckCast(CheckCast* x) { | |
1222 LIRItem obj(x->obj(), this); | |
1223 | |
1224 CodeEmitInfo* patching_info = NULL; | |
1225 if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check())) { | |
1226 // must do this before locking the destination register as an oop register, | |
1227 // and before the obj is loaded (the latter is for deoptimization) | |
1228 patching_info = state_for(x, x->state_before()); | |
1229 } | |
1230 obj.load_item(); | |
1231 | |
1232 // info for exceptions | |
1819 | 1233 CodeEmitInfo* info_for_exception = state_for(x); |
0 | 1234 |
1235 CodeStub* stub; | |
1236 if (x->is_incompatible_class_change_check()) { | |
1237 assert(patching_info == NULL, "can't patch this"); | |
1238 stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception); | |
1239 } else { | |
1240 stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); | |
1241 } | |
1242 LIR_Opr reg = rlock_result(x); | |
2002 | 1243 LIR_Opr tmp3 = LIR_OprFact::illegalOpr; |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
11080
diff
changeset
|
1244 if (!x->klass()->is_loaded() || UseCompressedClassPointers) { |
2002 | 1245 tmp3 = new_register(objectType); |
1246 } | |
0 | 1247 __ checkcast(reg, obj.result(), x->klass(), |
2002 | 1248 new_register(objectType), new_register(objectType), tmp3, |
0 | 1249 x->direct_compare(), info_for_exception, patching_info, stub, |
1250 x->profiled_method(), x->profiled_bci()); | |
1251 } | |
1252 | |
1253 | |
1254 void LIRGenerator::do_InstanceOf(InstanceOf* x) { | |
1255 LIRItem obj(x->obj(), this); | |
1256 | |
1257 // result and test object may not be in same register | |
1258 LIR_Opr reg = rlock_result(x); | |
1259 CodeEmitInfo* patching_info = NULL; | |
1260 if ((!x->klass()->is_loaded() || PatchALot)) { | |
1261 // must do this before locking the destination register as an oop register | |
1262 patching_info = state_for(x, x->state_before()); | |
1263 } | |
1264 obj.load_item(); | |
2002 | 1265 LIR_Opr tmp3 = LIR_OprFact::illegalOpr; |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
11080
diff
changeset
|
1266 if (!x->klass()->is_loaded() || UseCompressedClassPointers) { |
2002 | 1267 tmp3 = new_register(objectType); |
1268 } | |
0 | 1269 __ instanceof(reg, obj.result(), x->klass(), |
2002 | 1270 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
|
1271 x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); |
0 | 1272 } |
1273 | |
1274 | |
1275 void LIRGenerator::do_If(If* x) { | |
1276 assert(x->number_of_sux() == 2, "inconsistency"); | |
1277 ValueTag tag = x->x()->type()->tag(); | |
1278 bool is_safepoint = x->is_safepoint(); | |
1279 | |
1280 If::Condition cond = x->cond(); | |
1281 | |
1282 LIRItem xitem(x->x(), this); | |
1283 LIRItem yitem(x->y(), this); | |
1284 LIRItem* xin = &xitem; | |
1285 LIRItem* yin = &yitem; | |
1286 | |
1287 if (tag == longTag) { | |
1288 // for longs, only conditions "eql", "neq", "lss", "geq" are valid; | |
1289 // mirror for other conditions | |
1290 if (cond == If::gtr || cond == If::leq) { | |
1291 cond = Instruction::mirror(cond); | |
1292 xin = &yitem; | |
1293 yin = &xitem; | |
1294 } | |
1295 xin->set_destroys_register(); | |
1296 } | |
1297 xin->load_item(); | |
1298 if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) { | |
1299 // inline long zero | |
1300 yin->dont_load_item(); | |
1301 } else if (tag == longTag || tag == floatTag || tag == doubleTag) { | |
1302 // longs cannot handle constants at right side | |
1303 yin->load_item(); | |
1304 } else { | |
1305 yin->dont_load_item(); | |
1306 } | |
1307 | |
1308 // add safepoint before generating condition code so it can be recomputed | |
1309 if (x->is_safepoint()) { | |
1310 // increment backedge counter if needed | |
1783 | 1311 increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci()); |
0 | 1312 __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before())); |
1313 } | |
1314 set_no_result(x); | |
1315 | |
1316 LIR_Opr left = xin->result(); | |
1317 LIR_Opr right = yin->result(); | |
1318 __ cmp(lir_cond(cond), left, right); | |
1783 | 1319 // Generate branch profiling. Profiling code doesn't kill flags. |
0 | 1320 profile_branch(x, cond); |
1321 move_to_phi(x->state()); | |
1322 if (x->x()->type()->is_float_kind()) { | |
1323 __ branch(lir_cond(cond), right->type(), x->tsux(), x->usux()); | |
1324 } else { | |
1325 __ branch(lir_cond(cond), right->type(), x->tsux()); | |
1326 } | |
1327 assert(x->default_sux() == x->fsux(), "wrong destination above"); | |
1328 __ jump(x->default_sux()); | |
1329 } | |
1330 | |
1331 | |
1332 LIR_Opr LIRGenerator::getThreadPointer() { | |
304 | 1333 #ifdef _LP64 |
1334 return FrameMap::as_pointer_opr(r15_thread); | |
1335 #else | |
0 | 1336 LIR_Opr result = new_register(T_INT); |
1337 __ get_thread(result); | |
1338 return result; | |
304 | 1339 #endif // |
0 | 1340 } |
1341 | |
1342 void LIRGenerator::trace_block_entry(BlockBegin* block) { | |
1343 store_stack_parameter(LIR_OprFact::intConst(block->block_id()), in_ByteSize(0)); | |
1344 LIR_OprList* args = new LIR_OprList(); | |
1345 address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry); | |
1346 __ call_runtime_leaf(func, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, args); | |
1347 } | |
1348 | |
1349 | |
1350 void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address, | |
1351 CodeEmitInfo* info) { | |
1352 if (address->type() == T_LONG) { | |
1353 address = new LIR_Address(address->base(), | |
1354 address->index(), address->scale(), | |
1355 address->disp(), T_DOUBLE); | |
1356 // Transfer the value atomically by using FP moves. This means | |
1357 // the value has to be moved between CPU and FPU registers. It | |
1358 // always has to be moved through spill slot since there's no | |
1359 // quick way to pack the value into an SSE register. | |
1360 LIR_Opr temp_double = new_register(T_DOUBLE); | |
1361 LIR_Opr spill = new_register(T_LONG); | |
1362 set_vreg_flag(spill, must_start_in_memory); | |
1363 __ move(value, spill); | |
1364 __ volatile_move(spill, temp_double, T_LONG); | |
1365 __ volatile_move(temp_double, LIR_OprFact::address(address), T_LONG, info); | |
1366 } else { | |
1367 __ store(value, address, info); | |
1368 } | |
1369 } | |
1370 | |
1371 | |
1372 | |
1373 void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result, | |
1374 CodeEmitInfo* info) { | |
1375 if (address->type() == T_LONG) { | |
1376 address = new LIR_Address(address->base(), | |
1377 address->index(), address->scale(), | |
1378 address->disp(), T_DOUBLE); | |
1379 // Transfer the value atomically by using FP moves. This means | |
1380 // the value has to be moved between CPU and FPU registers. In | |
1381 // SSE0 and SSE1 mode it has to be moved through spill slot but in | |
1382 // SSE2+ mode it can be moved directly. | |
1383 LIR_Opr temp_double = new_register(T_DOUBLE); | |
1384 __ volatile_move(LIR_OprFact::address(address), temp_double, T_LONG, info); | |
1385 __ volatile_move(temp_double, result, T_LONG); | |
1386 if (UseSSE < 2) { | |
1387 // no spill slot needed in SSE2 mode because xmm->cpu register move is possible | |
1388 set_vreg_flag(result, must_start_in_memory); | |
1389 } | |
1390 } else { | |
1391 __ load(address, result, info); | |
1392 } | |
1393 } | |
1394 | |
1395 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset, | |
1396 BasicType type, bool is_volatile) { | |
1397 if (is_volatile && type == T_LONG) { | |
1398 LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE); | |
1399 LIR_Opr tmp = new_register(T_DOUBLE); | |
1400 __ load(addr, tmp); | |
1401 LIR_Opr spill = new_register(T_LONG); | |
1402 set_vreg_flag(spill, must_start_in_memory); | |
1403 __ move(tmp, spill); | |
1404 __ move(spill, dst); | |
1405 } else { | |
1406 LIR_Address* addr = new LIR_Address(src, offset, type); | |
1407 __ load(addr, dst); | |
1408 } | |
1409 } | |
1410 | |
1411 | |
1412 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, | |
1413 BasicType type, bool is_volatile) { | |
1414 if (is_volatile && type == T_LONG) { | |
1415 LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE); | |
1416 LIR_Opr tmp = new_register(T_DOUBLE); | |
1417 LIR_Opr spill = new_register(T_DOUBLE); | |
1418 set_vreg_flag(spill, must_start_in_memory); | |
1419 __ move(data, spill); | |
1420 __ move(spill, tmp); | |
1421 __ move(tmp, addr); | |
1422 } else { | |
1423 LIR_Address* addr = new LIR_Address(src, offset, type); | |
1424 bool is_obj = (type == T_ARRAY || type == T_OBJECT); | |
1425 if (is_obj) { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
1426 // 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
|
1427 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
|
1428 true /* do_load */, false /* patch */, NULL); |
0 | 1429 __ move(data, addr); |
1430 assert(src->is_register(), "must be register"); | |
1431 // Seems to be a precise address | |
1432 post_barrier(LIR_OprFact::address(addr), data); | |
1433 } else { | |
1434 __ move(data, addr); | |
1435 } | |
1436 } | |
1437 } | |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1438 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1439 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1440 BasicType type = x->basic_type(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1441 LIRItem src(x->object(), this); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1442 LIRItem off(x->offset(), this); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1443 LIRItem value(x->value(), this); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1444 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1445 src.load_item(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1446 value.load_item(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1447 off.load_nonconstant(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1448 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1449 LIR_Opr dst = rlock_result(x, type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1450 LIR_Opr data = value.result(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1451 bool is_obj = (type == T_ARRAY || type == T_OBJECT); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1452 LIR_Opr offset = off.result(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1453 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1454 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
|
1455 LIR_Address* addr; |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1456 if (offset->is_constant()) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1457 #ifdef _LP64 |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1458 jlong c = offset->as_jlong(); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1459 if ((jlong)((jint)c) == c) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1460 addr = new LIR_Address(src.result(), (jint)c, type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1461 } else { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1462 LIR_Opr tmp = new_register(T_LONG); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1463 __ move(offset, tmp); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1464 addr = new LIR_Address(src.result(), tmp, type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1465 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1466 #else |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1467 addr = new LIR_Address(src.result(), offset->as_jint(), type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1468 #endif |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1469 } else { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1470 addr = new LIR_Address(src.result(), offset, type); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1471 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1472 |
13022
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1473 // 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
|
1474 __ move(data, dst); |
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1475 |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1476 if (x->is_add()) { |
13022
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1477 __ xadd(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr); |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1478 } else { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1479 if (is_obj) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1480 // Do the pre-write barrier, if any. |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1481 pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */, |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1482 true /* do_load */, false /* patch */, NULL); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1483 } |
13022
946a8294ab15
8024919: G1: SPECjbb2013 crashes due to a broken object reference
iveresov
parents:
12226
diff
changeset
|
1484 __ xchg(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr); |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1485 if (is_obj) { |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1486 // Seems to be a precise address |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1487 post_barrier(LIR_OprFact::address(addr), data); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1488 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1489 } |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6739
diff
changeset
|
1490 } |