Mercurial > hg > graal-compiler
annotate src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @ 6812:988bf00cc564
7200261: G1: Liveness counting inconsistencies during marking verification
Summary: The clipping code in the routine that sets the bits for a range of cards, in the liveness accounting verification code was incorrect. It set all the bits in the card bitmap from the given starting index which would lead to spurious marking verification failures.
Reviewed-by: brutisso, jwilhelm, jmasa
author | johnc |
---|---|
date | Thu, 27 Sep 2012 15:44:01 -0700 |
parents | 8a02ca5e5576 |
children | 7eca5de9e0b6 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6145
diff
changeset
|
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
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_sparc.inline.hpp" | |
0 | 39 |
40 #ifdef ASSERT | |
41 #define __ gen()->lir(__FILE__, __LINE__)-> | |
42 #else | |
43 #define __ gen()->lir()-> | |
44 #endif | |
45 | |
46 void LIRItem::load_byte_item() { | |
47 // byte loads use same registers as other loads | |
48 load_item(); | |
49 } | |
50 | |
51 | |
52 void LIRItem::load_nonconstant() { | |
53 LIR_Opr r = value()->operand(); | |
54 if (_gen->can_inline_as_constant(value())) { | |
55 if (!r->is_constant()) { | |
56 r = LIR_OprFact::value_type(value()->type()); | |
57 } | |
58 _result = r; | |
59 } else { | |
60 load_item(); | |
61 } | |
62 } | |
63 | |
64 | |
65 //-------------------------------------------------------------- | |
66 // LIRGenerator | |
67 //-------------------------------------------------------------- | |
68 | |
69 LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::Oexception_opr; } | |
70 LIR_Opr LIRGenerator::exceptionPcOpr() { return FrameMap::Oissuing_pc_opr; } | |
71 LIR_Opr LIRGenerator::syncTempOpr() { return new_register(T_OBJECT); } | |
72 LIR_Opr LIRGenerator::getThreadTemp() { return rlock_callee_saved(T_INT); } | |
73 | |
74 LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) { | |
75 LIR_Opr opr; | |
76 switch (type->tag()) { | |
77 case intTag: opr = callee ? FrameMap::I0_opr : FrameMap::O0_opr; break; | |
78 case objectTag: opr = callee ? FrameMap::I0_oop_opr : FrameMap::O0_oop_opr; break; | |
79 case longTag: opr = callee ? FrameMap::in_long_opr : FrameMap::out_long_opr; break; | |
80 case floatTag: opr = FrameMap::F0_opr; break; | |
81 case doubleTag: opr = FrameMap::F0_double_opr; break; | |
82 | |
83 case addressTag: | |
84 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr; | |
85 } | |
86 | |
87 assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch"); | |
88 return opr; | |
89 } | |
90 | |
91 LIR_Opr LIRGenerator::rlock_callee_saved(BasicType type) { | |
92 LIR_Opr reg = new_register(type); | |
93 set_vreg_flag(reg, callee_saved); | |
94 return reg; | |
95 } | |
96 | |
97 | |
98 LIR_Opr LIRGenerator::rlock_byte(BasicType type) { | |
99 return new_register(T_INT); | |
100 } | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 //--------- loading items into registers -------------------------------- | |
107 | |
108 // SPARC cannot inline all constants | |
109 bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { | |
110 if (v->type()->as_IntConstant() != NULL) { | |
111 return v->type()->as_IntConstant()->value() == 0; | |
112 } else if (v->type()->as_LongConstant() != NULL) { | |
113 return v->type()->as_LongConstant()->value() == 0L; | |
114 } else if (v->type()->as_ObjectConstant() != NULL) { | |
115 return v->type()->as_ObjectConstant()->value()->is_null_object(); | |
116 } else { | |
117 return false; | |
118 } | |
119 } | |
120 | |
121 | |
122 // only simm13 constants can be inlined | |
123 bool LIRGenerator:: can_inline_as_constant(Value i) const { | |
124 if (i->type()->as_IntConstant() != NULL) { | |
125 return Assembler::is_simm13(i->type()->as_IntConstant()->value()); | |
126 } else { | |
127 return can_store_as_constant(i, as_BasicType(i->type())); | |
128 } | |
129 } | |
130 | |
131 | |
132 bool LIRGenerator:: can_inline_as_constant(LIR_Const* c) const { | |
133 if (c->type() == T_INT) { | |
134 return Assembler::is_simm13(c->as_jint()); | |
135 } | |
136 return false; | |
137 } | |
138 | |
139 | |
140 LIR_Opr LIRGenerator::safepoint_poll_register() { | |
141 return new_register(T_INT); | |
142 } | |
143 | |
144 | |
145 | |
146 LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, | |
147 int shift, int disp, BasicType type) { | |
148 assert(base->is_register(), "must be"); | |
149 | |
150 // accumulate fixed displacements | |
151 if (index->is_constant()) { | |
152 disp += index->as_constant_ptr()->as_jint() << shift; | |
153 index = LIR_OprFact::illegalOpr; | |
154 } | |
155 | |
156 if (index->is_register()) { | |
157 // apply the shift and accumulate the displacement | |
158 if (shift > 0) { | |
1060 | 159 LIR_Opr tmp = new_pointer_register(); |
0 | 160 __ shift_left(index, shift, tmp); |
161 index = tmp; | |
162 } | |
163 if (disp != 0) { | |
1060 | 164 LIR_Opr tmp = new_pointer_register(); |
0 | 165 if (Assembler::is_simm13(disp)) { |
1060 | 166 __ add(tmp, LIR_OprFact::intptrConst(disp), tmp); |
0 | 167 index = tmp; |
168 } else { | |
1060 | 169 __ move(LIR_OprFact::intptrConst(disp), tmp); |
0 | 170 __ add(tmp, index, tmp); |
171 index = tmp; | |
172 } | |
173 disp = 0; | |
174 } | |
175 } else if (disp != 0 && !Assembler::is_simm13(disp)) { | |
176 // index is illegal so replace it with the displacement loaded into a register | |
1060 | 177 index = new_pointer_register(); |
178 __ move(LIR_OprFact::intptrConst(disp), index); | |
0 | 179 disp = 0; |
180 } | |
181 | |
182 // at this point we either have base + index or base + displacement | |
183 if (disp == 0) { | |
184 return new LIR_Address(base, index, type); | |
185 } else { | |
186 assert(Assembler::is_simm13(disp), "must be"); | |
187 return new LIR_Address(base, disp, type); | |
188 } | |
189 } | |
190 | |
191 | |
192 LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, | |
193 BasicType type, bool needs_card_mark) { | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
194 int elem_size = type2aelembytes(type); |
0 | 195 int shift = exact_log2(elem_size); |
196 | |
197 LIR_Opr base_opr; | |
198 int offset = arrayOopDesc::base_offset_in_bytes(type); | |
199 | |
200 if (index_opr->is_constant()) { | |
201 int i = index_opr->as_constant_ptr()->as_jint(); | |
202 int array_offset = i * elem_size; | |
203 if (Assembler::is_simm13(array_offset + offset)) { | |
204 base_opr = array_opr; | |
205 offset = array_offset + offset; | |
206 } else { | |
207 base_opr = new_pointer_register(); | |
208 if (Assembler::is_simm13(array_offset)) { | |
209 __ add(array_opr, LIR_OprFact::intptrConst(array_offset), base_opr); | |
210 } else { | |
211 __ move(LIR_OprFact::intptrConst(array_offset), base_opr); | |
212 __ add(base_opr, array_opr, base_opr); | |
213 } | |
214 } | |
215 } else { | |
216 #ifdef _LP64 | |
217 if (index_opr->type() == T_INT) { | |
218 LIR_Opr tmp = new_register(T_LONG); | |
219 __ convert(Bytecodes::_i2l, index_opr, tmp); | |
220 index_opr = tmp; | |
221 } | |
222 #endif | |
223 | |
224 base_opr = new_pointer_register(); | |
225 assert (index_opr->is_register(), "Must be register"); | |
226 if (shift > 0) { | |
227 __ shift_left(index_opr, shift, base_opr); | |
228 __ add(base_opr, array_opr, base_opr); | |
229 } else { | |
230 __ add(index_opr, array_opr, base_opr); | |
231 } | |
232 } | |
233 if (needs_card_mark) { | |
234 LIR_Opr ptr = new_pointer_register(); | |
235 __ add(base_opr, LIR_OprFact::intptrConst(offset), ptr); | |
1572 | 236 return new LIR_Address(ptr, type); |
0 | 237 } else { |
238 return new LIR_Address(base_opr, offset, type); | |
239 } | |
240 } | |
241 | |
1783 | 242 LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { |
243 LIR_Opr r; | |
244 if (type == T_LONG) { | |
245 r = LIR_OprFact::longConst(x); | |
246 } else if (type == T_INT) { | |
247 r = LIR_OprFact::intConst(x); | |
248 } else { | |
249 ShouldNotReachHere(); | |
250 } | |
251 if (!Assembler::is_simm13(x)) { | |
252 LIR_Opr tmp = new_register(type); | |
253 __ move(r, tmp); | |
254 return tmp; | |
255 } | |
256 return r; | |
257 } | |
0 | 258 |
1783 | 259 void LIRGenerator::increment_counter(address counter, BasicType type, int step) { |
0 | 260 LIR_Opr pointer = new_pointer_register(); |
261 __ move(LIR_OprFact::intptrConst(counter), pointer); | |
1783 | 262 LIR_Address* addr = new LIR_Address(pointer, type); |
0 | 263 increment_counter(addr, step); |
264 } | |
265 | |
266 void LIRGenerator::increment_counter(LIR_Address* addr, int step) { | |
1783 | 267 LIR_Opr temp = new_register(addr->type()); |
0 | 268 __ move(addr, temp); |
1783 | 269 __ add(temp, load_immediate(step, addr->type()), temp); |
0 | 270 __ move(temp, addr); |
271 } | |
272 | |
273 void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) { | |
274 LIR_Opr o7opr = FrameMap::O7_opr; | |
275 __ load(new LIR_Address(base, disp, T_INT), o7opr, info); | |
276 __ cmp(condition, o7opr, c); | |
277 } | |
278 | |
279 | |
280 void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) { | |
281 LIR_Opr o7opr = FrameMap::O7_opr; | |
282 __ load(new LIR_Address(base, disp, type), o7opr, info); | |
283 __ cmp(condition, reg, o7opr); | |
284 } | |
285 | |
286 | |
287 void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info) { | |
288 LIR_Opr o7opr = FrameMap::O7_opr; | |
289 __ load(new LIR_Address(base, disp, type), o7opr, info); | |
290 __ cmp(condition, reg, o7opr); | |
291 } | |
292 | |
293 | |
294 bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) { | |
295 assert(left != result, "should be different registers"); | |
296 if (is_power_of_2(c + 1)) { | |
297 __ shift_left(left, log2_intptr(c + 1), result); | |
298 __ sub(result, left, result); | |
299 return true; | |
300 } else if (is_power_of_2(c - 1)) { | |
301 __ shift_left(left, log2_intptr(c - 1), result); | |
302 __ add(result, left, result); | |
303 return true; | |
304 } | |
305 return false; | |
306 } | |
307 | |
308 | |
309 void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) { | |
310 BasicType t = item->type(); | |
311 LIR_Opr sp_opr = FrameMap::SP_opr; | |
312 if ((t == T_LONG || t == T_DOUBLE) && | |
313 ((in_bytes(offset_from_sp) - STACK_BIAS) % 8 != 0)) { | |
314 __ unaligned_move(item, new LIR_Address(sp_opr, in_bytes(offset_from_sp), t)); | |
315 } else { | |
316 __ move(item, new LIR_Address(sp_opr, in_bytes(offset_from_sp), t)); | |
317 } | |
318 } | |
319 | |
320 //---------------------------------------------------------------------- | |
321 // visitor functions | |
322 //---------------------------------------------------------------------- | |
323 | |
324 | |
325 void LIRGenerator::do_StoreIndexed(StoreIndexed* x) { | |
1819 | 326 assert(x->is_pinned(),""); |
0 | 327 bool needs_range_check = true; |
328 bool use_length = x->length() != NULL; | |
329 bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT; | |
330 bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL || | |
3957 | 331 !get_jobject_constant(x->value())->is_null_object() || |
332 x->should_profile()); | |
0 | 333 |
334 LIRItem array(x->array(), this); | |
335 LIRItem index(x->index(), this); | |
336 LIRItem value(x->value(), this); | |
337 LIRItem length(this); | |
338 | |
339 array.load_item(); | |
340 index.load_nonconstant(); | |
341 | |
342 if (use_length) { | |
343 needs_range_check = x->compute_needs_range_check(); | |
344 if (needs_range_check) { | |
345 length.set_instruction(x->length()); | |
346 length.load_item(); | |
347 } | |
348 } | |
349 if (needs_store_check) { | |
350 value.load_item(); | |
351 } else { | |
352 value.load_for_store(x->elt_type()); | |
353 } | |
354 | |
355 set_no_result(x); | |
356 | |
357 // the CodeEmitInfo must be duplicated for each different | |
358 // LIR-instruction because spilling can occur anywhere between two | |
359 // instructions and so the debug information must be different | |
360 CodeEmitInfo* range_check_info = state_for(x); | |
361 CodeEmitInfo* null_check_info = NULL; | |
362 if (x->needs_null_check()) { | |
363 null_check_info = new CodeEmitInfo(range_check_info); | |
364 } | |
365 | |
366 // emit array address setup early so it schedules better | |
367 LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store); | |
368 | |
369 if (GenerateRangeChecks && needs_range_check) { | |
370 if (use_length) { | |
371 __ cmp(lir_cond_belowEqual, length.result(), index.result()); | |
372 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); | |
373 } else { | |
374 array_range_check(array.result(), index.result(), null_check_info, range_check_info); | |
375 // range_check also does the null check | |
376 null_check_info = NULL; | |
377 } | |
378 } | |
379 | |
380 if (GenerateArrayStoreCheck && needs_store_check) { | |
381 LIR_Opr tmp1 = FrameMap::G1_opr; | |
382 LIR_Opr tmp2 = FrameMap::G3_opr; | |
383 LIR_Opr tmp3 = FrameMap::G5_opr; | |
384 | |
385 CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info); | |
3957 | 386 __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci()); |
0 | 387 } |
388 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
389 if (obj_store) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
390 // Needs GC write barriers. |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2089
diff
changeset
|
391 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:
2089
diff
changeset
|
392 true /* do_load */, false /* patch */, NULL); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
393 } |
0 | 394 __ move(value.result(), array_addr, null_check_info); |
395 if (obj_store) { | |
819
c6386080541b
6849574: VM crash using NonBlockingHashMap (high_scale_lib)
never
parents:
362
diff
changeset
|
396 // Precise card mark |
0 | 397 post_barrier(LIR_OprFact::address(array_addr), value.result()); |
398 } | |
399 } | |
400 | |
401 | |
402 void LIRGenerator::do_MonitorEnter(MonitorEnter* x) { | |
1819 | 403 assert(x->is_pinned(),""); |
0 | 404 LIRItem obj(x->obj(), this); |
405 obj.load_item(); | |
406 | |
407 set_no_result(x); | |
408 | |
409 LIR_Opr lock = FrameMap::G1_opr; | |
410 LIR_Opr scratch = FrameMap::G3_opr; | |
411 LIR_Opr hdr = FrameMap::G4_opr; | |
412 | |
413 CodeEmitInfo* info_for_exception = NULL; | |
414 if (x->needs_null_check()) { | |
1819 | 415 info_for_exception = state_for(x); |
0 | 416 } |
417 | |
418 // this CodeEmitInfo must not have the xhandlers because here the | |
419 // object is already locked (xhandlers expects object to be unlocked) | |
420 CodeEmitInfo* info = state_for(x, x->state(), true); | |
421 monitor_enter(obj.result(), lock, hdr, scratch, x->monitor_no(), info_for_exception, info); | |
422 } | |
423 | |
424 | |
425 void LIRGenerator::do_MonitorExit(MonitorExit* x) { | |
1819 | 426 assert(x->is_pinned(),""); |
0 | 427 LIRItem obj(x->obj(), this); |
428 obj.dont_load_item(); | |
429 | |
430 set_no_result(x); | |
431 LIR_Opr lock = FrameMap::G1_opr; | |
432 LIR_Opr hdr = FrameMap::G3_opr; | |
433 LIR_Opr obj_temp = FrameMap::G4_opr; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
434 monitor_exit(obj_temp, lock, hdr, LIR_OprFact::illegalOpr, x->monitor_no()); |
0 | 435 } |
436 | |
437 | |
438 // _ineg, _lneg, _fneg, _dneg | |
439 void LIRGenerator::do_NegateOp(NegateOp* x) { | |
440 LIRItem value(x->x(), this); | |
441 value.load_item(); | |
442 LIR_Opr reg = rlock_result(x); | |
443 __ negate(value.result(), reg); | |
444 } | |
445 | |
446 | |
447 | |
448 // for _fadd, _fmul, _fsub, _fdiv, _frem | |
449 // _dadd, _dmul, _dsub, _ddiv, _drem | |
450 void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { | |
451 switch (x->op()) { | |
452 case Bytecodes::_fadd: | |
453 case Bytecodes::_fmul: | |
454 case Bytecodes::_fsub: | |
455 case Bytecodes::_fdiv: | |
456 case Bytecodes::_dadd: | |
457 case Bytecodes::_dmul: | |
458 case Bytecodes::_dsub: | |
459 case Bytecodes::_ddiv: { | |
460 LIRItem left(x->x(), this); | |
461 LIRItem right(x->y(), this); | |
462 left.load_item(); | |
463 right.load_item(); | |
464 rlock_result(x); | |
465 arithmetic_op_fpu(x->op(), x->operand(), left.result(), right.result(), x->is_strictfp()); | |
466 } | |
467 break; | |
468 | |
469 case Bytecodes::_frem: | |
470 case Bytecodes::_drem: { | |
471 address entry; | |
472 switch (x->op()) { | |
473 case Bytecodes::_frem: | |
474 entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem); | |
475 break; | |
476 case Bytecodes::_drem: | |
477 entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem); | |
478 break; | |
479 default: | |
480 ShouldNotReachHere(); | |
481 } | |
482 LIR_Opr result = call_runtime(x->x(), x->y(), entry, x->type(), NULL); | |
483 set_result(x, result); | |
484 } | |
485 break; | |
486 | |
487 default: ShouldNotReachHere(); | |
488 } | |
489 } | |
490 | |
491 | |
492 // for _ladd, _lmul, _lsub, _ldiv, _lrem | |
493 void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { | |
494 switch (x->op()) { | |
495 case Bytecodes::_lrem: | |
496 case Bytecodes::_lmul: | |
497 case Bytecodes::_ldiv: { | |
498 | |
499 if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) { | |
500 LIRItem right(x->y(), this); | |
501 right.load_item(); | |
502 | |
503 CodeEmitInfo* info = state_for(x); | |
504 LIR_Opr item = right.result(); | |
505 assert(item->is_register(), "must be"); | |
506 __ cmp(lir_cond_equal, item, LIR_OprFact::longConst(0)); | |
507 __ branch(lir_cond_equal, T_LONG, new DivByZeroStub(info)); | |
508 } | |
509 | |
510 address entry; | |
511 switch (x->op()) { | |
512 case Bytecodes::_lrem: | |
513 entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem); | |
514 break; // check if dividend is 0 is done elsewhere | |
515 case Bytecodes::_ldiv: | |
516 entry = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv); | |
517 break; // check if dividend is 0 is done elsewhere | |
518 case Bytecodes::_lmul: | |
519 entry = CAST_FROM_FN_PTR(address, SharedRuntime::lmul); | |
520 break; | |
521 default: | |
522 ShouldNotReachHere(); | |
523 } | |
524 | |
525 // order of arguments to runtime call is reversed. | |
526 LIR_Opr result = call_runtime(x->y(), x->x(), entry, x->type(), NULL); | |
527 set_result(x, result); | |
528 break; | |
529 } | |
530 case Bytecodes::_ladd: | |
531 case Bytecodes::_lsub: { | |
532 LIRItem left(x->x(), this); | |
533 LIRItem right(x->y(), this); | |
534 left.load_item(); | |
535 right.load_item(); | |
536 rlock_result(x); | |
537 | |
538 arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL); | |
539 break; | |
540 } | |
541 default: ShouldNotReachHere(); | |
542 } | |
543 } | |
544 | |
545 | |
546 // Returns if item is an int constant that can be represented by a simm13 | |
547 static bool is_simm13(LIR_Opr item) { | |
548 if (item->is_constant() && item->type() == T_INT) { | |
549 return Assembler::is_simm13(item->as_constant_ptr()->as_jint()); | |
550 } else { | |
551 return false; | |
552 } | |
553 } | |
554 | |
555 | |
556 // for: _iadd, _imul, _isub, _idiv, _irem | |
557 void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) { | |
558 bool is_div_rem = x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem; | |
559 LIRItem left(x->x(), this); | |
560 LIRItem right(x->y(), this); | |
561 // missing test if instr is commutative and if we should swap | |
562 right.load_nonconstant(); | |
563 assert(right.is_constant() || right.is_register(), "wrong state of right"); | |
564 left.load_item(); | |
565 rlock_result(x); | |
566 if (is_div_rem) { | |
567 CodeEmitInfo* info = state_for(x); | |
568 LIR_Opr tmp = FrameMap::G1_opr; | |
569 if (x->op() == Bytecodes::_irem) { | |
570 __ irem(left.result(), right.result(), x->operand(), tmp, info); | |
571 } else if (x->op() == Bytecodes::_idiv) { | |
572 __ idiv(left.result(), right.result(), x->operand(), tmp, info); | |
573 } | |
574 } else { | |
575 arithmetic_op_int(x->op(), x->operand(), left.result(), right.result(), FrameMap::G1_opr); | |
576 } | |
577 } | |
578 | |
579 | |
580 void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) { | |
581 ValueTag tag = x->type()->tag(); | |
582 assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters"); | |
583 switch (tag) { | |
584 case floatTag: | |
585 case doubleTag: do_ArithmeticOp_FPU(x); return; | |
586 case longTag: do_ArithmeticOp_Long(x); return; | |
587 case intTag: do_ArithmeticOp_Int(x); return; | |
588 } | |
589 ShouldNotReachHere(); | |
590 } | |
591 | |
592 | |
593 // _ishl, _lshl, _ishr, _lshr, _iushr, _lushr | |
594 void LIRGenerator::do_ShiftOp(ShiftOp* x) { | |
595 LIRItem value(x->x(), this); | |
596 LIRItem count(x->y(), this); | |
597 // Long shift destroys count register | |
598 if (value.type()->is_long()) { | |
599 count.set_destroys_register(); | |
600 } | |
601 value.load_item(); | |
602 // the old backend doesn't support this | |
603 if (count.is_constant() && count.type()->as_IntConstant() != NULL && value.type()->is_int()) { | |
604 jint c = count.get_jint_constant() & 0x1f; | |
605 assert(c >= 0 && c < 32, "should be small"); | |
606 count.dont_load_item(); | |
607 } else { | |
608 count.load_item(); | |
609 } | |
610 LIR_Opr reg = rlock_result(x); | |
611 shift_op(x->op(), reg, value.result(), count.result(), LIR_OprFact::illegalOpr); | |
612 } | |
613 | |
614 | |
615 // _iand, _land, _ior, _lor, _ixor, _lxor | |
616 void LIRGenerator::do_LogicOp(LogicOp* x) { | |
617 LIRItem left(x->x(), this); | |
618 LIRItem right(x->y(), this); | |
619 | |
620 left.load_item(); | |
621 right.load_nonconstant(); | |
622 LIR_Opr reg = rlock_result(x); | |
623 | |
624 logic_op(x->op(), reg, left.result(), right.result()); | |
625 } | |
626 | |
627 | |
628 | |
629 // _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg | |
630 void LIRGenerator::do_CompareOp(CompareOp* x) { | |
631 LIRItem left(x->x(), this); | |
632 LIRItem right(x->y(), this); | |
633 left.load_item(); | |
634 right.load_item(); | |
635 LIR_Opr reg = rlock_result(x); | |
636 if (x->x()->type()->is_float_kind()) { | |
637 Bytecodes::Code code = x->op(); | |
638 __ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl)); | |
639 } else if (x->x()->type()->tag() == longTag) { | |
640 __ lcmp2int(left.result(), right.result(), reg); | |
641 } else { | |
642 Unimplemented(); | |
643 } | |
644 } | |
645 | |
646 | |
647 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { | |
648 assert(x->number_of_arguments() == 4, "wrong type"); | |
649 LIRItem obj (x->argument_at(0), this); // object | |
650 LIRItem offset(x->argument_at(1), this); // offset of field | |
651 LIRItem cmp (x->argument_at(2), this); // value to compare with field | |
652 LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp | |
653 | |
654 // Use temps to avoid kills | |
655 LIR_Opr t1 = FrameMap::G1_opr; | |
656 LIR_Opr t2 = FrameMap::G3_opr; | |
1873 | 657 LIR_Opr addr = new_pointer_register(); |
0 | 658 |
659 // get address of field | |
660 obj.load_item(); | |
661 offset.load_item(); | |
662 cmp.load_item(); | |
663 val.load_item(); | |
664 | |
665 __ add(obj.result(), offset.result(), addr); | |
666 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
667 if (type == objectType) { // Write-barrier needed for Object fields. |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2089
diff
changeset
|
668 pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2089
diff
changeset
|
669 true /* do_load */, false /* patch */, NULL); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
670 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
671 |
0 | 672 if (type == objectType) |
673 __ cas_obj(addr, cmp.result(), val.result(), t1, t2); | |
674 else if (type == intType) | |
675 __ cas_int(addr, cmp.result(), val.result(), t1, t2); | |
676 else if (type == longType) | |
677 __ cas_long(addr, cmp.result(), val.result(), t1, t2); | |
678 else { | |
679 ShouldNotReachHere(); | |
680 } | |
681 // generate conditional move of boolean result | |
682 LIR_Opr result = rlock_result(x); | |
2089
037c727f35fb
7009231: C1: Incorrect CAS code for longs on SPARC 32bit
iveresov
parents:
1972
diff
changeset
|
683 __ 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:
1972
diff
changeset
|
684 result, as_BasicType(type)); |
0 | 685 if (type == objectType) { // Write-barrier needed for Object fields. |
819
c6386080541b
6849574: VM crash using NonBlockingHashMap (high_scale_lib)
never
parents:
362
diff
changeset
|
686 // Precise card mark since could either be object or array |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
687 post_barrier(addr, val.result()); |
0 | 688 } |
689 } | |
690 | |
691 | |
692 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { | |
693 switch (x->id()) { | |
694 case vmIntrinsics::_dabs: | |
695 case vmIntrinsics::_dsqrt: { | |
696 assert(x->number_of_arguments() == 1, "wrong type"); | |
697 LIRItem value(x->argument_at(0), this); | |
698 value.load_item(); | |
699 LIR_Opr dst = rlock_result(x); | |
700 | |
701 switch (x->id()) { | |
702 case vmIntrinsics::_dsqrt: { | |
703 __ sqrt(value.result(), dst, LIR_OprFact::illegalOpr); | |
704 break; | |
705 } | |
706 case vmIntrinsics::_dabs: { | |
707 __ abs(value.result(), dst, LIR_OprFact::illegalOpr); | |
708 break; | |
709 } | |
710 } | |
711 break; | |
712 } | |
713 case vmIntrinsics::_dlog10: // fall through | |
714 case vmIntrinsics::_dlog: // fall through | |
715 case vmIntrinsics::_dsin: // fall through | |
716 case vmIntrinsics::_dtan: // fall through | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
717 case vmIntrinsics::_dcos: // fall through |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
718 case vmIntrinsics::_dexp: { |
0 | 719 assert(x->number_of_arguments() == 1, "wrong type"); |
720 | |
721 address runtime_entry = NULL; | |
722 switch (x->id()) { | |
723 case vmIntrinsics::_dsin: | |
724 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); | |
725 break; | |
726 case vmIntrinsics::_dcos: | |
727 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); | |
728 break; | |
729 case vmIntrinsics::_dtan: | |
730 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); | |
731 break; | |
732 case vmIntrinsics::_dlog: | |
733 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); | |
734 break; | |
735 case vmIntrinsics::_dlog10: | |
736 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); | |
737 break; | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
738 case vmIntrinsics::_dexp: |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
739 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
740 break; |
0 | 741 default: |
742 ShouldNotReachHere(); | |
743 } | |
744 | |
745 LIR_Opr result = call_runtime(x->argument_at(0), runtime_entry, x->type(), NULL); | |
746 set_result(x, result); | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
747 break; |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
748 } |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
749 case vmIntrinsics::_dpow: { |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
750 assert(x->number_of_arguments() == 2, "wrong type"); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
751 address runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
752 LIR_Opr result = call_runtime(x->argument_at(0), x->argument_at(1), runtime_entry, x->type(), NULL); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
753 set_result(x, result); |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
3957
diff
changeset
|
754 break; |
0 | 755 } |
756 } | |
757 } | |
758 | |
759 | |
760 void LIRGenerator::do_ArrayCopy(Intrinsic* x) { | |
761 assert(x->number_of_arguments() == 5, "wrong type"); | |
928
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
762 |
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
763 // Make all state_for calls early since they can emit code |
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
764 CodeEmitInfo* info = state_for(x, x->state()); |
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
765 |
0 | 766 // Note: spill caller save before setting the item |
767 LIRItem src (x->argument_at(0), this); | |
768 LIRItem src_pos (x->argument_at(1), this); | |
769 LIRItem dst (x->argument_at(2), this); | |
770 LIRItem dst_pos (x->argument_at(3), this); | |
771 LIRItem length (x->argument_at(4), this); | |
772 // load all values in callee_save_registers, as this makes the | |
773 // parameter passing to the fast case simpler | |
774 src.load_item_force (rlock_callee_saved(T_OBJECT)); | |
775 src_pos.load_item_force (rlock_callee_saved(T_INT)); | |
776 dst.load_item_force (rlock_callee_saved(T_OBJECT)); | |
777 dst_pos.load_item_force (rlock_callee_saved(T_INT)); | |
778 length.load_item_force (rlock_callee_saved(T_INT)); | |
779 | |
780 int flags; | |
781 ciArrayKlass* expected_type; | |
782 arraycopy_helper(x, &flags, &expected_type); | |
783 | |
784 __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), | |
785 length.result(), rlock_callee_saved(T_INT), | |
786 expected_type, flags, info); | |
787 set_no_result(x); | |
788 } | |
789 | |
790 // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f | |
791 // _i2b, _i2c, _i2s | |
792 void LIRGenerator::do_Convert(Convert* x) { | |
793 | |
794 switch (x->op()) { | |
795 case Bytecodes::_f2l: | |
796 case Bytecodes::_d2l: | |
797 case Bytecodes::_d2i: | |
798 case Bytecodes::_l2f: | |
799 case Bytecodes::_l2d: { | |
800 | |
801 address entry; | |
802 switch (x->op()) { | |
803 case Bytecodes::_l2f: | |
804 entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2f); | |
805 break; | |
806 case Bytecodes::_l2d: | |
807 entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2d); | |
808 break; | |
809 case Bytecodes::_f2l: | |
810 entry = CAST_FROM_FN_PTR(address, SharedRuntime::f2l); | |
811 break; | |
812 case Bytecodes::_d2l: | |
813 entry = CAST_FROM_FN_PTR(address, SharedRuntime::d2l); | |
814 break; | |
815 case Bytecodes::_d2i: | |
816 entry = CAST_FROM_FN_PTR(address, SharedRuntime::d2i); | |
817 break; | |
818 default: | |
819 ShouldNotReachHere(); | |
820 } | |
821 LIR_Opr result = call_runtime(x->value(), entry, x->type(), NULL); | |
822 set_result(x, result); | |
823 break; | |
824 } | |
825 | |
826 case Bytecodes::_i2f: | |
827 case Bytecodes::_i2d: { | |
828 LIRItem value(x->value(), this); | |
829 | |
830 LIR_Opr reg = rlock_result(x); | |
831 // To convert an int to double, we need to load the 32-bit int | |
832 // from memory into a single precision floating point register | |
833 // (even numbered). Then the sparc fitod instruction takes care | |
834 // of the conversion. This is a bit ugly, but is the best way to | |
835 // get the int value in a single precision floating point register | |
836 value.load_item(); | |
837 LIR_Opr tmp = force_to_spill(value.result(), T_FLOAT); | |
838 __ convert(x->op(), tmp, reg); | |
839 break; | |
840 } | |
841 break; | |
842 | |
843 case Bytecodes::_i2l: | |
844 case Bytecodes::_i2b: | |
845 case Bytecodes::_i2c: | |
846 case Bytecodes::_i2s: | |
847 case Bytecodes::_l2i: | |
848 case Bytecodes::_f2d: | |
849 case Bytecodes::_d2f: { // inline code | |
850 LIRItem value(x->value(), this); | |
851 | |
852 value.load_item(); | |
853 LIR_Opr reg = rlock_result(x); | |
854 __ convert(x->op(), value.result(), reg, false); | |
855 } | |
856 break; | |
857 | |
858 case Bytecodes::_f2i: { | |
859 LIRItem value (x->value(), this); | |
860 value.set_destroys_register(); | |
861 value.load_item(); | |
862 LIR_Opr reg = rlock_result(x); | |
863 set_vreg_flag(reg, must_start_in_memory); | |
864 __ convert(x->op(), value.result(), reg, false); | |
865 } | |
866 break; | |
867 | |
868 default: ShouldNotReachHere(); | |
869 } | |
870 } | |
871 | |
872 | |
873 void LIRGenerator::do_NewInstance(NewInstance* x) { | |
874 // This instruction can be deoptimized in the slow path : use | |
875 // O0 as result register. | |
876 const LIR_Opr reg = result_register_for(x->type()); | |
1819 | 877 #ifndef PRODUCT |
0 | 878 if (PrintNotLoaded && !x->klass()->is_loaded()) { |
1819 | 879 tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci()); |
0 | 880 } |
1819 | 881 #endif |
0 | 882 CodeEmitInfo* info = state_for(x, x->state()); |
883 LIR_Opr tmp1 = FrameMap::G1_oop_opr; | |
884 LIR_Opr tmp2 = FrameMap::G3_oop_opr; | |
885 LIR_Opr tmp3 = FrameMap::G4_oop_opr; | |
886 LIR_Opr tmp4 = FrameMap::O1_oop_opr; | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
887 LIR_Opr klass_reg = FrameMap::G5_metadata_opr; |
0 | 888 new_instance(reg, x->klass(), tmp1, tmp2, tmp3, tmp4, klass_reg, info); |
889 LIR_Opr result = rlock_result(x); | |
890 __ move(reg, result); | |
891 } | |
892 | |
893 | |
894 void LIRGenerator::do_NewTypeArray(NewTypeArray* x) { | |
928
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
895 // Evaluate state_for early since it may emit code |
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
896 CodeEmitInfo* info = state_for(x, x->state()); |
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
897 |
0 | 898 LIRItem length(x->length(), this); |
899 length.load_item(); | |
900 | |
901 LIR_Opr reg = result_register_for(x->type()); | |
902 LIR_Opr tmp1 = FrameMap::G1_oop_opr; | |
903 LIR_Opr tmp2 = FrameMap::G3_oop_opr; | |
904 LIR_Opr tmp3 = FrameMap::G4_oop_opr; | |
905 LIR_Opr tmp4 = FrameMap::O1_oop_opr; | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
906 LIR_Opr klass_reg = FrameMap::G5_metadata_opr; |
0 | 907 LIR_Opr len = length.result(); |
908 BasicType elem_type = x->elt_type(); | |
909 | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
910 __ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg); |
0 | 911 |
912 CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info); | |
913 __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path); | |
914 | |
915 LIR_Opr result = rlock_result(x); | |
916 __ move(reg, result); | |
917 } | |
918 | |
919 | |
920 void LIRGenerator::do_NewObjectArray(NewObjectArray* x) { | |
928
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
921 // Evaluate state_for early since it may emit code. |
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
922 CodeEmitInfo* info = state_for(x, x->state()); |
0 | 923 // in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction |
924 // and therefore provide the state before the parameters have been consumed | |
925 CodeEmitInfo* patching_info = NULL; | |
926 if (!x->klass()->is_loaded() || PatchALot) { | |
927 patching_info = state_for(x, x->state_before()); | |
928 } | |
929 | |
928
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
930 LIRItem length(x->length(), this); |
0 | 931 length.load_item(); |
932 | |
933 const LIR_Opr reg = result_register_for(x->type()); | |
934 LIR_Opr tmp1 = FrameMap::G1_oop_opr; | |
935 LIR_Opr tmp2 = FrameMap::G3_oop_opr; | |
936 LIR_Opr tmp3 = FrameMap::G4_oop_opr; | |
937 LIR_Opr tmp4 = FrameMap::O1_oop_opr; | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
938 LIR_Opr klass_reg = FrameMap::G5_metadata_opr; |
0 | 939 LIR_Opr len = length.result(); |
940 | |
941 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
|
942 ciMetadata* obj = ciObjArrayKlass::make(x->klass()); |
0 | 943 if (obj == ciEnv::unloaded_ciobjarrayklass()) { |
944 BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error"); | |
945 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6145
diff
changeset
|
946 klass2reg_with_patching(klass_reg, obj, patching_info); |
0 | 947 __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path); |
948 | |
949 LIR_Opr result = rlock_result(x); | |
950 __ move(reg, result); | |
951 } | |
952 | |
953 | |
954 void LIRGenerator::do_NewMultiArray(NewMultiArray* x) { | |
955 Values* dims = x->dims(); | |
956 int i = dims->length(); | |
957 LIRItemList* items = new LIRItemList(dims->length(), NULL); | |
958 while (i-- > 0) { | |
959 LIRItem* size = new LIRItem(dims->at(i), this); | |
960 items->at_put(i, size); | |
961 } | |
962 | |
928
d0acbc302e14
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
never
parents:
844
diff
changeset
|
963 // Evaluate state_for early since it may emit code. |
0 | 964 CodeEmitInfo* patching_info = NULL; |
965 if (!x->klass()->is_loaded() || PatchALot) { | |
966 patching_info = state_for(x, x->state_before()); | |
967 | |
6145
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
6143
diff
changeset
|
968 // 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
|
969 // 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
|
970 // 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
|
971 // is done explicitly here because a stub isn't being used). |
0 | 972 x->set_exception_handlers(new XHandlers(x->exception_handlers())); |
973 } | |
933
cdb8b7c37ac1
6875329: fix for 6795465 broke exception handler cloning
never
parents:
928
diff
changeset
|
974 CodeEmitInfo* info = state_for(x, x->state()); |
0 | 975 |
976 i = dims->length(); | |
977 while (i-- > 0) { | |
978 LIRItem* size = items->at(i); | |
979 size->load_item(); | |
980 store_stack_parameter (size->result(), | |
981 in_ByteSize(STACK_BIAS + | |
304 | 982 frame::memory_parameter_word_sp_offset * wordSize + |
983 i * sizeof(jint))); | |
0 | 984 } |
985 | |
986 // This instruction can be deoptimized in the slow path : use | |
987 // O0 as result register. | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
988 const LIR_Opr klass_reg = FrameMap::O0_metadata_opr; |
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
989 klass2reg_with_patching(klass_reg, x->klass(), patching_info); |
0 | 990 LIR_Opr rank = FrameMap::O1_opr; |
991 __ move(LIR_OprFact::intConst(x->rank()), rank); | |
992 LIR_Opr varargs = FrameMap::as_pointer_opr(O2); | |
993 int offset_from_sp = (frame::memory_parameter_word_sp_offset * wordSize) + STACK_BIAS; | |
994 __ add(FrameMap::SP_opr, | |
995 LIR_OprFact::intptrConst(offset_from_sp), | |
996 varargs); | |
997 LIR_OprList* args = new LIR_OprList(3); | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
998 args->append(klass_reg); |
0 | 999 args->append(rank); |
1000 args->append(varargs); | |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6725
diff
changeset
|
1001 const LIR_Opr reg = result_register_for(x->type()); |
0 | 1002 __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id), |
1003 LIR_OprFact::illegalOpr, | |
1004 reg, args, info); | |
1005 | |
1006 LIR_Opr result = rlock_result(x); | |
1007 __ move(reg, result); | |
1008 } | |
1009 | |
1010 | |
1011 void LIRGenerator::do_BlockBegin(BlockBegin* x) { | |
1012 } | |
1013 | |
1014 | |
1015 void LIRGenerator::do_CheckCast(CheckCast* x) { | |
1016 LIRItem obj(x->obj(), this); | |
1017 CodeEmitInfo* patching_info = NULL; | |
1018 if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check())) { | |
1019 // must do this before locking the destination register as an oop register, | |
1020 // and before the obj is loaded (so x->obj()->item() is valid for creating a debug info location) | |
1021 patching_info = state_for(x, x->state_before()); | |
1022 } | |
1023 obj.load_item(); | |
1024 LIR_Opr out_reg = rlock_result(x); | |
1025 CodeStub* stub; | |
1819 | 1026 CodeEmitInfo* info_for_exception = state_for(x); |
0 | 1027 |
1028 if (x->is_incompatible_class_change_check()) { | |
1029 assert(patching_info == NULL, "can't patch this"); | |
1030 stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception); | |
1031 } else { | |
1032 stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); | |
1033 } | |
1034 LIR_Opr tmp1 = FrameMap::G1_oop_opr; | |
1035 LIR_Opr tmp2 = FrameMap::G3_oop_opr; | |
1036 LIR_Opr tmp3 = FrameMap::G4_oop_opr; | |
1037 __ checkcast(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3, | |
1038 x->direct_compare(), info_for_exception, patching_info, stub, | |
1039 x->profiled_method(), x->profiled_bci()); | |
1040 } | |
1041 | |
1042 | |
1043 void LIRGenerator::do_InstanceOf(InstanceOf* x) { | |
1044 LIRItem obj(x->obj(), this); | |
1045 CodeEmitInfo* patching_info = NULL; | |
1046 if (!x->klass()->is_loaded() || PatchALot) { | |
1047 patching_info = state_for(x, x->state_before()); | |
1048 } | |
1049 // ensure the result register is not the input register because the result is initialized before the patching safepoint | |
1050 obj.load_item(); | |
1051 LIR_Opr out_reg = rlock_result(x); | |
1052 LIR_Opr tmp1 = FrameMap::G1_oop_opr; | |
1053 LIR_Opr tmp2 = FrameMap::G3_oop_opr; | |
1054 LIR_Opr tmp3 = FrameMap::G4_oop_opr; | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1055 __ instanceof(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3, |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1056 x->direct_compare(), patching_info, |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1057 x->profiled_method(), x->profiled_bci()); |
0 | 1058 } |
1059 | |
1060 | |
1061 void LIRGenerator::do_If(If* x) { | |
1062 assert(x->number_of_sux() == 2, "inconsistency"); | |
1063 ValueTag tag = x->x()->type()->tag(); | |
1064 LIRItem xitem(x->x(), this); | |
1065 LIRItem yitem(x->y(), this); | |
1066 LIRItem* xin = &xitem; | |
1067 LIRItem* yin = &yitem; | |
1068 If::Condition cond = x->cond(); | |
1069 | |
1070 if (tag == longTag) { | |
1071 // for longs, only conditions "eql", "neq", "lss", "geq" are valid; | |
1072 // mirror for other conditions | |
1073 if (cond == If::gtr || cond == If::leq) { | |
1074 // swap inputs | |
1075 cond = Instruction::mirror(cond); | |
1076 xin = &yitem; | |
1077 yin = &xitem; | |
1078 } | |
1079 xin->set_destroys_register(); | |
1080 } | |
1081 | |
1082 LIR_Opr left = LIR_OprFact::illegalOpr; | |
1083 LIR_Opr right = LIR_OprFact::illegalOpr; | |
1084 | |
1085 xin->load_item(); | |
1086 left = xin->result(); | |
1087 | |
1088 if (is_simm13(yin->result())) { | |
1089 // inline int constants which are small enough to be immediate operands | |
1090 right = LIR_OprFact::value_type(yin->value()->type()); | |
1091 } else if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && | |
1092 (cond == If::eql || cond == If::neq)) { | |
1093 // inline long zero | |
1094 right = LIR_OprFact::value_type(yin->value()->type()); | |
1095 } else if (tag == objectTag && yin->is_constant() && (yin->get_jobject_constant()->is_null_object())) { | |
1096 right = LIR_OprFact::value_type(yin->value()->type()); | |
1097 } else { | |
1098 yin->load_item(); | |
1099 right = yin->result(); | |
1100 } | |
1101 set_no_result(x); | |
1102 | |
1103 // add safepoint before generating condition code so it can be recomputed | |
1104 if (x->is_safepoint()) { | |
1105 // increment backedge counter if needed | |
1783 | 1106 increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci()); |
0 | 1107 __ safepoint(new_register(T_INT), state_for(x, x->state_before())); |
1108 } | |
1109 | |
1110 __ cmp(lir_cond(cond), left, right); | |
1783 | 1111 // Generate branch profiling. Profiling code doesn't kill flags. |
0 | 1112 profile_branch(x, cond); |
1113 move_to_phi(x->state()); | |
1114 if (x->x()->type()->is_float_kind()) { | |
1115 __ branch(lir_cond(cond), right->type(), x->tsux(), x->usux()); | |
1116 } else { | |
1117 __ branch(lir_cond(cond), right->type(), x->tsux()); | |
1118 } | |
1119 assert(x->default_sux() == x->fsux(), "wrong destination above"); | |
1120 __ jump(x->default_sux()); | |
1121 } | |
1122 | |
1123 | |
1124 LIR_Opr LIRGenerator::getThreadPointer() { | |
1125 return FrameMap::as_pointer_opr(G2); | |
1126 } | |
1127 | |
1128 | |
1129 void LIRGenerator::trace_block_entry(BlockBegin* block) { | |
1130 __ move(LIR_OprFact::intConst(block->block_id()), FrameMap::O0_opr); | |
1131 LIR_OprList* args = new LIR_OprList(1); | |
1132 args->append(FrameMap::O0_opr); | |
1133 address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry); | |
1134 __ call_runtime_leaf(func, rlock_callee_saved(T_INT), LIR_OprFact::illegalOpr, args); | |
1135 } | |
1136 | |
1137 | |
1138 void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address, | |
1139 CodeEmitInfo* info) { | |
1140 #ifdef _LP64 | |
1141 __ store(value, address, info); | |
1142 #else | |
1143 __ volatile_store_mem_reg(value, address, info); | |
1144 #endif | |
1145 } | |
1146 | |
1147 void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result, | |
1148 CodeEmitInfo* info) { | |
1149 #ifdef _LP64 | |
1150 __ load(address, result, info); | |
1151 #else | |
1152 __ volatile_load_mem_reg(address, result, info); | |
1153 #endif | |
1154 } | |
1155 | |
1156 | |
1157 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, | |
1158 BasicType type, bool is_volatile) { | |
1159 LIR_Opr base_op = src; | |
1160 LIR_Opr index_op = offset; | |
1161 | |
1162 bool is_obj = (type == T_ARRAY || type == T_OBJECT); | |
1163 #ifndef _LP64 | |
1164 if (is_volatile && type == T_LONG) { | |
1165 __ volatile_store_unsafe_reg(data, src, offset, type, NULL, lir_patch_none); | |
1166 } else | |
1167 #endif | |
1168 { | |
1169 if (type == T_BOOLEAN) { | |
1170 type = T_BYTE; | |
1171 } | |
1172 LIR_Address* addr; | |
1173 if (type == T_ARRAY || type == T_OBJECT) { | |
1174 LIR_Opr tmp = new_pointer_register(); | |
1175 __ add(base_op, index_op, tmp); | |
1572 | 1176 addr = new LIR_Address(tmp, type); |
0 | 1177 } else { |
1178 addr = new LIR_Address(base_op, index_op, type); | |
1179 } | |
1180 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
1181 if (is_obj) { |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2089
diff
changeset
|
1182 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:
2089
diff
changeset
|
1183 true /* do_load */, false /* patch */, NULL); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
1184 // _bs->c1_write_barrier_pre(this, LIR_OprFact::address(addr)); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
1185 } |
0 | 1186 __ move(data, addr); |
1187 if (is_obj) { | |
1188 // This address is precise | |
1189 post_barrier(LIR_OprFact::address(addr), data); | |
1190 } | |
1191 } | |
1192 } | |
1193 | |
1194 | |
1195 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset, | |
1196 BasicType type, bool is_volatile) { | |
1197 #ifndef _LP64 | |
1198 if (is_volatile && type == T_LONG) { | |
1199 __ volatile_load_unsafe_reg(src, offset, dst, type, NULL, lir_patch_none); | |
1200 } else | |
1201 #endif | |
1202 { | |
1203 LIR_Address* addr = new LIR_Address(src, offset, type); | |
1204 __ load(addr, dst); | |
1205 } | |
1206 } |