Mercurial > hg > truffle
annotate src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @ 2007:5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Thu, 02 Dec 2010 17:21:12 -0800 |
parents | ac637b7220d1 |
children | 7601ab0e1e33 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
diff
changeset
|
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
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:
1378
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_Compilation.hpp" | |
27 #include "c1/c1_LIRAssembler.hpp" | |
28 #include "c1/c1_MacroAssembler.hpp" | |
29 #include "c1/c1_Runtime1.hpp" | |
30 #include "c1/c1_ValueStack.hpp" | |
31 #include "ci/ciArrayKlass.hpp" | |
32 #include "ci/ciInstance.hpp" | |
33 #include "gc_interface/collectedHeap.hpp" | |
34 #include "memory/barrierSet.hpp" | |
35 #include "memory/cardTableModRefBS.hpp" | |
36 #include "nativeInst_sparc.hpp" | |
37 #include "oops/objArrayKlass.hpp" | |
38 #include "runtime/sharedRuntime.hpp" | |
0 | 39 |
40 #define __ _masm-> | |
41 | |
42 | |
43 //------------------------------------------------------------ | |
44 | |
45 | |
46 bool LIR_Assembler::is_small_constant(LIR_Opr opr) { | |
47 if (opr->is_constant()) { | |
48 LIR_Const* constant = opr->as_constant_ptr(); | |
49 switch (constant->type()) { | |
50 case T_INT: { | |
51 jint value = constant->as_jint(); | |
52 return Assembler::is_simm13(value); | |
53 } | |
54 | |
55 default: | |
56 return false; | |
57 } | |
58 } | |
59 return false; | |
60 } | |
61 | |
62 | |
63 bool LIR_Assembler::is_single_instruction(LIR_Op* op) { | |
64 switch (op->code()) { | |
65 case lir_null_check: | |
66 return true; | |
67 | |
68 | |
69 case lir_add: | |
70 case lir_ushr: | |
71 case lir_shr: | |
72 case lir_shl: | |
73 // integer shifts and adds are always one instruction | |
74 return op->result_opr()->is_single_cpu(); | |
75 | |
76 | |
77 case lir_move: { | |
78 LIR_Op1* op1 = op->as_Op1(); | |
79 LIR_Opr src = op1->in_opr(); | |
80 LIR_Opr dst = op1->result_opr(); | |
81 | |
82 if (src == dst) { | |
83 NEEDS_CLEANUP; | |
84 // this works around a problem where moves with the same src and dst | |
85 // end up in the delay slot and then the assembler swallows the mov | |
86 // since it has no effect and then it complains because the delay slot | |
87 // is empty. returning false stops the optimizer from putting this in | |
88 // the delay slot | |
89 return false; | |
90 } | |
91 | |
92 // don't put moves involving oops into the delay slot since the VerifyOops code | |
93 // will make it much larger than a single instruction. | |
94 if (VerifyOops) { | |
95 return false; | |
96 } | |
97 | |
98 if (src->is_double_cpu() || dst->is_double_cpu() || op1->patch_code() != lir_patch_none || | |
99 ((src->is_double_fpu() || dst->is_double_fpu()) && op1->move_kind() != lir_move_normal)) { | |
100 return false; | |
101 } | |
102 | |
2002 | 103 if (UseCompressedOops) { |
104 if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false; | |
105 if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false; | |
106 } | |
107 | |
0 | 108 if (dst->is_register()) { |
109 if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) { | |
110 return !PatchALot; | |
111 } else if (src->is_single_stack()) { | |
112 return true; | |
113 } | |
114 } | |
115 | |
116 if (src->is_register()) { | |
117 if (dst->is_address() && Assembler::is_simm13(dst->as_address_ptr()->disp())) { | |
118 return !PatchALot; | |
119 } else if (dst->is_single_stack()) { | |
120 return true; | |
121 } | |
122 } | |
123 | |
124 if (dst->is_register() && | |
125 ((src->is_register() && src->is_single_word() && src->is_same_type(dst)) || | |
126 (src->is_constant() && LIR_Assembler::is_small_constant(op->as_Op1()->in_opr())))) { | |
127 return true; | |
128 } | |
129 | |
130 return false; | |
131 } | |
132 | |
133 default: | |
134 return false; | |
135 } | |
136 ShouldNotReachHere(); | |
137 } | |
138 | |
139 | |
140 LIR_Opr LIR_Assembler::receiverOpr() { | |
141 return FrameMap::O0_oop_opr; | |
142 } | |
143 | |
144 | |
145 LIR_Opr LIR_Assembler::incomingReceiverOpr() { | |
146 return FrameMap::I0_oop_opr; | |
147 } | |
148 | |
149 | |
150 LIR_Opr LIR_Assembler::osrBufferPointer() { | |
151 return FrameMap::I0_opr; | |
152 } | |
153 | |
154 | |
155 int LIR_Assembler::initial_frame_size_in_bytes() { | |
156 return in_bytes(frame_map()->framesize_in_bytes()); | |
157 } | |
158 | |
159 | |
160 // inline cache check: the inline cached class is in G5_inline_cache_reg(G5); | |
161 // we fetch the class of the receiver (O0) and compare it with the cached class. | |
162 // If they do not match we jump to slow case. | |
163 int LIR_Assembler::check_icache() { | |
164 int offset = __ offset(); | |
165 __ inline_cache_check(O0, G5_inline_cache_reg); | |
166 return offset; | |
167 } | |
168 | |
169 | |
170 void LIR_Assembler::osr_entry() { | |
171 // On-stack-replacement entry sequence (interpreter frame layout described in interpreter_sparc.cpp): | |
172 // | |
173 // 1. Create a new compiled activation. | |
174 // 2. Initialize local variables in the compiled activation. The expression stack must be empty | |
175 // at the osr_bci; it is not initialized. | |
176 // 3. Jump to the continuation address in compiled code to resume execution. | |
177 | |
178 // OSR entry point | |
179 offsets()->set_value(CodeOffsets::OSR_Entry, code_offset()); | |
180 BlockBegin* osr_entry = compilation()->hir()->osr_entry(); | |
181 ValueStack* entry_state = osr_entry->end()->state(); | |
182 int number_of_locks = entry_state->locks_size(); | |
183 | |
184 // Create a frame for the compiled activation. | |
185 __ build_frame(initial_frame_size_in_bytes()); | |
186 | |
187 // OSR buffer is | |
188 // | |
189 // locals[nlocals-1..0] | |
190 // monitors[number_of_locks-1..0] | |
191 // | |
192 // locals is a direct copy of the interpreter frame so in the osr buffer | |
193 // so first slot in the local array is the last local from the interpreter | |
194 // and last slot is local[0] (receiver) from the interpreter | |
195 // | |
196 // Similarly with locks. The first lock slot in the osr buffer is the nth lock | |
197 // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock | |
198 // in the interpreter frame (the method lock if a sync method) | |
199 | |
200 // Initialize monitors in the compiled activation. | |
201 // I0: pointer to osr buffer | |
202 // | |
203 // All other registers are dead at this point and the locals will be | |
204 // copied into place by code emitted in the IR. | |
205 | |
206 Register OSR_buf = osrBufferPointer()->as_register(); | |
207 { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); | |
208 int monitor_offset = BytesPerWord * method()->max_locals() + | |
1060 | 209 (2 * BytesPerWord) * (number_of_locks - 1); |
210 // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in | |
211 // the OSR buffer using 2 word entries: first the lock and then | |
212 // the oop. | |
0 | 213 for (int i = 0; i < number_of_locks; i++) { |
1060 | 214 int slot_offset = monitor_offset - ((i * 2) * BytesPerWord); |
0 | 215 #ifdef ASSERT |
216 // verify the interpreter's monitor has a non-null object | |
217 { | |
218 Label L; | |
1060 | 219 __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7); |
0 | 220 __ cmp(G0, O7); |
221 __ br(Assembler::notEqual, false, Assembler::pt, L); | |
222 __ delayed()->nop(); | |
223 __ stop("locked object is NULL"); | |
224 __ bind(L); | |
225 } | |
226 #endif // ASSERT | |
227 // Copy the lock field into the compiled activation. | |
1060 | 228 __ ld_ptr(OSR_buf, slot_offset + 0, O7); |
0 | 229 __ st_ptr(O7, frame_map()->address_for_monitor_lock(i)); |
1060 | 230 __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7); |
0 | 231 __ st_ptr(O7, frame_map()->address_for_monitor_object(i)); |
232 } | |
233 } | |
234 } | |
235 | |
236 | |
237 // Optimized Library calls | |
238 // This is the fast version of java.lang.String.compare; it has not | |
239 // OSR-entry and therefore, we generate a slow version for OSR's | |
240 void LIR_Assembler::emit_string_compare(LIR_Opr left, LIR_Opr right, LIR_Opr dst, CodeEmitInfo* info) { | |
241 Register str0 = left->as_register(); | |
242 Register str1 = right->as_register(); | |
243 | |
244 Label Ldone; | |
245 | |
246 Register result = dst->as_register(); | |
247 { | |
248 // Get a pointer to the first character of string0 in tmp0 and get string0.count in str0 | |
249 // Get a pointer to the first character of string1 in tmp1 and get string1.count in str1 | |
250 // Also, get string0.count-string1.count in o7 and get the condition code set | |
251 // Note: some instructions have been hoisted for better instruction scheduling | |
252 | |
253 Register tmp0 = L0; | |
254 Register tmp1 = L1; | |
255 Register tmp2 = L2; | |
256 | |
257 int value_offset = java_lang_String:: value_offset_in_bytes(); // char array | |
258 int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position | |
259 int count_offset = java_lang_String:: count_offset_in_bytes(); | |
260 | |
2002 | 261 __ load_heap_oop(str0, value_offset, tmp0); |
727 | 262 __ ld(str0, offset_offset, tmp2); |
0 | 263 __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0); |
727 | 264 __ ld(str0, count_offset, str0); |
0 | 265 __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2); |
266 | |
267 // str1 may be null | |
268 add_debug_info_for_null_check_here(info); | |
269 | |
2002 | 270 __ load_heap_oop(str1, value_offset, tmp1); |
0 | 271 __ add(tmp0, tmp2, tmp0); |
272 | |
727 | 273 __ ld(str1, offset_offset, tmp2); |
0 | 274 __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1); |
727 | 275 __ ld(str1, count_offset, str1); |
0 | 276 __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2); |
277 __ subcc(str0, str1, O7); | |
278 __ add(tmp1, tmp2, tmp1); | |
279 } | |
280 | |
281 { | |
282 // Compute the minimum of the string lengths, scale it and store it in limit | |
283 Register count0 = I0; | |
284 Register count1 = I1; | |
285 Register limit = L3; | |
286 | |
287 Label Lskip; | |
288 __ sll(count0, exact_log2(sizeof(jchar)), limit); // string0 is shorter | |
289 __ br(Assembler::greater, true, Assembler::pt, Lskip); | |
290 __ delayed()->sll(count1, exact_log2(sizeof(jchar)), limit); // string1 is shorter | |
291 __ bind(Lskip); | |
292 | |
293 // If either string is empty (or both of them) the result is the difference in lengths | |
294 __ cmp(limit, 0); | |
295 __ br(Assembler::equal, true, Assembler::pn, Ldone); | |
296 __ delayed()->mov(O7, result); // result is difference in lengths | |
297 } | |
298 | |
299 { | |
300 // Neither string is empty | |
301 Label Lloop; | |
302 | |
303 Register base0 = L0; | |
304 Register base1 = L1; | |
305 Register chr0 = I0; | |
306 Register chr1 = I1; | |
307 Register limit = L3; | |
308 | |
309 // Shift base0 and base1 to the end of the arrays, negate limit | |
310 __ add(base0, limit, base0); | |
311 __ add(base1, limit, base1); | |
312 __ neg(limit); // limit = -min{string0.count, strin1.count} | |
313 | |
314 __ lduh(base0, limit, chr0); | |
315 __ bind(Lloop); | |
316 __ lduh(base1, limit, chr1); | |
317 __ subcc(chr0, chr1, chr0); | |
318 __ br(Assembler::notZero, false, Assembler::pn, Ldone); | |
319 assert(chr0 == result, "result must be pre-placed"); | |
320 __ delayed()->inccc(limit, sizeof(jchar)); | |
321 __ br(Assembler::notZero, true, Assembler::pt, Lloop); | |
322 __ delayed()->lduh(base0, limit, chr0); | |
323 } | |
324 | |
325 // If strings are equal up to min length, return the length difference. | |
326 __ mov(O7, result); | |
327 | |
328 // Otherwise, return the difference between the first mismatched chars. | |
329 __ bind(Ldone); | |
330 } | |
331 | |
332 | |
333 // -------------------------------------------------------------------------------------------- | |
334 | |
335 void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register hdr, int monitor_no) { | |
336 if (!GenerateSynchronizationCode) return; | |
337 | |
338 Register obj_reg = obj_opr->as_register(); | |
339 Register lock_reg = lock_opr->as_register(); | |
340 | |
341 Address mon_addr = frame_map()->address_for_monitor_lock(monitor_no); | |
342 Register reg = mon_addr.base(); | |
343 int offset = mon_addr.disp(); | |
344 // compute pointer to BasicLock | |
345 if (mon_addr.is_simm13()) { | |
346 __ add(reg, offset, lock_reg); | |
347 } | |
348 else { | |
349 __ set(offset, lock_reg); | |
350 __ add(reg, lock_reg, lock_reg); | |
351 } | |
352 // unlock object | |
353 MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, UseFastLocking, monitor_no); | |
354 // _slow_case_stubs->append(slow_case); | |
355 // temporary fix: must be created after exceptionhandler, therefore as call stub | |
356 _slow_case_stubs->append(slow_case); | |
357 if (UseFastLocking) { | |
358 // try inlined fast unlocking first, revert to slow locking if it fails | |
359 // note: lock_reg points to the displaced header since the displaced header offset is 0! | |
360 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); | |
361 __ unlock_object(hdr, obj_reg, lock_reg, *slow_case->entry()); | |
362 } else { | |
363 // always do slow unlocking | |
364 // note: the slow unlocking code could be inlined here, however if we use | |
365 // slow unlocking, speed doesn't matter anyway and this solution is | |
366 // simpler and requires less duplicated code - additionally, the | |
367 // slow unlocking code is the same in either case which simplifies | |
368 // debugging | |
369 __ br(Assembler::always, false, Assembler::pt, *slow_case->entry()); | |
370 __ delayed()->nop(); | |
371 } | |
372 // done | |
373 __ bind(*slow_case->continuation()); | |
374 } | |
375 | |
376 | |
1204 | 377 int LIR_Assembler::emit_exception_handler() { |
0 | 378 // if the last instruction is a call (typically to do a throw which |
379 // is coming at the end after block reordering) the return address | |
380 // must still point into the code area in order to avoid assertion | |
381 // failures when searching for the corresponding bci => add a nop | |
382 // (was bug 5/14/1999 - gri) | |
383 __ nop(); | |
384 | |
385 // generate code for exception handler | |
386 ciMethod* method = compilation()->method(); | |
387 | |
388 address handler_base = __ start_a_stub(exception_handler_size); | |
389 | |
390 if (handler_base == NULL) { | |
391 // not enough space left for the handler | |
392 bailout("exception handler overflow"); | |
1204 | 393 return -1; |
0 | 394 } |
1204 | 395 |
0 | 396 int offset = code_offset(); |
397 | |
1295 | 398 __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type); |
0 | 399 __ delayed()->nop(); |
400 debug_only(__ stop("should have gone to the caller");) | |
401 assert(code_offset() - offset <= exception_handler_size, "overflow"); | |
402 __ end_a_stub(); | |
1204 | 403 |
404 return offset; | |
0 | 405 } |
406 | |
1204 | 407 |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
408 // Emit the code to remove the frame from the stack in the exception |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
409 // unwind path. |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
410 int LIR_Assembler::emit_unwind_handler() { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
411 #ifndef PRODUCT |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
412 if (CommentedAssembly) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
413 _masm->block_comment("Unwind handler"); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
414 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
415 #endif |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
416 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
417 int offset = code_offset(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
418 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
419 // Fetch the exception from TLS and clear out exception related thread state |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
420 __ ld_ptr(G2_thread, in_bytes(JavaThread::exception_oop_offset()), O0); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
421 __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_oop_offset())); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
422 __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_pc_offset())); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
423 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
424 __ bind(_unwind_handler_entry); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
425 __ verify_not_null_oop(O0); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
426 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
427 __ mov(O0, I0); // Preserve the exception |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
428 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
429 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
430 // Preform needed unlocking |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
431 MonitorExitStub* stub = NULL; |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
432 if (method()->is_synchronized()) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
433 monitor_address(0, FrameMap::I1_opr); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
434 stub = new MonitorExitStub(FrameMap::I1_opr, true, 0); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
435 __ unlock_object(I3, I2, I1, *stub->entry()); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
436 __ bind(*stub->continuation()); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
437 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
438 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
439 if (compilation()->env()->dtrace_method_probes()) { |
1830
a3f7f95b0165
6988018: dtrace/hotspot/MethodInvocation/MethodInvocation002 crashes with client compiler
never
parents:
1791
diff
changeset
|
440 __ mov(G2_thread, O0); |
a3f7f95b0165
6988018: dtrace/hotspot/MethodInvocation/MethodInvocation002 crashes with client compiler
never
parents:
1791
diff
changeset
|
441 jobject2reg(method()->constant_encoding(), O1); |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
442 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), relocInfo::runtime_call_type); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
443 __ delayed()->nop(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
444 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
445 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
446 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
447 __ mov(I0, O0); // Restore the exception |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
448 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
449 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
450 // dispatch to the unwind logic |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
451 __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
452 __ delayed()->nop(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
453 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
454 // Emit the slow path assembly |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
455 if (stub != NULL) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
456 stub->emit_code(this); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
457 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
458 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
459 return offset; |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
460 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
461 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
462 |
1204 | 463 int LIR_Assembler::emit_deopt_handler() { |
0 | 464 // if the last instruction is a call (typically to do a throw which |
465 // is coming at the end after block reordering) the return address | |
466 // must still point into the code area in order to avoid assertion | |
467 // failures when searching for the corresponding bci => add a nop | |
468 // (was bug 5/14/1999 - gri) | |
469 __ nop(); | |
470 | |
471 // generate code for deopt handler | |
472 ciMethod* method = compilation()->method(); | |
473 address handler_base = __ start_a_stub(deopt_handler_size); | |
474 if (handler_base == NULL) { | |
475 // not enough space left for the handler | |
476 bailout("deopt handler overflow"); | |
1204 | 477 return -1; |
0 | 478 } |
1204 | 479 |
0 | 480 int offset = code_offset(); |
727 | 481 AddressLiteral deopt_blob(SharedRuntime::deopt_blob()->unpack()); |
482 __ JUMP(deopt_blob, G3_scratch, 0); // sethi;jmp | |
0 | 483 __ delayed()->nop(); |
484 assert(code_offset() - offset <= deopt_handler_size, "overflow"); | |
485 debug_only(__ stop("should have gone to the caller");) | |
486 __ end_a_stub(); | |
1204 | 487 |
488 return offset; | |
0 | 489 } |
490 | |
491 | |
492 void LIR_Assembler::jobject2reg(jobject o, Register reg) { | |
493 if (o == NULL) { | |
494 __ set(NULL_WORD, reg); | |
495 } else { | |
496 int oop_index = __ oop_recorder()->find_index(o); | |
497 RelocationHolder rspec = oop_Relocation::spec(oop_index); | |
498 __ set(NULL_WORD, reg, rspec); // Will be set when the nmethod is created | |
499 } | |
500 } | |
501 | |
502 | |
503 void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo *info) { | |
504 // Allocate a new index in oop table to hold the oop once it's been patched | |
505 int oop_index = __ oop_recorder()->allocate_index((jobject)NULL); | |
506 PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id, oop_index); | |
507 | |
727 | 508 AddressLiteral addrlit(NULL, oop_Relocation::spec(oop_index)); |
509 assert(addrlit.rspec().type() == relocInfo::oop_type, "must be an oop reloc"); | |
0 | 510 // It may not seem necessary to use a sethi/add pair to load a NULL into dest, but the |
511 // NULL will be dynamically patched later and the patched value may be large. We must | |
512 // therefore generate the sethi/add as a placeholders | |
727 | 513 __ patchable_set(addrlit, reg); |
0 | 514 |
515 patching_epilog(patch, lir_patch_normal, reg, info); | |
516 } | |
517 | |
518 | |
519 void LIR_Assembler::emit_op3(LIR_Op3* op) { | |
520 Register Rdividend = op->in_opr1()->as_register(); | |
521 Register Rdivisor = noreg; | |
522 Register Rscratch = op->in_opr3()->as_register(); | |
523 Register Rresult = op->result_opr()->as_register(); | |
524 int divisor = -1; | |
525 | |
526 if (op->in_opr2()->is_register()) { | |
527 Rdivisor = op->in_opr2()->as_register(); | |
528 } else { | |
529 divisor = op->in_opr2()->as_constant_ptr()->as_jint(); | |
530 assert(Assembler::is_simm13(divisor), "can only handle simm13"); | |
531 } | |
532 | |
533 assert(Rdividend != Rscratch, ""); | |
534 assert(Rdivisor != Rscratch, ""); | |
535 assert(op->code() == lir_idiv || op->code() == lir_irem, "Must be irem or idiv"); | |
536 | |
537 if (Rdivisor == noreg && is_power_of_2(divisor)) { | |
538 // convert division by a power of two into some shifts and logical operations | |
539 if (op->code() == lir_idiv) { | |
540 if (divisor == 2) { | |
541 __ srl(Rdividend, 31, Rscratch); | |
542 } else { | |
543 __ sra(Rdividend, 31, Rscratch); | |
544 __ and3(Rscratch, divisor - 1, Rscratch); | |
545 } | |
546 __ add(Rdividend, Rscratch, Rscratch); | |
547 __ sra(Rscratch, log2_intptr(divisor), Rresult); | |
548 return; | |
549 } else { | |
550 if (divisor == 2) { | |
551 __ srl(Rdividend, 31, Rscratch); | |
552 } else { | |
553 __ sra(Rdividend, 31, Rscratch); | |
554 __ and3(Rscratch, divisor - 1,Rscratch); | |
555 } | |
556 __ add(Rdividend, Rscratch, Rscratch); | |
557 __ andn(Rscratch, divisor - 1,Rscratch); | |
558 __ sub(Rdividend, Rscratch, Rresult); | |
559 return; | |
560 } | |
561 } | |
562 | |
563 __ sra(Rdividend, 31, Rscratch); | |
564 __ wry(Rscratch); | |
565 if (!VM_Version::v9_instructions_work()) { | |
566 // v9 doesn't require these nops | |
567 __ nop(); | |
568 __ nop(); | |
569 __ nop(); | |
570 __ nop(); | |
571 } | |
572 | |
573 add_debug_info_for_div0_here(op->info()); | |
574 | |
575 if (Rdivisor != noreg) { | |
576 __ sdivcc(Rdividend, Rdivisor, (op->code() == lir_idiv ? Rresult : Rscratch)); | |
577 } else { | |
578 assert(Assembler::is_simm13(divisor), "can only handle simm13"); | |
579 __ sdivcc(Rdividend, divisor, (op->code() == lir_idiv ? Rresult : Rscratch)); | |
580 } | |
581 | |
582 Label skip; | |
583 __ br(Assembler::overflowSet, true, Assembler::pn, skip); | |
584 __ delayed()->Assembler::sethi(0x80000000, (op->code() == lir_idiv ? Rresult : Rscratch)); | |
585 __ bind(skip); | |
586 | |
587 if (op->code() == lir_irem) { | |
588 if (Rdivisor != noreg) { | |
589 __ smul(Rscratch, Rdivisor, Rscratch); | |
590 } else { | |
591 __ smul(Rscratch, divisor, Rscratch); | |
592 } | |
593 __ sub(Rdividend, Rscratch, Rresult); | |
594 } | |
595 } | |
596 | |
597 | |
598 void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) { | |
599 #ifdef ASSERT | |
600 assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label"); | |
601 if (op->block() != NULL) _branch_target_blocks.append(op->block()); | |
602 if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock()); | |
603 #endif | |
604 assert(op->info() == NULL, "shouldn't have CodeEmitInfo"); | |
605 | |
606 if (op->cond() == lir_cond_always) { | |
607 __ br(Assembler::always, false, Assembler::pt, *(op->label())); | |
608 } else if (op->code() == lir_cond_float_branch) { | |
609 assert(op->ublock() != NULL, "must have unordered successor"); | |
610 bool is_unordered = (op->ublock() == op->block()); | |
611 Assembler::Condition acond; | |
612 switch (op->cond()) { | |
613 case lir_cond_equal: acond = Assembler::f_equal; break; | |
614 case lir_cond_notEqual: acond = Assembler::f_notEqual; break; | |
615 case lir_cond_less: acond = (is_unordered ? Assembler::f_unorderedOrLess : Assembler::f_less); break; | |
616 case lir_cond_greater: acond = (is_unordered ? Assembler::f_unorderedOrGreater : Assembler::f_greater); break; | |
617 case lir_cond_lessEqual: acond = (is_unordered ? Assembler::f_unorderedOrLessOrEqual : Assembler::f_lessOrEqual); break; | |
618 case lir_cond_greaterEqual: acond = (is_unordered ? Assembler::f_unorderedOrGreaterOrEqual: Assembler::f_greaterOrEqual); break; | |
619 default : ShouldNotReachHere(); | |
620 }; | |
621 | |
622 if (!VM_Version::v9_instructions_work()) { | |
623 __ nop(); | |
624 } | |
625 __ fb( acond, false, Assembler::pn, *(op->label())); | |
626 } else { | |
627 assert (op->code() == lir_branch, "just checking"); | |
628 | |
629 Assembler::Condition acond; | |
630 switch (op->cond()) { | |
631 case lir_cond_equal: acond = Assembler::equal; break; | |
632 case lir_cond_notEqual: acond = Assembler::notEqual; break; | |
633 case lir_cond_less: acond = Assembler::less; break; | |
634 case lir_cond_lessEqual: acond = Assembler::lessEqual; break; | |
635 case lir_cond_greaterEqual: acond = Assembler::greaterEqual; break; | |
636 case lir_cond_greater: acond = Assembler::greater; break; | |
637 case lir_cond_aboveEqual: acond = Assembler::greaterEqualUnsigned; break; | |
638 case lir_cond_belowEqual: acond = Assembler::lessEqualUnsigned; break; | |
639 default: ShouldNotReachHere(); | |
640 }; | |
641 | |
642 // sparc has different condition codes for testing 32-bit | |
643 // vs. 64-bit values. We could always test xcc is we could | |
644 // guarantee that 32-bit loads always sign extended but that isn't | |
645 // true and since sign extension isn't free, it would impose a | |
646 // slight cost. | |
647 #ifdef _LP64 | |
648 if (op->type() == T_INT) { | |
649 __ br(acond, false, Assembler::pn, *(op->label())); | |
650 } else | |
651 #endif | |
652 __ brx(acond, false, Assembler::pn, *(op->label())); | |
653 } | |
654 // The peephole pass fills the delay slot | |
655 } | |
656 | |
657 | |
658 void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { | |
659 Bytecodes::Code code = op->bytecode(); | |
660 LIR_Opr dst = op->result_opr(); | |
661 | |
662 switch(code) { | |
663 case Bytecodes::_i2l: { | |
664 Register rlo = dst->as_register_lo(); | |
665 Register rhi = dst->as_register_hi(); | |
666 Register rval = op->in_opr()->as_register(); | |
667 #ifdef _LP64 | |
668 __ sra(rval, 0, rlo); | |
669 #else | |
670 __ mov(rval, rlo); | |
671 __ sra(rval, BitsPerInt-1, rhi); | |
672 #endif | |
673 break; | |
674 } | |
675 case Bytecodes::_i2d: | |
676 case Bytecodes::_i2f: { | |
677 bool is_double = (code == Bytecodes::_i2d); | |
678 FloatRegister rdst = is_double ? dst->as_double_reg() : dst->as_float_reg(); | |
679 FloatRegisterImpl::Width w = is_double ? FloatRegisterImpl::D : FloatRegisterImpl::S; | |
680 FloatRegister rsrc = op->in_opr()->as_float_reg(); | |
681 if (rsrc != rdst) { | |
682 __ fmov(FloatRegisterImpl::S, rsrc, rdst); | |
683 } | |
684 __ fitof(w, rdst, rdst); | |
685 break; | |
686 } | |
687 case Bytecodes::_f2i:{ | |
688 FloatRegister rsrc = op->in_opr()->as_float_reg(); | |
689 Address addr = frame_map()->address_for_slot(dst->single_stack_ix()); | |
690 Label L; | |
691 // result must be 0 if value is NaN; test by comparing value to itself | |
692 __ fcmp(FloatRegisterImpl::S, Assembler::fcc0, rsrc, rsrc); | |
693 if (!VM_Version::v9_instructions_work()) { | |
694 __ nop(); | |
695 } | |
696 __ fb(Assembler::f_unordered, true, Assembler::pn, L); | |
697 __ delayed()->st(G0, addr); // annuled if contents of rsrc is not NaN | |
698 __ ftoi(FloatRegisterImpl::S, rsrc, rsrc); | |
699 // move integer result from float register to int register | |
700 __ stf(FloatRegisterImpl::S, rsrc, addr.base(), addr.disp()); | |
701 __ bind (L); | |
702 break; | |
703 } | |
704 case Bytecodes::_l2i: { | |
705 Register rlo = op->in_opr()->as_register_lo(); | |
706 Register rhi = op->in_opr()->as_register_hi(); | |
707 Register rdst = dst->as_register(); | |
708 #ifdef _LP64 | |
709 __ sra(rlo, 0, rdst); | |
710 #else | |
711 __ mov(rlo, rdst); | |
712 #endif | |
713 break; | |
714 } | |
715 case Bytecodes::_d2f: | |
716 case Bytecodes::_f2d: { | |
717 bool is_double = (code == Bytecodes::_f2d); | |
718 assert((!is_double && dst->is_single_fpu()) || (is_double && dst->is_double_fpu()), "check"); | |
719 LIR_Opr val = op->in_opr(); | |
720 FloatRegister rval = (code == Bytecodes::_d2f) ? val->as_double_reg() : val->as_float_reg(); | |
721 FloatRegister rdst = is_double ? dst->as_double_reg() : dst->as_float_reg(); | |
722 FloatRegisterImpl::Width vw = is_double ? FloatRegisterImpl::S : FloatRegisterImpl::D; | |
723 FloatRegisterImpl::Width dw = is_double ? FloatRegisterImpl::D : FloatRegisterImpl::S; | |
724 __ ftof(vw, dw, rval, rdst); | |
725 break; | |
726 } | |
727 case Bytecodes::_i2s: | |
728 case Bytecodes::_i2b: { | |
729 Register rval = op->in_opr()->as_register(); | |
730 Register rdst = dst->as_register(); | |
731 int shift = (code == Bytecodes::_i2b) ? (BitsPerInt - T_BYTE_aelem_bytes * BitsPerByte) : (BitsPerInt - BitsPerShort); | |
732 __ sll (rval, shift, rdst); | |
733 __ sra (rdst, shift, rdst); | |
734 break; | |
735 } | |
736 case Bytecodes::_i2c: { | |
737 Register rval = op->in_opr()->as_register(); | |
738 Register rdst = dst->as_register(); | |
739 int shift = BitsPerInt - T_CHAR_aelem_bytes * BitsPerByte; | |
740 __ sll (rval, shift, rdst); | |
741 __ srl (rdst, shift, rdst); | |
742 break; | |
743 } | |
744 | |
745 default: ShouldNotReachHere(); | |
746 } | |
747 } | |
748 | |
749 | |
750 void LIR_Assembler::align_call(LIR_Code) { | |
751 // do nothing since all instructions are word aligned on sparc | |
752 } | |
753 | |
754 | |
1295 | 755 void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { |
756 __ call(op->addr(), rtype); | |
1564 | 757 // The peephole pass fills the delay slot, add_call_info is done in |
758 // LIR_Assembler::emit_delay. | |
0 | 759 } |
760 | |
761 | |
1295 | 762 void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { |
0 | 763 RelocationHolder rspec = virtual_call_Relocation::spec(pc()); |
764 __ set_oop((jobject)Universe::non_oop_word(), G5_inline_cache_reg); | |
765 __ relocate(rspec); | |
1295 | 766 __ call(op->addr(), relocInfo::none); |
1564 | 767 // The peephole pass fills the delay slot, add_call_info is done in |
768 // LIR_Assembler::emit_delay. | |
0 | 769 } |
770 | |
771 | |
1295 | 772 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { |
773 add_debug_info_for_null_check_here(op->info()); | |
2002 | 774 __ load_klass(O0, G3_scratch); |
1295 | 775 if (__ is_simm13(op->vtable_offset())) { |
776 __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method); | |
0 | 777 } else { |
778 // This will generate 2 instructions | |
1295 | 779 __ set(op->vtable_offset(), G5_method); |
0 | 780 // ld_ptr, set_hi, set |
781 __ ld_ptr(G3_scratch, G5_method, G5_method); | |
782 } | |
727 | 783 __ ld_ptr(G5_method, methodOopDesc::from_compiled_offset(), G3_scratch); |
0 | 784 __ callr(G3_scratch, G0); |
785 // the peephole pass fills the delay slot | |
786 } | |
787 | |
2002 | 788 int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) { |
0 | 789 int store_offset; |
790 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { | |
791 assert(!unaligned, "can't handle this"); | |
792 // for offsets larger than a simm13 we setup the offset in O7 | |
727 | 793 __ set(offset, O7); |
2002 | 794 store_offset = store(from_reg, base, O7, type, wide); |
0 | 795 } else { |
2002 | 796 if (type == T_ARRAY || type == T_OBJECT) { |
797 __ verify_oop(from_reg->as_register()); | |
798 } | |
0 | 799 store_offset = code_offset(); |
800 switch (type) { | |
801 case T_BOOLEAN: // fall through | |
802 case T_BYTE : __ stb(from_reg->as_register(), base, offset); break; | |
803 case T_CHAR : __ sth(from_reg->as_register(), base, offset); break; | |
804 case T_SHORT : __ sth(from_reg->as_register(), base, offset); break; | |
805 case T_INT : __ stw(from_reg->as_register(), base, offset); break; | |
806 case T_LONG : | |
807 #ifdef _LP64 | |
808 if (unaligned || PatchALot) { | |
809 __ srax(from_reg->as_register_lo(), 32, O7); | |
810 __ stw(from_reg->as_register_lo(), base, offset + lo_word_offset_in_bytes); | |
811 __ stw(O7, base, offset + hi_word_offset_in_bytes); | |
812 } else { | |
813 __ stx(from_reg->as_register_lo(), base, offset); | |
814 } | |
815 #else | |
816 assert(Assembler::is_simm13(offset + 4), "must be"); | |
817 __ stw(from_reg->as_register_lo(), base, offset + lo_word_offset_in_bytes); | |
818 __ stw(from_reg->as_register_hi(), base, offset + hi_word_offset_in_bytes); | |
819 #endif | |
820 break; | |
2002 | 821 case T_ADDRESS: |
822 __ st_ptr(from_reg->as_register(), base, offset); | |
823 break; | |
0 | 824 case T_ARRAY : // fall through |
2002 | 825 case T_OBJECT: |
826 { | |
827 if (UseCompressedOops && !wide) { | |
828 __ encode_heap_oop(from_reg->as_register(), G3_scratch); | |
829 store_offset = code_offset(); | |
830 __ stw(G3_scratch, base, offset); | |
831 } else { | |
832 __ st_ptr(from_reg->as_register(), base, offset); | |
833 } | |
834 break; | |
835 } | |
836 | |
0 | 837 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, offset); break; |
838 case T_DOUBLE: | |
839 { | |
840 FloatRegister reg = from_reg->as_double_reg(); | |
841 // split unaligned stores | |
842 if (unaligned || PatchALot) { | |
843 assert(Assembler::is_simm13(offset + 4), "must be"); | |
844 __ stf(FloatRegisterImpl::S, reg->successor(), base, offset + 4); | |
845 __ stf(FloatRegisterImpl::S, reg, base, offset); | |
846 } else { | |
847 __ stf(FloatRegisterImpl::D, reg, base, offset); | |
848 } | |
849 break; | |
850 } | |
851 default : ShouldNotReachHere(); | |
852 } | |
853 } | |
854 return store_offset; | |
855 } | |
856 | |
857 | |
2002 | 858 int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide) { |
859 if (type == T_ARRAY || type == T_OBJECT) { | |
860 __ verify_oop(from_reg->as_register()); | |
861 } | |
0 | 862 int store_offset = code_offset(); |
863 switch (type) { | |
864 case T_BOOLEAN: // fall through | |
865 case T_BYTE : __ stb(from_reg->as_register(), base, disp); break; | |
866 case T_CHAR : __ sth(from_reg->as_register(), base, disp); break; | |
867 case T_SHORT : __ sth(from_reg->as_register(), base, disp); break; | |
868 case T_INT : __ stw(from_reg->as_register(), base, disp); break; | |
869 case T_LONG : | |
870 #ifdef _LP64 | |
871 __ stx(from_reg->as_register_lo(), base, disp); | |
872 #else | |
873 assert(from_reg->as_register_hi()->successor() == from_reg->as_register_lo(), "must match"); | |
874 __ std(from_reg->as_register_hi(), base, disp); | |
875 #endif | |
876 break; | |
2002 | 877 case T_ADDRESS: |
878 __ st_ptr(from_reg->as_register(), base, disp); | |
879 break; | |
0 | 880 case T_ARRAY : // fall through |
2002 | 881 case T_OBJECT: |
882 { | |
883 if (UseCompressedOops && !wide) { | |
884 __ encode_heap_oop(from_reg->as_register(), G3_scratch); | |
885 store_offset = code_offset(); | |
886 __ stw(G3_scratch, base, disp); | |
887 } else { | |
888 __ st_ptr(from_reg->as_register(), base, disp); | |
889 } | |
890 break; | |
891 } | |
0 | 892 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, disp); break; |
893 case T_DOUBLE: __ stf(FloatRegisterImpl::D, from_reg->as_double_reg(), base, disp); break; | |
894 default : ShouldNotReachHere(); | |
895 } | |
896 return store_offset; | |
897 } | |
898 | |
899 | |
2002 | 900 int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned) { |
0 | 901 int load_offset; |
902 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) { | |
903 assert(base != O7, "destroying register"); | |
904 assert(!unaligned, "can't handle this"); | |
905 // for offsets larger than a simm13 we setup the offset in O7 | |
727 | 906 __ set(offset, O7); |
2002 | 907 load_offset = load(base, O7, to_reg, type, wide); |
0 | 908 } else { |
909 load_offset = code_offset(); | |
910 switch(type) { | |
911 case T_BOOLEAN: // fall through | |
912 case T_BYTE : __ ldsb(base, offset, to_reg->as_register()); break; | |
913 case T_CHAR : __ lduh(base, offset, to_reg->as_register()); break; | |
914 case T_SHORT : __ ldsh(base, offset, to_reg->as_register()); break; | |
915 case T_INT : __ ld(base, offset, to_reg->as_register()); break; | |
916 case T_LONG : | |
917 if (!unaligned) { | |
918 #ifdef _LP64 | |
919 __ ldx(base, offset, to_reg->as_register_lo()); | |
920 #else | |
921 assert(to_reg->as_register_hi()->successor() == to_reg->as_register_lo(), | |
922 "must be sequential"); | |
923 __ ldd(base, offset, to_reg->as_register_hi()); | |
924 #endif | |
925 } else { | |
926 #ifdef _LP64 | |
927 assert(base != to_reg->as_register_lo(), "can't handle this"); | |
1060 | 928 assert(O7 != to_reg->as_register_lo(), "can't handle this"); |
0 | 929 __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_lo()); |
1060 | 930 __ lduw(base, offset + lo_word_offset_in_bytes, O7); // in case O7 is base or offset, use it last |
0 | 931 __ sllx(to_reg->as_register_lo(), 32, to_reg->as_register_lo()); |
1060 | 932 __ or3(to_reg->as_register_lo(), O7, to_reg->as_register_lo()); |
0 | 933 #else |
934 if (base == to_reg->as_register_lo()) { | |
935 __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi()); | |
936 __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo()); | |
937 } else { | |
938 __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo()); | |
939 __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi()); | |
940 } | |
941 #endif | |
942 } | |
943 break; | |
2002 | 944 case T_ADDRESS: __ ld_ptr(base, offset, to_reg->as_register()); break; |
0 | 945 case T_ARRAY : // fall through |
2002 | 946 case T_OBJECT: |
947 { | |
948 if (UseCompressedOops && !wide) { | |
949 __ lduw(base, offset, to_reg->as_register()); | |
950 __ decode_heap_oop(to_reg->as_register()); | |
951 } else { | |
952 __ ld_ptr(base, offset, to_reg->as_register()); | |
953 } | |
954 break; | |
955 } | |
0 | 956 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break; |
957 case T_DOUBLE: | |
958 { | |
959 FloatRegister reg = to_reg->as_double_reg(); | |
960 // split unaligned loads | |
961 if (unaligned || PatchALot) { | |
1060 | 962 __ ldf(FloatRegisterImpl::S, base, offset + 4, reg->successor()); |
963 __ ldf(FloatRegisterImpl::S, base, offset, reg); | |
0 | 964 } else { |
965 __ ldf(FloatRegisterImpl::D, base, offset, to_reg->as_double_reg()); | |
966 } | |
967 break; | |
968 } | |
969 default : ShouldNotReachHere(); | |
970 } | |
2002 | 971 if (type == T_ARRAY || type == T_OBJECT) { |
972 __ verify_oop(to_reg->as_register()); | |
973 } | |
0 | 974 } |
975 return load_offset; | |
976 } | |
977 | |
978 | |
2002 | 979 int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide) { |
0 | 980 int load_offset = code_offset(); |
981 switch(type) { | |
982 case T_BOOLEAN: // fall through | |
2002 | 983 case T_BYTE : __ ldsb(base, disp, to_reg->as_register()); break; |
984 case T_CHAR : __ lduh(base, disp, to_reg->as_register()); break; | |
985 case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break; | |
986 case T_INT : __ ld(base, disp, to_reg->as_register()); break; | |
987 case T_ADDRESS: __ ld_ptr(base, disp, to_reg->as_register()); break; | |
0 | 988 case T_ARRAY : // fall through |
2002 | 989 case T_OBJECT: |
990 { | |
991 if (UseCompressedOops && !wide) { | |
992 __ lduw(base, disp, to_reg->as_register()); | |
993 __ decode_heap_oop(to_reg->as_register()); | |
994 } else { | |
995 __ ld_ptr(base, disp, to_reg->as_register()); | |
996 } | |
997 break; | |
998 } | |
0 | 999 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, disp, to_reg->as_float_reg()); break; |
1000 case T_DOUBLE: __ ldf(FloatRegisterImpl::D, base, disp, to_reg->as_double_reg()); break; | |
1001 case T_LONG : | |
1002 #ifdef _LP64 | |
1003 __ ldx(base, disp, to_reg->as_register_lo()); | |
1004 #else | |
1005 assert(to_reg->as_register_hi()->successor() == to_reg->as_register_lo(), | |
1006 "must be sequential"); | |
1007 __ ldd(base, disp, to_reg->as_register_hi()); | |
1008 #endif | |
1009 break; | |
1010 default : ShouldNotReachHere(); | |
1011 } | |
2002 | 1012 if (type == T_ARRAY || type == T_OBJECT) { |
1013 __ verify_oop(to_reg->as_register()); | |
1014 } | |
0 | 1015 return load_offset; |
1016 } | |
1017 | |
1018 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { | |
1019 LIR_Const* c = src->as_constant_ptr(); | |
1020 switch (c->type()) { | |
1021 case T_INT: | |
2002 | 1022 case T_FLOAT: { |
1023 Register src_reg = O7; | |
1024 int value = c->as_jint_bits(); | |
1025 if (value == 0) { | |
1026 src_reg = G0; | |
1027 } else { | |
1028 __ set(value, O7); | |
1029 } | |
1030 Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); | |
1031 __ stw(src_reg, addr.base(), addr.disp()); | |
1032 break; | |
1033 } | |
1297
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1295
diff
changeset
|
1034 case T_ADDRESS: { |
0 | 1035 Register src_reg = O7; |
1036 int value = c->as_jint_bits(); | |
1037 if (value == 0) { | |
1038 src_reg = G0; | |
1039 } else { | |
1040 __ set(value, O7); | |
1041 } | |
1042 Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); | |
2002 | 1043 __ st_ptr(src_reg, addr.base(), addr.disp()); |
0 | 1044 break; |
1045 } | |
1046 case T_OBJECT: { | |
1047 Register src_reg = O7; | |
1048 jobject2reg(c->as_jobject(), src_reg); | |
1049 Address addr = frame_map()->address_for_slot(dest->single_stack_ix()); | |
1050 __ st_ptr(src_reg, addr.base(), addr.disp()); | |
1051 break; | |
1052 } | |
1053 case T_LONG: | |
1054 case T_DOUBLE: { | |
1055 Address addr = frame_map()->address_for_double_slot(dest->double_stack_ix()); | |
1056 | |
1057 Register tmp = O7; | |
1058 int value_lo = c->as_jint_lo_bits(); | |
1059 if (value_lo == 0) { | |
1060 tmp = G0; | |
1061 } else { | |
1062 __ set(value_lo, O7); | |
1063 } | |
1064 __ stw(tmp, addr.base(), addr.disp() + lo_word_offset_in_bytes); | |
1065 int value_hi = c->as_jint_hi_bits(); | |
1066 if (value_hi == 0) { | |
1067 tmp = G0; | |
1068 } else { | |
1069 __ set(value_hi, O7); | |
1070 } | |
1071 __ stw(tmp, addr.base(), addr.disp() + hi_word_offset_in_bytes); | |
1072 break; | |
1073 } | |
1074 default: | |
1075 Unimplemented(); | |
1076 } | |
1077 } | |
1078 | |
1079 | |
2002 | 1080 void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { |
0 | 1081 LIR_Const* c = src->as_constant_ptr(); |
1082 LIR_Address* addr = dest->as_address_ptr(); | |
1083 Register base = addr->base()->as_pointer_register(); | |
2002 | 1084 int offset = -1; |
1085 | |
0 | 1086 switch (c->type()) { |
1087 case T_INT: | |
1297
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1295
diff
changeset
|
1088 case T_FLOAT: |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1295
diff
changeset
|
1089 case T_ADDRESS: { |
0 | 1090 LIR_Opr tmp = FrameMap::O7_opr; |
1091 int value = c->as_jint_bits(); | |
1092 if (value == 0) { | |
1093 tmp = FrameMap::G0_opr; | |
1094 } else if (Assembler::is_simm13(value)) { | |
1095 __ set(value, O7); | |
1096 } | |
1097 if (addr->index()->is_valid()) { | |
1098 assert(addr->disp() == 0, "must be zero"); | |
2002 | 1099 offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide); |
0 | 1100 } else { |
1101 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); | |
2002 | 1102 offset = store(tmp, base, addr->disp(), type, wide, false); |
0 | 1103 } |
1104 break; | |
1105 } | |
1106 case T_LONG: | |
1107 case T_DOUBLE: { | |
1108 assert(!addr->index()->is_valid(), "can't handle reg reg address here"); | |
1109 assert(Assembler::is_simm13(addr->disp()) && | |
1110 Assembler::is_simm13(addr->disp() + 4), "can't handle larger addresses"); | |
1111 | |
2002 | 1112 LIR_Opr tmp = FrameMap::O7_opr; |
0 | 1113 int value_lo = c->as_jint_lo_bits(); |
1114 if (value_lo == 0) { | |
2002 | 1115 tmp = FrameMap::G0_opr; |
0 | 1116 } else { |
1117 __ set(value_lo, O7); | |
1118 } | |
2002 | 1119 offset = store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT, wide, false); |
0 | 1120 int value_hi = c->as_jint_hi_bits(); |
1121 if (value_hi == 0) { | |
2002 | 1122 tmp = FrameMap::G0_opr; |
0 | 1123 } else { |
1124 __ set(value_hi, O7); | |
1125 } | |
2002 | 1126 offset = store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false); |
0 | 1127 break; |
1128 } | |
1129 case T_OBJECT: { | |
1130 jobject obj = c->as_jobject(); | |
1131 LIR_Opr tmp; | |
1132 if (obj == NULL) { | |
1133 tmp = FrameMap::G0_opr; | |
1134 } else { | |
1135 tmp = FrameMap::O7_opr; | |
1136 jobject2reg(c->as_jobject(), O7); | |
1137 } | |
1138 // handle either reg+reg or reg+disp address | |
1139 if (addr->index()->is_valid()) { | |
1140 assert(addr->disp() == 0, "must be zero"); | |
2002 | 1141 offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide); |
0 | 1142 } else { |
1143 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses"); | |
2002 | 1144 offset = store(tmp, base, addr->disp(), type, wide, false); |
0 | 1145 } |
1146 | |
1147 break; | |
1148 } | |
1149 default: | |
1150 Unimplemented(); | |
1151 } | |
2002 | 1152 if (info != NULL) { |
1153 assert(offset != -1, "offset should've been set"); | |
1154 add_debug_info_for_null_check(offset, info); | |
1155 } | |
0 | 1156 } |
1157 | |
1158 | |
1159 void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) { | |
1160 LIR_Const* c = src->as_constant_ptr(); | |
1161 LIR_Opr to_reg = dest; | |
1162 | |
1163 switch (c->type()) { | |
1164 case T_INT: | |
1297
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1295
diff
changeset
|
1165 case T_ADDRESS: |
0 | 1166 { |
1167 jint con = c->as_jint(); | |
1168 if (to_reg->is_single_cpu()) { | |
1169 assert(patch_code == lir_patch_none, "no patching handled here"); | |
1170 __ set(con, to_reg->as_register()); | |
1171 } else { | |
1172 ShouldNotReachHere(); | |
1173 assert(to_reg->is_single_fpu(), "wrong register kind"); | |
1174 | |
1175 __ set(con, O7); | |
727 | 1176 Address temp_slot(SP, (frame::register_save_words * wordSize) + STACK_BIAS); |
0 | 1177 __ st(O7, temp_slot); |
1178 __ ldf(FloatRegisterImpl::S, temp_slot, to_reg->as_float_reg()); | |
1179 } | |
1180 } | |
1181 break; | |
1182 | |
1183 case T_LONG: | |
1184 { | |
1185 jlong con = c->as_jlong(); | |
1186 | |
1187 if (to_reg->is_double_cpu()) { | |
1188 #ifdef _LP64 | |
1189 __ set(con, to_reg->as_register_lo()); | |
1190 #else | |
1191 __ set(low(con), to_reg->as_register_lo()); | |
1192 __ set(high(con), to_reg->as_register_hi()); | |
1193 #endif | |
1194 #ifdef _LP64 | |
1195 } else if (to_reg->is_single_cpu()) { | |
1196 __ set(con, to_reg->as_register()); | |
1197 #endif | |
1198 } else { | |
1199 ShouldNotReachHere(); | |
1200 assert(to_reg->is_double_fpu(), "wrong register kind"); | |
727 | 1201 Address temp_slot_lo(SP, ((frame::register_save_words ) * wordSize) + STACK_BIAS); |
1202 Address temp_slot_hi(SP, ((frame::register_save_words) * wordSize) + (longSize/2) + STACK_BIAS); | |
0 | 1203 __ set(low(con), O7); |
1204 __ st(O7, temp_slot_lo); | |
1205 __ set(high(con), O7); | |
1206 __ st(O7, temp_slot_hi); | |
1207 __ ldf(FloatRegisterImpl::D, temp_slot_lo, to_reg->as_double_reg()); | |
1208 } | |
1209 } | |
1210 break; | |
1211 | |
1212 case T_OBJECT: | |
1213 { | |
1214 if (patch_code == lir_patch_none) { | |
1215 jobject2reg(c->as_jobject(), to_reg->as_register()); | |
1216 } else { | |
1217 jobject2reg_with_patching(to_reg->as_register(), info); | |
1218 } | |
1219 } | |
1220 break; | |
1221 | |
1222 case T_FLOAT: | |
1223 { | |
1224 address const_addr = __ float_constant(c->as_jfloat()); | |
1225 if (const_addr == NULL) { | |
1226 bailout("const section overflow"); | |
1227 break; | |
1228 } | |
1229 RelocationHolder rspec = internal_word_Relocation::spec(const_addr); | |
727 | 1230 AddressLiteral const_addrlit(const_addr, rspec); |
0 | 1231 if (to_reg->is_single_fpu()) { |
727 | 1232 __ patchable_sethi(const_addrlit, O7); |
0 | 1233 __ relocate(rspec); |
727 | 1234 __ ldf(FloatRegisterImpl::S, O7, const_addrlit.low10(), to_reg->as_float_reg()); |
0 | 1235 |
1236 } else { | |
1237 assert(to_reg->is_single_cpu(), "Must be a cpu register."); | |
1238 | |
727 | 1239 __ set(const_addrlit, O7); |
2002 | 1240 __ ld(O7, 0, to_reg->as_register()); |
0 | 1241 } |
1242 } | |
1243 break; | |
1244 | |
1245 case T_DOUBLE: | |
1246 { | |
1247 address const_addr = __ double_constant(c->as_jdouble()); | |
1248 if (const_addr == NULL) { | |
1249 bailout("const section overflow"); | |
1250 break; | |
1251 } | |
1252 RelocationHolder rspec = internal_word_Relocation::spec(const_addr); | |
1253 | |
1254 if (to_reg->is_double_fpu()) { | |
727 | 1255 AddressLiteral const_addrlit(const_addr, rspec); |
1256 __ patchable_sethi(const_addrlit, O7); | |
0 | 1257 __ relocate(rspec); |
727 | 1258 __ ldf (FloatRegisterImpl::D, O7, const_addrlit.low10(), to_reg->as_double_reg()); |
0 | 1259 } else { |
1260 assert(to_reg->is_double_cpu(), "Must be a long register."); | |
1261 #ifdef _LP64 | |
1262 __ set(jlong_cast(c->as_jdouble()), to_reg->as_register_lo()); | |
1263 #else | |
1264 __ set(low(jlong_cast(c->as_jdouble())), to_reg->as_register_lo()); | |
1265 __ set(high(jlong_cast(c->as_jdouble())), to_reg->as_register_hi()); | |
1266 #endif | |
1267 } | |
1268 | |
1269 } | |
1270 break; | |
1271 | |
1272 default: | |
1273 ShouldNotReachHere(); | |
1274 } | |
1275 } | |
1276 | |
1277 Address LIR_Assembler::as_Address(LIR_Address* addr) { | |
1278 Register reg = addr->base()->as_register(); | |
727 | 1279 return Address(reg, addr->disp()); |
0 | 1280 } |
1281 | |
1282 | |
1283 void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { | |
1284 switch (type) { | |
1285 case T_INT: | |
1286 case T_FLOAT: { | |
1287 Register tmp = O7; | |
1288 Address from = frame_map()->address_for_slot(src->single_stack_ix()); | |
1289 Address to = frame_map()->address_for_slot(dest->single_stack_ix()); | |
1290 __ lduw(from.base(), from.disp(), tmp); | |
1291 __ stw(tmp, to.base(), to.disp()); | |
1292 break; | |
1293 } | |
1294 case T_OBJECT: { | |
1295 Register tmp = O7; | |
1296 Address from = frame_map()->address_for_slot(src->single_stack_ix()); | |
1297 Address to = frame_map()->address_for_slot(dest->single_stack_ix()); | |
1298 __ ld_ptr(from.base(), from.disp(), tmp); | |
1299 __ st_ptr(tmp, to.base(), to.disp()); | |
1300 break; | |
1301 } | |
1302 case T_LONG: | |
1303 case T_DOUBLE: { | |
1304 Register tmp = O7; | |
1305 Address from = frame_map()->address_for_double_slot(src->double_stack_ix()); | |
1306 Address to = frame_map()->address_for_double_slot(dest->double_stack_ix()); | |
1307 __ lduw(from.base(), from.disp(), tmp); | |
1308 __ stw(tmp, to.base(), to.disp()); | |
1309 __ lduw(from.base(), from.disp() + 4, tmp); | |
1310 __ stw(tmp, to.base(), to.disp() + 4); | |
1311 break; | |
1312 } | |
1313 | |
1314 default: | |
1315 ShouldNotReachHere(); | |
1316 } | |
1317 } | |
1318 | |
1319 | |
1320 Address LIR_Assembler::as_Address_hi(LIR_Address* addr) { | |
1321 Address base = as_Address(addr); | |
727 | 1322 return Address(base.base(), base.disp() + hi_word_offset_in_bytes); |
0 | 1323 } |
1324 | |
1325 | |
1326 Address LIR_Assembler::as_Address_lo(LIR_Address* addr) { | |
1327 Address base = as_Address(addr); | |
727 | 1328 return Address(base.base(), base.disp() + lo_word_offset_in_bytes); |
0 | 1329 } |
1330 | |
1331 | |
1332 void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, | |
2002 | 1333 LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool unaligned) { |
0 | 1334 |
1335 LIR_Address* addr = src_opr->as_address_ptr(); | |
1336 LIR_Opr to_reg = dest; | |
1337 | |
1338 Register src = addr->base()->as_pointer_register(); | |
1339 Register disp_reg = noreg; | |
1340 int disp_value = addr->disp(); | |
1341 bool needs_patching = (patch_code != lir_patch_none); | |
1342 | |
1343 if (addr->base()->type() == T_OBJECT) { | |
1344 __ verify_oop(src); | |
1345 } | |
1346 | |
1347 PatchingStub* patch = NULL; | |
1348 if (needs_patching) { | |
1349 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | |
1350 assert(!to_reg->is_double_cpu() || | |
1351 patch_code == lir_patch_none || | |
1352 patch_code == lir_patch_normal, "patching doesn't match register"); | |
1353 } | |
1354 | |
1355 if (addr->index()->is_illegal()) { | |
1356 if (!Assembler::is_simm13(disp_value) && (!unaligned || Assembler::is_simm13(disp_value + 4))) { | |
1357 if (needs_patching) { | |
727 | 1358 __ patchable_set(0, O7); |
0 | 1359 } else { |
1360 __ set(disp_value, O7); | |
1361 } | |
1362 disp_reg = O7; | |
1363 } | |
1364 } else if (unaligned || PatchALot) { | |
1365 __ add(src, addr->index()->as_register(), O7); | |
1366 src = O7; | |
1367 } else { | |
1368 disp_reg = addr->index()->as_pointer_register(); | |
1369 assert(disp_value == 0, "can't handle 3 operand addresses"); | |
1370 } | |
1371 | |
1372 // remember the offset of the load. The patching_epilog must be done | |
1373 // before the call to add_debug_info, otherwise the PcDescs don't get | |
1374 // entered in increasing order. | |
1375 int offset = code_offset(); | |
1376 | |
1377 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); | |
1378 if (disp_reg == noreg) { | |
2002 | 1379 offset = load(src, disp_value, to_reg, type, wide, unaligned); |
0 | 1380 } else { |
1381 assert(!unaligned, "can't handle this"); | |
2002 | 1382 offset = load(src, disp_reg, to_reg, type, wide); |
0 | 1383 } |
1384 | |
1385 if (patch != NULL) { | |
1386 patching_epilog(patch, patch_code, src, info); | |
1387 } | |
1388 if (info != NULL) add_debug_info_for_null_check(offset, info); | |
1389 } | |
1390 | |
1391 | |
1392 void LIR_Assembler::prefetchr(LIR_Opr src) { | |
1393 LIR_Address* addr = src->as_address_ptr(); | |
1394 Address from_addr = as_Address(addr); | |
1395 | |
1396 if (VM_Version::has_v9()) { | |
1397 __ prefetch(from_addr, Assembler::severalReads); | |
1398 } | |
1399 } | |
1400 | |
1401 | |
1402 void LIR_Assembler::prefetchw(LIR_Opr src) { | |
1403 LIR_Address* addr = src->as_address_ptr(); | |
1404 Address from_addr = as_Address(addr); | |
1405 | |
1406 if (VM_Version::has_v9()) { | |
1407 __ prefetch(from_addr, Assembler::severalWritesAndPossiblyReads); | |
1408 } | |
1409 } | |
1410 | |
1411 | |
1412 void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { | |
1413 Address addr; | |
1414 if (src->is_single_word()) { | |
1415 addr = frame_map()->address_for_slot(src->single_stack_ix()); | |
1416 } else if (src->is_double_word()) { | |
1417 addr = frame_map()->address_for_double_slot(src->double_stack_ix()); | |
1418 } | |
1419 | |
1420 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; | |
2002 | 1421 load(addr.base(), addr.disp(), dest, dest->type(), true /*wide*/, unaligned); |
0 | 1422 } |
1423 | |
1424 | |
1425 void LIR_Assembler::reg2stack(LIR_Opr from_reg, LIR_Opr dest, BasicType type, bool pop_fpu_stack) { | |
1426 Address addr; | |
1427 if (dest->is_single_word()) { | |
1428 addr = frame_map()->address_for_slot(dest->single_stack_ix()); | |
1429 } else if (dest->is_double_word()) { | |
1430 addr = frame_map()->address_for_slot(dest->double_stack_ix()); | |
1431 } | |
1432 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0; | |
2002 | 1433 store(from_reg, addr.base(), addr.disp(), from_reg->type(), true /*wide*/, unaligned); |
0 | 1434 } |
1435 | |
1436 | |
1437 void LIR_Assembler::reg2reg(LIR_Opr from_reg, LIR_Opr to_reg) { | |
1438 if (from_reg->is_float_kind() && to_reg->is_float_kind()) { | |
1439 if (from_reg->is_double_fpu()) { | |
1440 // double to double moves | |
1441 assert(to_reg->is_double_fpu(), "should match"); | |
1442 __ fmov(FloatRegisterImpl::D, from_reg->as_double_reg(), to_reg->as_double_reg()); | |
1443 } else { | |
1444 // float to float moves | |
1445 assert(to_reg->is_single_fpu(), "should match"); | |
1446 __ fmov(FloatRegisterImpl::S, from_reg->as_float_reg(), to_reg->as_float_reg()); | |
1447 } | |
1448 } else if (!from_reg->is_float_kind() && !to_reg->is_float_kind()) { | |
1449 if (from_reg->is_double_cpu()) { | |
1450 #ifdef _LP64 | |
1451 __ mov(from_reg->as_pointer_register(), to_reg->as_pointer_register()); | |
1452 #else | |
1453 assert(to_reg->is_double_cpu() && | |
1454 from_reg->as_register_hi() != to_reg->as_register_lo() && | |
1455 from_reg->as_register_lo() != to_reg->as_register_hi(), | |
1456 "should both be long and not overlap"); | |
1457 // long to long moves | |
1458 __ mov(from_reg->as_register_hi(), to_reg->as_register_hi()); | |
1459 __ mov(from_reg->as_register_lo(), to_reg->as_register_lo()); | |
1460 #endif | |
1461 #ifdef _LP64 | |
1462 } else if (to_reg->is_double_cpu()) { | |
1463 // int to int moves | |
1464 __ mov(from_reg->as_register(), to_reg->as_register_lo()); | |
1465 #endif | |
1466 } else { | |
1467 // int to int moves | |
1468 __ mov(from_reg->as_register(), to_reg->as_register()); | |
1469 } | |
1470 } else { | |
1471 ShouldNotReachHere(); | |
1472 } | |
1473 if (to_reg->type() == T_OBJECT || to_reg->type() == T_ARRAY) { | |
1474 __ verify_oop(to_reg->as_register()); | |
1475 } | |
1476 } | |
1477 | |
1478 | |
1479 void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type, | |
1480 LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, | |
2002 | 1481 bool wide, bool unaligned) { |
0 | 1482 LIR_Address* addr = dest->as_address_ptr(); |
1483 | |
1484 Register src = addr->base()->as_pointer_register(); | |
1485 Register disp_reg = noreg; | |
1486 int disp_value = addr->disp(); | |
1487 bool needs_patching = (patch_code != lir_patch_none); | |
1488 | |
1489 if (addr->base()->is_oop_register()) { | |
1490 __ verify_oop(src); | |
1491 } | |
1492 | |
1493 PatchingStub* patch = NULL; | |
1494 if (needs_patching) { | |
1495 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | |
1496 assert(!from_reg->is_double_cpu() || | |
1497 patch_code == lir_patch_none || | |
1498 patch_code == lir_patch_normal, "patching doesn't match register"); | |
1499 } | |
1500 | |
1501 if (addr->index()->is_illegal()) { | |
1502 if (!Assembler::is_simm13(disp_value) && (!unaligned || Assembler::is_simm13(disp_value + 4))) { | |
1503 if (needs_patching) { | |
727 | 1504 __ patchable_set(0, O7); |
0 | 1505 } else { |
1506 __ set(disp_value, O7); | |
1507 } | |
1508 disp_reg = O7; | |
1509 } | |
1510 } else if (unaligned || PatchALot) { | |
1511 __ add(src, addr->index()->as_register(), O7); | |
1512 src = O7; | |
1513 } else { | |
1514 disp_reg = addr->index()->as_pointer_register(); | |
1515 assert(disp_value == 0, "can't handle 3 operand addresses"); | |
1516 } | |
1517 | |
1518 // remember the offset of the store. The patching_epilog must be done | |
1519 // before the call to add_debug_info_for_null_check, otherwise the PcDescs don't get | |
1520 // entered in increasing order. | |
1521 int offset; | |
1522 | |
1523 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up"); | |
1524 if (disp_reg == noreg) { | |
2002 | 1525 offset = store(from_reg, src, disp_value, type, wide, unaligned); |
0 | 1526 } else { |
1527 assert(!unaligned, "can't handle this"); | |
2002 | 1528 offset = store(from_reg, src, disp_reg, type, wide); |
0 | 1529 } |
1530 | |
1531 if (patch != NULL) { | |
1532 patching_epilog(patch, patch_code, src, info); | |
1533 } | |
1534 | |
1535 if (info != NULL) add_debug_info_for_null_check(offset, info); | |
1536 } | |
1537 | |
1538 | |
1539 void LIR_Assembler::return_op(LIR_Opr result) { | |
1540 // the poll may need a register so just pick one that isn't the return register | |
1783 | 1541 #if defined(TIERED) && !defined(_LP64) |
0 | 1542 if (result->type_field() == LIR_OprDesc::long_type) { |
1543 // Must move the result to G1 | |
1544 // Must leave proper result in O0,O1 and G1 (TIERED only) | |
1545 __ sllx(I0, 32, G1); // Shift bits into high G1 | |
1546 __ srl (I1, 0, I1); // Zero extend O1 (harmless?) | |
1547 __ or3 (I1, G1, G1); // OR 64 bits into G1 | |
1783 | 1548 #ifdef ASSERT |
1549 // mangle it so any problems will show up | |
1550 __ set(0xdeadbeef, I0); | |
1551 __ set(0xdeadbeef, I1); | |
1552 #endif | |
0 | 1553 } |
1554 #endif // TIERED | |
1555 __ set((intptr_t)os::get_polling_page(), L0); | |
1556 __ relocate(relocInfo::poll_return_type); | |
1557 __ ld_ptr(L0, 0, G0); | |
1558 __ ret(); | |
1559 __ delayed()->restore(); | |
1560 } | |
1561 | |
1562 | |
1563 int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { | |
1564 __ set((intptr_t)os::get_polling_page(), tmp->as_register()); | |
1565 if (info != NULL) { | |
1566 add_debug_info_for_branch(info); | |
1567 } else { | |
1568 __ relocate(relocInfo::poll_type); | |
1569 } | |
1570 | |
1571 int offset = __ offset(); | |
1572 __ ld_ptr(tmp->as_register(), 0, G0); | |
1573 | |
1574 return offset; | |
1575 } | |
1576 | |
1577 | |
1578 void LIR_Assembler::emit_static_call_stub() { | |
1579 address call_pc = __ pc(); | |
1580 address stub = __ start_a_stub(call_stub_size); | |
1581 if (stub == NULL) { | |
1582 bailout("static call stub overflow"); | |
1583 return; | |
1584 } | |
1585 | |
1586 int start = __ offset(); | |
1587 __ relocate(static_stub_Relocation::spec(call_pc)); | |
1588 | |
1589 __ set_oop(NULL, G5); | |
1590 // must be set to -1 at code generation time | |
727 | 1591 AddressLiteral addrlit(-1); |
1592 __ jump_to(addrlit, G3); | |
0 | 1593 __ delayed()->nop(); |
1594 | |
1595 assert(__ offset() - start <= call_stub_size, "stub too big"); | |
1596 __ end_a_stub(); | |
1597 } | |
1598 | |
1599 | |
1600 void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Op2* op) { | |
1601 if (opr1->is_single_fpu()) { | |
1602 __ fcmp(FloatRegisterImpl::S, Assembler::fcc0, opr1->as_float_reg(), opr2->as_float_reg()); | |
1603 } else if (opr1->is_double_fpu()) { | |
1604 __ fcmp(FloatRegisterImpl::D, Assembler::fcc0, opr1->as_double_reg(), opr2->as_double_reg()); | |
1605 } else if (opr1->is_single_cpu()) { | |
1606 if (opr2->is_constant()) { | |
1607 switch (opr2->as_constant_ptr()->type()) { | |
1608 case T_INT: | |
1609 { jint con = opr2->as_constant_ptr()->as_jint(); | |
1610 if (Assembler::is_simm13(con)) { | |
1611 __ cmp(opr1->as_register(), con); | |
1612 } else { | |
1613 __ set(con, O7); | |
1614 __ cmp(opr1->as_register(), O7); | |
1615 } | |
1616 } | |
1617 break; | |
1618 | |
1619 case T_OBJECT: | |
1620 // there are only equal/notequal comparisions on objects | |
1621 { jobject con = opr2->as_constant_ptr()->as_jobject(); | |
1622 if (con == NULL) { | |
1623 __ cmp(opr1->as_register(), 0); | |
1624 } else { | |
1625 jobject2reg(con, O7); | |
1626 __ cmp(opr1->as_register(), O7); | |
1627 } | |
1628 } | |
1629 break; | |
1630 | |
1631 default: | |
1632 ShouldNotReachHere(); | |
1633 break; | |
1634 } | |
1635 } else { | |
1636 if (opr2->is_address()) { | |
1637 LIR_Address * addr = opr2->as_address_ptr(); | |
1638 BasicType type = addr->type(); | |
1639 if ( type == T_OBJECT ) __ ld_ptr(as_Address(addr), O7); | |
1640 else __ ld(as_Address(addr), O7); | |
1641 __ cmp(opr1->as_register(), O7); | |
1642 } else { | |
1643 __ cmp(opr1->as_register(), opr2->as_register()); | |
1644 } | |
1645 } | |
1646 } else if (opr1->is_double_cpu()) { | |
1647 Register xlo = opr1->as_register_lo(); | |
1648 Register xhi = opr1->as_register_hi(); | |
1649 if (opr2->is_constant() && opr2->as_jlong() == 0) { | |
1650 assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "only handles these cases"); | |
1651 #ifdef _LP64 | |
1652 __ orcc(xhi, G0, G0); | |
1653 #else | |
1654 __ orcc(xhi, xlo, G0); | |
1655 #endif | |
1656 } else if (opr2->is_register()) { | |
1657 Register ylo = opr2->as_register_lo(); | |
1658 Register yhi = opr2->as_register_hi(); | |
1659 #ifdef _LP64 | |
1660 __ cmp(xlo, ylo); | |
1661 #else | |
1662 __ subcc(xlo, ylo, xlo); | |
1663 __ subccc(xhi, yhi, xhi); | |
1664 if (condition == lir_cond_equal || condition == lir_cond_notEqual) { | |
1665 __ orcc(xhi, xlo, G0); | |
1666 } | |
1667 #endif | |
1668 } else { | |
1669 ShouldNotReachHere(); | |
1670 } | |
1671 } else if (opr1->is_address()) { | |
1672 LIR_Address * addr = opr1->as_address_ptr(); | |
1673 BasicType type = addr->type(); | |
1674 assert (opr2->is_constant(), "Checking"); | |
1675 if ( type == T_OBJECT ) __ ld_ptr(as_Address(addr), O7); | |
1676 else __ ld(as_Address(addr), O7); | |
1677 __ cmp(O7, opr2->as_constant_ptr()->as_jint()); | |
1678 } else { | |
1679 ShouldNotReachHere(); | |
1680 } | |
1681 } | |
1682 | |
1683 | |
1684 void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op){ | |
1685 if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) { | |
1686 bool is_unordered_less = (code == lir_ucmp_fd2i); | |
1687 if (left->is_single_fpu()) { | |
1688 __ float_cmp(true, is_unordered_less ? -1 : 1, left->as_float_reg(), right->as_float_reg(), dst->as_register()); | |
1689 } else if (left->is_double_fpu()) { | |
1690 __ float_cmp(false, is_unordered_less ? -1 : 1, left->as_double_reg(), right->as_double_reg(), dst->as_register()); | |
1691 } else { | |
1692 ShouldNotReachHere(); | |
1693 } | |
1694 } else if (code == lir_cmp_l2i) { | |
1369 | 1695 #ifdef _LP64 |
1696 __ lcmp(left->as_register_lo(), right->as_register_lo(), dst->as_register()); | |
1697 #else | |
0 | 1698 __ lcmp(left->as_register_hi(), left->as_register_lo(), |
1699 right->as_register_hi(), right->as_register_lo(), | |
1700 dst->as_register()); | |
1369 | 1701 #endif |
0 | 1702 } else { |
1703 ShouldNotReachHere(); | |
1704 } | |
1705 } | |
1706 | |
1707 | |
1708 void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) { | |
1709 | |
1710 Assembler::Condition acond; | |
1711 switch (condition) { | |
1712 case lir_cond_equal: acond = Assembler::equal; break; | |
1713 case lir_cond_notEqual: acond = Assembler::notEqual; break; | |
1714 case lir_cond_less: acond = Assembler::less; break; | |
1715 case lir_cond_lessEqual: acond = Assembler::lessEqual; break; | |
1716 case lir_cond_greaterEqual: acond = Assembler::greaterEqual; break; | |
1717 case lir_cond_greater: acond = Assembler::greater; break; | |
1718 case lir_cond_aboveEqual: acond = Assembler::greaterEqualUnsigned; break; | |
1719 case lir_cond_belowEqual: acond = Assembler::lessEqualUnsigned; break; | |
1720 default: ShouldNotReachHere(); | |
1721 }; | |
1722 | |
1723 if (opr1->is_constant() && opr1->type() == T_INT) { | |
1724 Register dest = result->as_register(); | |
1725 // load up first part of constant before branch | |
1726 // and do the rest in the delay slot. | |
1727 if (!Assembler::is_simm13(opr1->as_jint())) { | |
1728 __ sethi(opr1->as_jint(), dest); | |
1729 } | |
1730 } else if (opr1->is_constant()) { | |
1731 const2reg(opr1, result, lir_patch_none, NULL); | |
1732 } else if (opr1->is_register()) { | |
1733 reg2reg(opr1, result); | |
1734 } else if (opr1->is_stack()) { | |
1735 stack2reg(opr1, result, result->type()); | |
1736 } else { | |
1737 ShouldNotReachHere(); | |
1738 } | |
1739 Label skip; | |
1740 __ br(acond, false, Assembler::pt, skip); | |
1741 if (opr1->is_constant() && opr1->type() == T_INT) { | |
1742 Register dest = result->as_register(); | |
1743 if (Assembler::is_simm13(opr1->as_jint())) { | |
1744 __ delayed()->or3(G0, opr1->as_jint(), dest); | |
1745 } else { | |
1746 // the sethi has been done above, so just put in the low 10 bits | |
1747 __ delayed()->or3(dest, opr1->as_jint() & 0x3ff, dest); | |
1748 } | |
1749 } else { | |
1750 // can't do anything useful in the delay slot | |
1751 __ delayed()->nop(); | |
1752 } | |
1753 if (opr2->is_constant()) { | |
1754 const2reg(opr2, result, lir_patch_none, NULL); | |
1755 } else if (opr2->is_register()) { | |
1756 reg2reg(opr2, result); | |
1757 } else if (opr2->is_stack()) { | |
1758 stack2reg(opr2, result, result->type()); | |
1759 } else { | |
1760 ShouldNotReachHere(); | |
1761 } | |
1762 __ bind(skip); | |
1763 } | |
1764 | |
1765 | |
1766 void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) { | |
1767 assert(info == NULL, "unused on this code path"); | |
1768 assert(left->is_register(), "wrong items state"); | |
1769 assert(dest->is_register(), "wrong items state"); | |
1770 | |
1771 if (right->is_register()) { | |
1772 if (dest->is_float_kind()) { | |
1773 | |
1774 FloatRegister lreg, rreg, res; | |
1775 FloatRegisterImpl::Width w; | |
1776 if (right->is_single_fpu()) { | |
1777 w = FloatRegisterImpl::S; | |
1778 lreg = left->as_float_reg(); | |
1779 rreg = right->as_float_reg(); | |
1780 res = dest->as_float_reg(); | |
1781 } else { | |
1782 w = FloatRegisterImpl::D; | |
1783 lreg = left->as_double_reg(); | |
1784 rreg = right->as_double_reg(); | |
1785 res = dest->as_double_reg(); | |
1786 } | |
1787 | |
1788 switch (code) { | |
1789 case lir_add: __ fadd(w, lreg, rreg, res); break; | |
1790 case lir_sub: __ fsub(w, lreg, rreg, res); break; | |
1791 case lir_mul: // fall through | |
1792 case lir_mul_strictfp: __ fmul(w, lreg, rreg, res); break; | |
1793 case lir_div: // fall through | |
1794 case lir_div_strictfp: __ fdiv(w, lreg, rreg, res); break; | |
1795 default: ShouldNotReachHere(); | |
1796 } | |
1797 | |
1798 } else if (dest->is_double_cpu()) { | |
1799 #ifdef _LP64 | |
1800 Register dst_lo = dest->as_register_lo(); | |
1801 Register op1_lo = left->as_pointer_register(); | |
1802 Register op2_lo = right->as_pointer_register(); | |
1803 | |
1804 switch (code) { | |
1805 case lir_add: | |
1806 __ add(op1_lo, op2_lo, dst_lo); | |
1807 break; | |
1808 | |
1809 case lir_sub: | |
1810 __ sub(op1_lo, op2_lo, dst_lo); | |
1811 break; | |
1812 | |
1813 default: ShouldNotReachHere(); | |
1814 } | |
1815 #else | |
1816 Register op1_lo = left->as_register_lo(); | |
1817 Register op1_hi = left->as_register_hi(); | |
1818 Register op2_lo = right->as_register_lo(); | |
1819 Register op2_hi = right->as_register_hi(); | |
1820 Register dst_lo = dest->as_register_lo(); | |
1821 Register dst_hi = dest->as_register_hi(); | |
1822 | |
1823 switch (code) { | |
1824 case lir_add: | |
1825 __ addcc(op1_lo, op2_lo, dst_lo); | |
1826 __ addc (op1_hi, op2_hi, dst_hi); | |
1827 break; | |
1828 | |
1829 case lir_sub: | |
1830 __ subcc(op1_lo, op2_lo, dst_lo); | |
1831 __ subc (op1_hi, op2_hi, dst_hi); | |
1832 break; | |
1833 | |
1834 default: ShouldNotReachHere(); | |
1835 } | |
1836 #endif | |
1837 } else { | |
1838 assert (right->is_single_cpu(), "Just Checking"); | |
1839 | |
1840 Register lreg = left->as_register(); | |
1841 Register res = dest->as_register(); | |
1842 Register rreg = right->as_register(); | |
1843 switch (code) { | |
1844 case lir_add: __ add (lreg, rreg, res); break; | |
1845 case lir_sub: __ sub (lreg, rreg, res); break; | |
1846 case lir_mul: __ mult (lreg, rreg, res); break; | |
1847 default: ShouldNotReachHere(); | |
1848 } | |
1849 } | |
1850 } else { | |
1851 assert (right->is_constant(), "must be constant"); | |
1852 | |
1853 if (dest->is_single_cpu()) { | |
1854 Register lreg = left->as_register(); | |
1855 Register res = dest->as_register(); | |
1856 int simm13 = right->as_constant_ptr()->as_jint(); | |
1857 | |
1858 switch (code) { | |
1859 case lir_add: __ add (lreg, simm13, res); break; | |
1860 case lir_sub: __ sub (lreg, simm13, res); break; | |
1861 case lir_mul: __ mult (lreg, simm13, res); break; | |
1862 default: ShouldNotReachHere(); | |
1863 } | |
1864 } else { | |
1865 Register lreg = left->as_pointer_register(); | |
1866 Register res = dest->as_register_lo(); | |
1867 long con = right->as_constant_ptr()->as_jlong(); | |
1868 assert(Assembler::is_simm13(con), "must be simm13"); | |
1869 | |
1870 switch (code) { | |
1871 case lir_add: __ add (lreg, (int)con, res); break; | |
1872 case lir_sub: __ sub (lreg, (int)con, res); break; | |
1873 case lir_mul: __ mult (lreg, (int)con, res); break; | |
1874 default: ShouldNotReachHere(); | |
1875 } | |
1876 } | |
1877 } | |
1878 } | |
1879 | |
1880 | |
1881 void LIR_Assembler::fpop() { | |
1882 // do nothing | |
1883 } | |
1884 | |
1885 | |
1886 void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr thread, LIR_Opr dest, LIR_Op* op) { | |
1887 switch (code) { | |
1888 case lir_sin: | |
1889 case lir_tan: | |
1890 case lir_cos: { | |
1891 assert(thread->is_valid(), "preserve the thread object for performance reasons"); | |
1892 assert(dest->as_double_reg() == F0, "the result will be in f0/f1"); | |
1893 break; | |
1894 } | |
1895 case lir_sqrt: { | |
1896 assert(!thread->is_valid(), "there is no need for a thread_reg for dsqrt"); | |
1897 FloatRegister src_reg = value->as_double_reg(); | |
1898 FloatRegister dst_reg = dest->as_double_reg(); | |
1899 __ fsqrt(FloatRegisterImpl::D, src_reg, dst_reg); | |
1900 break; | |
1901 } | |
1902 case lir_abs: { | |
1903 assert(!thread->is_valid(), "there is no need for a thread_reg for fabs"); | |
1904 FloatRegister src_reg = value->as_double_reg(); | |
1905 FloatRegister dst_reg = dest->as_double_reg(); | |
1906 __ fabs(FloatRegisterImpl::D, src_reg, dst_reg); | |
1907 break; | |
1908 } | |
1909 default: { | |
1910 ShouldNotReachHere(); | |
1911 break; | |
1912 } | |
1913 } | |
1914 } | |
1915 | |
1916 | |
1917 void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest) { | |
1918 if (right->is_constant()) { | |
1919 if (dest->is_single_cpu()) { | |
1920 int simm13 = right->as_constant_ptr()->as_jint(); | |
1921 switch (code) { | |
1922 case lir_logic_and: __ and3 (left->as_register(), simm13, dest->as_register()); break; | |
1923 case lir_logic_or: __ or3 (left->as_register(), simm13, dest->as_register()); break; | |
1924 case lir_logic_xor: __ xor3 (left->as_register(), simm13, dest->as_register()); break; | |
1925 default: ShouldNotReachHere(); | |
1926 } | |
1927 } else { | |
1928 long c = right->as_constant_ptr()->as_jlong(); | |
1929 assert(c == (int)c && Assembler::is_simm13(c), "out of range"); | |
1930 int simm13 = (int)c; | |
1931 switch (code) { | |
1932 case lir_logic_and: | |
1933 #ifndef _LP64 | |
1934 __ and3 (left->as_register_hi(), 0, dest->as_register_hi()); | |
1935 #endif | |
1936 __ and3 (left->as_register_lo(), simm13, dest->as_register_lo()); | |
1937 break; | |
1938 | |
1939 case lir_logic_or: | |
1940 #ifndef _LP64 | |
1941 __ or3 (left->as_register_hi(), 0, dest->as_register_hi()); | |
1942 #endif | |
1943 __ or3 (left->as_register_lo(), simm13, dest->as_register_lo()); | |
1944 break; | |
1945 | |
1946 case lir_logic_xor: | |
1947 #ifndef _LP64 | |
1948 __ xor3 (left->as_register_hi(), 0, dest->as_register_hi()); | |
1949 #endif | |
1950 __ xor3 (left->as_register_lo(), simm13, dest->as_register_lo()); | |
1951 break; | |
1952 | |
1953 default: ShouldNotReachHere(); | |
1954 } | |
1955 } | |
1956 } else { | |
1957 assert(right->is_register(), "right should be in register"); | |
1958 | |
1959 if (dest->is_single_cpu()) { | |
1960 switch (code) { | |
1961 case lir_logic_and: __ and3 (left->as_register(), right->as_register(), dest->as_register()); break; | |
1962 case lir_logic_or: __ or3 (left->as_register(), right->as_register(), dest->as_register()); break; | |
1963 case lir_logic_xor: __ xor3 (left->as_register(), right->as_register(), dest->as_register()); break; | |
1964 default: ShouldNotReachHere(); | |
1965 } | |
1966 } else { | |
1967 #ifdef _LP64 | |
1968 Register l = (left->is_single_cpu() && left->is_oop_register()) ? left->as_register() : | |
1969 left->as_register_lo(); | |
1970 Register r = (right->is_single_cpu() && right->is_oop_register()) ? right->as_register() : | |
1971 right->as_register_lo(); | |
1972 | |
1973 switch (code) { | |
1974 case lir_logic_and: __ and3 (l, r, dest->as_register_lo()); break; | |
1975 case lir_logic_or: __ or3 (l, r, dest->as_register_lo()); break; | |
1976 case lir_logic_xor: __ xor3 (l, r, dest->as_register_lo()); break; | |
1977 default: ShouldNotReachHere(); | |
1978 } | |
1979 #else | |
1980 switch (code) { | |
1981 case lir_logic_and: | |
1982 __ and3 (left->as_register_hi(), right->as_register_hi(), dest->as_register_hi()); | |
1983 __ and3 (left->as_register_lo(), right->as_register_lo(), dest->as_register_lo()); | |
1984 break; | |
1985 | |
1986 case lir_logic_or: | |
1987 __ or3 (left->as_register_hi(), right->as_register_hi(), dest->as_register_hi()); | |
1988 __ or3 (left->as_register_lo(), right->as_register_lo(), dest->as_register_lo()); | |
1989 break; | |
1990 | |
1991 case lir_logic_xor: | |
1992 __ xor3 (left->as_register_hi(), right->as_register_hi(), dest->as_register_hi()); | |
1993 __ xor3 (left->as_register_lo(), right->as_register_lo(), dest->as_register_lo()); | |
1994 break; | |
1995 | |
1996 default: ShouldNotReachHere(); | |
1997 } | |
1998 #endif | |
1999 } | |
2000 } | |
2001 } | |
2002 | |
2003 | |
2004 int LIR_Assembler::shift_amount(BasicType t) { | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
2005 int elem_size = type2aelembytes(t); |
0 | 2006 switch (elem_size) { |
2007 case 1 : return 0; | |
2008 case 2 : return 1; | |
2009 case 4 : return 2; | |
2010 case 8 : return 3; | |
2011 } | |
2012 ShouldNotReachHere(); | |
2013 return -1; | |
2014 } | |
2015 | |
2016 | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2017 void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { |
0 | 2018 assert(exceptionOop->as_register() == Oexception, "should match"); |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2019 assert(exceptionPC->as_register() == Oissuing_pc, "should match"); |
0 | 2020 |
2021 info->add_register_oop(exceptionOop); | |
2022 | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2023 // reuse the debug info from the safepoint poll for the throw op itself |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2024 address pc_for_athrow = __ pc(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2025 int pc_for_athrow_offset = __ offset(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2026 RelocationHolder rspec = internal_word_Relocation::spec(pc_for_athrow); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2027 __ set(pc_for_athrow, Oissuing_pc, rspec); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2028 add_call_info(pc_for_athrow_offset, info); // for exception handler |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2029 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2030 __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2031 __ delayed()->nop(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2032 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2033 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2034 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2035 void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2036 assert(exceptionOop->as_register() == Oexception, "should match"); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2037 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2038 __ br(Assembler::always, false, Assembler::pt, _unwind_handler_entry); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2039 __ delayed()->nop(); |
0 | 2040 } |
2041 | |
2042 | |
2043 void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { | |
2044 Register src = op->src()->as_register(); | |
2045 Register dst = op->dst()->as_register(); | |
2046 Register src_pos = op->src_pos()->as_register(); | |
2047 Register dst_pos = op->dst_pos()->as_register(); | |
2048 Register length = op->length()->as_register(); | |
2049 Register tmp = op->tmp()->as_register(); | |
2050 Register tmp2 = O7; | |
2051 | |
2052 int flags = op->flags(); | |
2053 ciArrayKlass* default_type = op->expected_type(); | |
2054 BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL; | |
2055 if (basic_type == T_ARRAY) basic_type = T_OBJECT; | |
2056 | |
2057 // set up the arraycopy stub information | |
2058 ArrayCopyStub* stub = op->stub(); | |
2059 | |
2060 // always do stub if no type information is available. it's ok if | |
2061 // the known type isn't loaded since the code sanity checks | |
2062 // in debug mode and the type isn't required when we know the exact type | |
2063 // also check that the type is an array type. | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
2064 // We also, for now, always call the stub if the barrier set requires a |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
2065 // write_ref_pre barrier (which the stub does, but none of the optimized |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
2066 // cases currently does). |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
2067 if (op->expected_type() == NULL || |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
29
diff
changeset
|
2068 Universe::heap()->barrier_set()->has_write_ref_pre_barrier()) { |
0 | 2069 __ mov(src, O0); |
2070 __ mov(src_pos, O1); | |
2071 __ mov(dst, O2); | |
2072 __ mov(dst_pos, O3); | |
2073 __ mov(length, O4); | |
2074 __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::arraycopy)); | |
2075 | |
2076 __ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry()); | |
2077 __ delayed()->nop(); | |
2078 __ bind(*stub->continuation()); | |
2079 return; | |
2080 } | |
2081 | |
2082 assert(default_type != NULL && default_type->is_array_klass(), "must be true at this point"); | |
2083 | |
2084 // make sure src and dst are non-null and load array length | |
2085 if (flags & LIR_OpArrayCopy::src_null_check) { | |
2086 __ tst(src); | |
2002 | 2087 __ brx(Assembler::equal, false, Assembler::pn, *stub->entry()); |
0 | 2088 __ delayed()->nop(); |
2089 } | |
2090 | |
2091 if (flags & LIR_OpArrayCopy::dst_null_check) { | |
2092 __ tst(dst); | |
2002 | 2093 __ brx(Assembler::equal, false, Assembler::pn, *stub->entry()); |
0 | 2094 __ delayed()->nop(); |
2095 } | |
2096 | |
2097 if (flags & LIR_OpArrayCopy::src_pos_positive_check) { | |
2098 // test src_pos register | |
2099 __ tst(src_pos); | |
2100 __ br(Assembler::less, false, Assembler::pn, *stub->entry()); | |
2101 __ delayed()->nop(); | |
2102 } | |
2103 | |
2104 if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { | |
2105 // test dst_pos register | |
2106 __ tst(dst_pos); | |
2107 __ br(Assembler::less, false, Assembler::pn, *stub->entry()); | |
2108 __ delayed()->nop(); | |
2109 } | |
2110 | |
2111 if (flags & LIR_OpArrayCopy::length_positive_check) { | |
2112 // make sure length isn't negative | |
2113 __ tst(length); | |
2114 __ br(Assembler::less, false, Assembler::pn, *stub->entry()); | |
2115 __ delayed()->nop(); | |
2116 } | |
2117 | |
2118 if (flags & LIR_OpArrayCopy::src_range_check) { | |
2119 __ ld(src, arrayOopDesc::length_offset_in_bytes(), tmp2); | |
2120 __ add(length, src_pos, tmp); | |
2121 __ cmp(tmp2, tmp); | |
2122 __ br(Assembler::carrySet, false, Assembler::pn, *stub->entry()); | |
2123 __ delayed()->nop(); | |
2124 } | |
2125 | |
2126 if (flags & LIR_OpArrayCopy::dst_range_check) { | |
2127 __ ld(dst, arrayOopDesc::length_offset_in_bytes(), tmp2); | |
2128 __ add(length, dst_pos, tmp); | |
2129 __ cmp(tmp2, tmp); | |
2130 __ br(Assembler::carrySet, false, Assembler::pn, *stub->entry()); | |
2131 __ delayed()->nop(); | |
2132 } | |
2133 | |
2134 if (flags & LIR_OpArrayCopy::type_check) { | |
2002 | 2135 if (UseCompressedOops) { |
2136 // We don't need decode because we just need to compare | |
2137 __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp); | |
2138 __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); | |
2139 __ cmp(tmp, tmp2); | |
2140 __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry()); | |
2141 } else { | |
2142 __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp); | |
2143 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); | |
2144 __ cmp(tmp, tmp2); | |
2145 __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry()); | |
2146 } | |
0 | 2147 __ delayed()->nop(); |
2148 } | |
2149 | |
2150 #ifdef ASSERT | |
2151 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { | |
2152 // Sanity check the known type with the incoming class. For the | |
2153 // primitive case the types must match exactly with src.klass and | |
2154 // dst.klass each exactly matching the default type. For the | |
2155 // object array case, if no type check is needed then either the | |
2156 // dst type is exactly the expected type and the src type is a | |
2157 // subtype which we can't check or src is the same array as dst | |
2158 // but not necessarily exactly of type default_type. | |
2159 Label known_ok, halt; | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
780
diff
changeset
|
2160 jobject2reg(op->expected_type()->constant_encoding(), tmp); |
2002 | 2161 if (UseCompressedOops) { |
2162 // tmp holds the default type. It currently comes uncompressed after the | |
2163 // load of a constant, so encode it. | |
2164 __ encode_heap_oop(tmp); | |
2165 // load the raw value of the dst klass, since we will be comparing | |
2166 // uncompressed values directly. | |
2167 __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); | |
2168 if (basic_type != T_OBJECT) { | |
2169 __ cmp(tmp, tmp2); | |
2170 __ br(Assembler::notEqual, false, Assembler::pn, halt); | |
2171 // load the raw value of the src klass. | |
2172 __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2); | |
2173 __ cmp(tmp, tmp2); | |
2174 __ br(Assembler::equal, false, Assembler::pn, known_ok); | |
2175 __ delayed()->nop(); | |
2176 } else { | |
2177 __ cmp(tmp, tmp2); | |
2178 __ br(Assembler::equal, false, Assembler::pn, known_ok); | |
2179 __ delayed()->cmp(src, dst); | |
2180 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2181 __ delayed()->nop(); | |
2182 } | |
0 | 2183 } else { |
2002 | 2184 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2); |
2185 if (basic_type != T_OBJECT) { | |
2186 __ cmp(tmp, tmp2); | |
2187 __ brx(Assembler::notEqual, false, Assembler::pn, halt); | |
2188 __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); | |
2189 __ cmp(tmp, tmp2); | |
2190 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2191 __ delayed()->nop(); | |
2192 } else { | |
2193 __ cmp(tmp, tmp2); | |
2194 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2195 __ delayed()->cmp(src, dst); | |
2196 __ brx(Assembler::equal, false, Assembler::pn, known_ok); | |
2197 __ delayed()->nop(); | |
2198 } | |
0 | 2199 } |
2200 __ bind(halt); | |
2201 __ stop("incorrect type information in arraycopy"); | |
2202 __ bind(known_ok); | |
2203 } | |
2204 #endif | |
2205 | |
2206 int shift = shift_amount(basic_type); | |
2207 | |
2208 Register src_ptr = O0; | |
2209 Register dst_ptr = O1; | |
2210 Register len = O2; | |
2211 | |
2212 __ add(src, arrayOopDesc::base_offset_in_bytes(basic_type), src_ptr); | |
1060 | 2213 LP64_ONLY(__ sra(src_pos, 0, src_pos);) //higher 32bits must be null |
0 | 2214 if (shift == 0) { |
2215 __ add(src_ptr, src_pos, src_ptr); | |
2216 } else { | |
2217 __ sll(src_pos, shift, tmp); | |
2218 __ add(src_ptr, tmp, src_ptr); | |
2219 } | |
2220 | |
2221 __ add(dst, arrayOopDesc::base_offset_in_bytes(basic_type), dst_ptr); | |
1060 | 2222 LP64_ONLY(__ sra(dst_pos, 0, dst_pos);) //higher 32bits must be null |
0 | 2223 if (shift == 0) { |
2224 __ add(dst_ptr, dst_pos, dst_ptr); | |
2225 } else { | |
2226 __ sll(dst_pos, shift, tmp); | |
2227 __ add(dst_ptr, tmp, dst_ptr); | |
2228 } | |
2229 | |
2230 if (basic_type != T_OBJECT) { | |
2231 if (shift == 0) { | |
2232 __ mov(length, len); | |
2233 } else { | |
2234 __ sll(length, shift, len); | |
2235 } | |
2236 __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::primitive_arraycopy)); | |
2237 } else { | |
2238 // oop_arraycopy takes a length in number of elements, so don't scale it. | |
2239 __ mov(length, len); | |
2240 __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy)); | |
2241 } | |
2242 | |
2243 __ bind(*stub->continuation()); | |
2244 } | |
2245 | |
2246 | |
2247 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) { | |
2248 if (dest->is_single_cpu()) { | |
2249 #ifdef _LP64 | |
2250 if (left->type() == T_OBJECT) { | |
2251 switch (code) { | |
2252 case lir_shl: __ sllx (left->as_register(), count->as_register(), dest->as_register()); break; | |
2253 case lir_shr: __ srax (left->as_register(), count->as_register(), dest->as_register()); break; | |
2254 case lir_ushr: __ srl (left->as_register(), count->as_register(), dest->as_register()); break; | |
2255 default: ShouldNotReachHere(); | |
2256 } | |
2257 } else | |
2258 #endif | |
2259 switch (code) { | |
2260 case lir_shl: __ sll (left->as_register(), count->as_register(), dest->as_register()); break; | |
2261 case lir_shr: __ sra (left->as_register(), count->as_register(), dest->as_register()); break; | |
2262 case lir_ushr: __ srl (left->as_register(), count->as_register(), dest->as_register()); break; | |
2263 default: ShouldNotReachHere(); | |
2264 } | |
2265 } else { | |
2266 #ifdef _LP64 | |
2267 switch (code) { | |
2268 case lir_shl: __ sllx (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break; | |
2269 case lir_shr: __ srax (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break; | |
2270 case lir_ushr: __ srlx (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break; | |
2271 default: ShouldNotReachHere(); | |
2272 } | |
2273 #else | |
2274 switch (code) { | |
2275 case lir_shl: __ lshl (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break; | |
2276 case lir_shr: __ lshr (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break; | |
2277 case lir_ushr: __ lushr (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break; | |
2278 default: ShouldNotReachHere(); | |
2279 } | |
2280 #endif | |
2281 } | |
2282 } | |
2283 | |
2284 | |
2285 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) { | |
2286 #ifdef _LP64 | |
2287 if (left->type() == T_OBJECT) { | |
2288 count = count & 63; // shouldn't shift by more than sizeof(intptr_t) | |
2289 Register l = left->as_register(); | |
2290 Register d = dest->as_register_lo(); | |
2291 switch (code) { | |
2292 case lir_shl: __ sllx (l, count, d); break; | |
2293 case lir_shr: __ srax (l, count, d); break; | |
2294 case lir_ushr: __ srlx (l, count, d); break; | |
2295 default: ShouldNotReachHere(); | |
2296 } | |
2297 return; | |
2298 } | |
2299 #endif | |
2300 | |
2301 if (dest->is_single_cpu()) { | |
2302 count = count & 0x1F; // Java spec | |
2303 switch (code) { | |
2304 case lir_shl: __ sll (left->as_register(), count, dest->as_register()); break; | |
2305 case lir_shr: __ sra (left->as_register(), count, dest->as_register()); break; | |
2306 case lir_ushr: __ srl (left->as_register(), count, dest->as_register()); break; | |
2307 default: ShouldNotReachHere(); | |
2308 } | |
2309 } else if (dest->is_double_cpu()) { | |
2310 count = count & 63; // Java spec | |
2311 switch (code) { | |
2312 case lir_shl: __ sllx (left->as_pointer_register(), count, dest->as_pointer_register()); break; | |
2313 case lir_shr: __ srax (left->as_pointer_register(), count, dest->as_pointer_register()); break; | |
2314 case lir_ushr: __ srlx (left->as_pointer_register(), count, dest->as_pointer_register()); break; | |
2315 default: ShouldNotReachHere(); | |
2316 } | |
2317 } else { | |
2318 ShouldNotReachHere(); | |
2319 } | |
2320 } | |
2321 | |
2322 | |
2323 void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { | |
2324 assert(op->tmp1()->as_register() == G1 && | |
2325 op->tmp2()->as_register() == G3 && | |
2326 op->tmp3()->as_register() == G4 && | |
2327 op->obj()->as_register() == O0 && | |
2328 op->klass()->as_register() == G5, "must be"); | |
2329 if (op->init_check()) { | |
2330 __ ld(op->klass()->as_register(), | |
2331 instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), | |
2332 op->tmp1()->as_register()); | |
2333 add_debug_info_for_null_check_here(op->stub()->info()); | |
2334 __ cmp(op->tmp1()->as_register(), instanceKlass::fully_initialized); | |
2335 __ br(Assembler::notEqual, false, Assembler::pn, *op->stub()->entry()); | |
2336 __ delayed()->nop(); | |
2337 } | |
2338 __ allocate_object(op->obj()->as_register(), | |
2339 op->tmp1()->as_register(), | |
2340 op->tmp2()->as_register(), | |
2341 op->tmp3()->as_register(), | |
2342 op->header_size(), | |
2343 op->object_size(), | |
2344 op->klass()->as_register(), | |
2345 *op->stub()->entry()); | |
2346 __ bind(*op->stub()->continuation()); | |
2347 __ verify_oop(op->obj()->as_register()); | |
2348 } | |
2349 | |
2350 | |
2351 void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { | |
2352 assert(op->tmp1()->as_register() == G1 && | |
2353 op->tmp2()->as_register() == G3 && | |
2354 op->tmp3()->as_register() == G4 && | |
2355 op->tmp4()->as_register() == O1 && | |
2356 op->klass()->as_register() == G5, "must be"); | |
2357 if (UseSlowPath || | |
2358 (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) || | |
2359 (!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) { | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2360 __ br(Assembler::always, false, Assembler::pt, *op->stub()->entry()); |
0 | 2361 __ delayed()->nop(); |
2362 } else { | |
2363 __ allocate_array(op->obj()->as_register(), | |
2364 op->len()->as_register(), | |
2365 op->tmp1()->as_register(), | |
2366 op->tmp2()->as_register(), | |
2367 op->tmp3()->as_register(), | |
2368 arrayOopDesc::header_size(op->type()), | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
2369 type2aelembytes(op->type()), |
0 | 2370 op->klass()->as_register(), |
2371 *op->stub()->entry()); | |
2372 } | |
2373 __ bind(*op->stub()->continuation()); | |
2374 } | |
2375 | |
2376 | |
1783 | 2377 void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias, |
2378 ciMethodData *md, ciProfileData *data, | |
2379 Register recv, Register tmp1, Label* update_done) { | |
2380 uint i; | |
2381 for (i = 0; i < VirtualCallData::row_limit(); i++) { | |
2382 Label next_test; | |
2383 // See if the receiver is receiver[n]. | |
2384 Address receiver_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - | |
2385 mdo_offset_bias); | |
2386 __ ld_ptr(receiver_addr, tmp1); | |
2387 __ verify_oop(tmp1); | |
2388 __ cmp(recv, tmp1); | |
2389 __ brx(Assembler::notEqual, false, Assembler::pt, next_test); | |
2390 __ delayed()->nop(); | |
2391 Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - | |
2392 mdo_offset_bias); | |
2393 __ ld_ptr(data_addr, tmp1); | |
2394 __ add(tmp1, DataLayout::counter_increment, tmp1); | |
2395 __ st_ptr(tmp1, data_addr); | |
2396 __ ba(false, *update_done); | |
2397 __ delayed()->nop(); | |
2398 __ bind(next_test); | |
2399 } | |
2400 | |
2401 // Didn't find receiver; find next empty slot and fill it in | |
2402 for (i = 0; i < VirtualCallData::row_limit(); i++) { | |
2403 Label next_test; | |
2404 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - | |
2405 mdo_offset_bias); | |
2002 | 2406 __ ld_ptr(recv_addr, tmp1); |
1783 | 2407 __ br_notnull(tmp1, false, Assembler::pt, next_test); |
2408 __ delayed()->nop(); | |
2409 __ st_ptr(recv, recv_addr); | |
2410 __ set(DataLayout::counter_increment, tmp1); | |
2411 __ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - | |
2412 mdo_offset_bias); | |
2413 __ ba(false, *update_done); | |
2414 __ delayed()->nop(); | |
2415 __ bind(next_test); | |
2416 } | |
2417 } | |
2418 | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2419 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2420 void LIR_Assembler::setup_md_access(ciMethod* method, int bci, |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2421 ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias) { |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
2422 md = method->method_data_or_null(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
2423 assert(md != NULL, "Sanity"); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2424 data = md->bci_to_data(bci); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2425 assert(data != NULL, "need data for checkcast"); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2426 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2427 if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2428 // The offset is large so bias the mdo by the base of the slot so |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2429 // that the ld can use simm13s to reference the slots of the data |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2430 mdo_offset_bias = md->byte_offset_of_slot(data, DataLayout::header_offset()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2431 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2432 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2433 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2434 void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) { |
1783 | 2435 // we always need a stub for the failure case. |
2436 CodeStub* stub = op->stub(); | |
2437 Register obj = op->object()->as_register(); | |
2438 Register k_RInfo = op->tmp1()->as_register(); | |
2439 Register klass_RInfo = op->tmp2()->as_register(); | |
2440 Register dst = op->result_opr()->as_register(); | |
2441 Register Rtmp1 = op->tmp3()->as_register(); | |
2442 ciKlass* k = op->klass(); | |
2443 | |
2444 | |
2445 if (obj == k_RInfo) { | |
2446 k_RInfo = klass_RInfo; | |
2447 klass_RInfo = obj; | |
2448 } | |
2449 | |
2450 ciMethodData* md; | |
2451 ciProfileData* data; | |
2452 int mdo_offset_bias = 0; | |
2453 if (op->should_profile()) { | |
2454 ciMethod* method = op->profiled_method(); | |
2455 assert(method != NULL, "Should have method"); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2456 setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2457 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2458 Label not_null; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2459 __ br_notnull(obj, false, Assembler::pn, not_null); |
1783 | 2460 __ delayed()->nop(); |
2461 Register mdo = k_RInfo; | |
2462 Register data_val = Rtmp1; | |
2463 jobject2reg(md->constant_encoding(), mdo); | |
2464 if (mdo_offset_bias > 0) { | |
2465 __ set(mdo_offset_bias, data_val); | |
2466 __ add(mdo, data_val, mdo); | |
2467 } | |
2468 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); | |
2469 __ ldub(flags_addr, data_val); | |
2470 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); | |
2471 __ stb(data_val, flags_addr); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2472 __ ba(false, *obj_is_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2473 __ delayed()->nop(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2474 __ bind(not_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2475 } else { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2476 __ br_null(obj, false, Assembler::pn, *obj_is_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2477 __ delayed()->nop(); |
1783 | 2478 } |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2479 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2480 Label profile_cast_failure, profile_cast_success; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2481 Label *failure_target = op->should_profile() ? &profile_cast_failure : failure; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2482 Label *success_target = op->should_profile() ? &profile_cast_success : success; |
1783 | 2483 |
2484 // patching may screw with our temporaries on sparc, | |
2485 // so let's do it before loading the class | |
2486 if (k->is_loaded()) { | |
2487 jobject2reg(k->constant_encoding(), k_RInfo); | |
2488 } else { | |
2489 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); | |
2490 } | |
2491 assert(obj != k_RInfo, "must be different"); | |
2492 | |
2493 // get object class | |
2494 // not a safepoint as obj null check happens earlier | |
2002 | 2495 __ load_klass(obj, klass_RInfo); |
1783 | 2496 if (op->fast_check()) { |
2497 assert_different_registers(klass_RInfo, k_RInfo); | |
2498 __ cmp(k_RInfo, klass_RInfo); | |
2499 __ brx(Assembler::notEqual, false, Assembler::pt, *failure_target); | |
2500 __ delayed()->nop(); | |
2501 } else { | |
2502 bool need_slow_path = true; | |
2503 if (k->is_loaded()) { | |
2504 if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()) | |
2505 need_slow_path = false; | |
2506 // perform the fast part of the checking logic | |
2507 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg, | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2508 (need_slow_path ? success_target : NULL), |
1783 | 2509 failure_target, NULL, |
2510 RegisterOrConstant(k->super_check_offset())); | |
2511 } else { | |
2512 // perform the fast part of the checking logic | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2513 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, |
1783 | 2514 failure_target, NULL); |
2515 } | |
2516 if (need_slow_path) { | |
2517 // call out-of-line instance of __ check_klass_subtype_slow_path(...): | |
2518 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); | |
2519 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); | |
2520 __ delayed()->nop(); | |
2521 __ cmp(G3, 0); | |
2522 __ br(Assembler::equal, false, Assembler::pn, *failure_target); | |
2523 __ delayed()->nop(); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2524 // Fall through to success case |
1783 | 2525 } |
2526 } | |
2527 | |
2528 if (op->should_profile()) { | |
2529 Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1; | |
2530 assert_different_registers(obj, mdo, recv, tmp1); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2531 __ bind(profile_cast_success); |
1783 | 2532 jobject2reg(md->constant_encoding(), mdo); |
2533 if (mdo_offset_bias > 0) { | |
2534 __ set(mdo_offset_bias, tmp1); | |
2535 __ add(mdo, tmp1, mdo); | |
2536 } | |
2002 | 2537 __ load_klass(obj, recv); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2538 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); |
1783 | 2539 // Jump over the failure case |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2540 __ ba(false, *success); |
1783 | 2541 __ delayed()->nop(); |
2542 // Cast failure case | |
2543 __ bind(profile_cast_failure); | |
2544 jobject2reg(md->constant_encoding(), mdo); | |
2545 if (mdo_offset_bias > 0) { | |
2546 __ set(mdo_offset_bias, tmp1); | |
2547 __ add(mdo, tmp1, mdo); | |
2548 } | |
2549 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); | |
2550 __ ld_ptr(data_addr, tmp1); | |
2551 __ sub(tmp1, DataLayout::counter_increment, tmp1); | |
2552 __ st_ptr(tmp1, data_addr); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2553 __ ba(false, *failure); |
1783 | 2554 __ delayed()->nop(); |
2555 } | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2556 __ ba(false, *success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2557 __ delayed()->nop(); |
1783 | 2558 } |
2559 | |
0 | 2560 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { |
2561 LIR_Code code = op->code(); | |
2562 if (code == lir_store_check) { | |
2563 Register value = op->object()->as_register(); | |
2564 Register array = op->array()->as_register(); | |
2565 Register k_RInfo = op->tmp1()->as_register(); | |
2566 Register klass_RInfo = op->tmp2()->as_register(); | |
2567 Register Rtmp1 = op->tmp3()->as_register(); | |
2568 | |
2569 __ verify_oop(value); | |
2570 CodeStub* stub = op->stub(); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2571 // check if it needs to be profiled |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2572 ciMethodData* md; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2573 ciProfileData* data; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2574 int mdo_offset_bias = 0; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2575 if (op->should_profile()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2576 ciMethod* method = op->profiled_method(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2577 assert(method != NULL, "Should have method"); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2578 setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2579 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2580 Label profile_cast_success, profile_cast_failure, done; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2581 Label *success_target = op->should_profile() ? &profile_cast_success : &done; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2582 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2583 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2584 if (op->should_profile()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2585 Label not_null; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2586 __ br_notnull(value, false, Assembler::pn, not_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2587 __ delayed()->nop(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2588 Register mdo = k_RInfo; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2589 Register data_val = Rtmp1; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2590 jobject2reg(md->constant_encoding(), mdo); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2591 if (mdo_offset_bias > 0) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2592 __ set(mdo_offset_bias, data_val); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2593 __ add(mdo, data_val, mdo); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2594 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2595 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2596 __ ldub(flags_addr, data_val); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2597 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2598 __ stb(data_val, flags_addr); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2599 __ ba(false, done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2600 __ delayed()->nop(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2601 __ bind(not_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2602 } else { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2603 __ br_null(value, false, Assembler::pn, done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2604 __ delayed()->nop(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2605 } |
2002 | 2606 add_debug_info_for_null_check_here(op->info_for_exception()); |
2607 __ load_klass(array, k_RInfo); | |
2608 __ load_klass(value, klass_RInfo); | |
0 | 2609 |
2610 // get instance klass | |
2002 | 2611 __ ld_ptr(Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)), k_RInfo); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
356
diff
changeset
|
2612 // perform the fast part of the checking logic |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2613 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
356
diff
changeset
|
2614 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
356
diff
changeset
|
2615 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
356
diff
changeset
|
2616 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
0 | 2617 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2618 __ delayed()->nop(); | |
2619 __ cmp(G3, 0); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2620 __ br(Assembler::equal, false, Assembler::pn, *failure_target); |
0 | 2621 __ delayed()->nop(); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2622 // fall through to the success case |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2623 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2624 if (op->should_profile()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2625 Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2626 assert_different_registers(value, mdo, recv, tmp1); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2627 __ bind(profile_cast_success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2628 jobject2reg(md->constant_encoding(), mdo); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2629 if (mdo_offset_bias > 0) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2630 __ set(mdo_offset_bias, tmp1); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2631 __ add(mdo, tmp1, mdo); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2632 } |
2002 | 2633 __ load_klass(value, recv); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2634 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2635 __ ba(false, done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2636 __ delayed()->nop(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2637 // Cast failure case |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2638 __ bind(profile_cast_failure); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2639 jobject2reg(md->constant_encoding(), mdo); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2640 if (mdo_offset_bias > 0) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2641 __ set(mdo_offset_bias, tmp1); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2642 __ add(mdo, tmp1, mdo); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2643 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2644 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2645 __ ld_ptr(data_addr, tmp1); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2646 __ sub(tmp1, DataLayout::counter_increment, tmp1); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2647 __ st_ptr(tmp1, data_addr); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2648 __ ba(false, *stub->entry()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2649 __ delayed()->nop(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2650 } |
0 | 2651 __ bind(done); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2652 } else if (code == lir_checkcast) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2653 Register obj = op->object()->as_register(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2654 Register dst = op->result_opr()->as_register(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2655 Label success; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2656 emit_typecheck_helper(op, &success, op->stub()->entry(), &success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2657 __ bind(success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2658 __ mov(obj, dst); |
0 | 2659 } else if (code == lir_instanceof) { |
2660 Register obj = op->object()->as_register(); | |
2661 Register dst = op->result_opr()->as_register(); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2662 Label success, failure, done; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2663 emit_typecheck_helper(op, &success, &failure, &failure); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2664 __ bind(failure); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2665 __ set(0, dst); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2666 __ ba(false, done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2667 __ delayed()->nop(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2668 __ bind(success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2669 __ set(1, dst); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
2670 __ bind(done); |
0 | 2671 } else { |
2672 ShouldNotReachHere(); | |
2673 } | |
2674 | |
2675 } | |
2676 | |
2677 | |
2678 void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { | |
2679 if (op->code() == lir_cas_long) { | |
2680 assert(VM_Version::supports_cx8(), "wrong machine"); | |
2681 Register addr = op->addr()->as_pointer_register(); | |
2682 Register cmp_value_lo = op->cmp_value()->as_register_lo(); | |
2683 Register cmp_value_hi = op->cmp_value()->as_register_hi(); | |
2684 Register new_value_lo = op->new_value()->as_register_lo(); | |
2685 Register new_value_hi = op->new_value()->as_register_hi(); | |
2686 Register t1 = op->tmp1()->as_register(); | |
2687 Register t2 = op->tmp2()->as_register(); | |
2688 #ifdef _LP64 | |
2689 __ mov(cmp_value_lo, t1); | |
2690 __ mov(new_value_lo, t2); | |
2691 #else | |
2692 // move high and low halves of long values into single registers | |
2693 __ sllx(cmp_value_hi, 32, t1); // shift high half into temp reg | |
2694 __ srl(cmp_value_lo, 0, cmp_value_lo); // clear upper 32 bits of low half | |
2695 __ or3(t1, cmp_value_lo, t1); // t1 holds 64-bit compare value | |
2696 __ sllx(new_value_hi, 32, t2); | |
2697 __ srl(new_value_lo, 0, new_value_lo); | |
2698 __ or3(t2, new_value_lo, t2); // t2 holds 64-bit value to swap | |
2699 #endif | |
2700 // perform the compare and swap operation | |
2701 __ casx(addr, t1, t2); | |
2702 // generate condition code - if the swap succeeded, t2 ("new value" reg) was | |
2703 // overwritten with the original value in "addr" and will be equal to t1. | |
2704 __ cmp(t1, t2); | |
2705 | |
2706 } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) { | |
2707 Register addr = op->addr()->as_pointer_register(); | |
2708 Register cmp_value = op->cmp_value()->as_register(); | |
2709 Register new_value = op->new_value()->as_register(); | |
2710 Register t1 = op->tmp1()->as_register(); | |
2711 Register t2 = op->tmp2()->as_register(); | |
2712 __ mov(cmp_value, t1); | |
2713 __ mov(new_value, t2); | |
2714 if (op->code() == lir_cas_obj) { | |
2002 | 2715 if (UseCompressedOops) { |
2716 __ encode_heap_oop(t1); | |
2717 __ encode_heap_oop(t2); | |
0 | 2718 __ cas(addr, t1, t2); |
2002 | 2719 } else { |
2720 __ casx(addr, t1, t2); | |
0 | 2721 } |
2002 | 2722 } else { |
2723 __ cas(addr, t1, t2); | |
2724 } | |
0 | 2725 __ cmp(t1, t2); |
2726 } else { | |
2727 Unimplemented(); | |
2728 } | |
2729 } | |
2730 | |
2731 void LIR_Assembler::set_24bit_FPU() { | |
2732 Unimplemented(); | |
2733 } | |
2734 | |
2735 | |
2736 void LIR_Assembler::reset_FPU() { | |
2737 Unimplemented(); | |
2738 } | |
2739 | |
2740 | |
2741 void LIR_Assembler::breakpoint() { | |
2742 __ breakpoint_trap(); | |
2743 } | |
2744 | |
2745 | |
2746 void LIR_Assembler::push(LIR_Opr opr) { | |
2747 Unimplemented(); | |
2748 } | |
2749 | |
2750 | |
2751 void LIR_Assembler::pop(LIR_Opr opr) { | |
2752 Unimplemented(); | |
2753 } | |
2754 | |
2755 | |
2756 void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst_opr) { | |
2757 Address mon_addr = frame_map()->address_for_monitor_lock(monitor_no); | |
2758 Register dst = dst_opr->as_register(); | |
2759 Register reg = mon_addr.base(); | |
2760 int offset = mon_addr.disp(); | |
2761 // compute pointer to BasicLock | |
2762 if (mon_addr.is_simm13()) { | |
2763 __ add(reg, offset, dst); | |
2764 } else { | |
2765 __ set(offset, dst); | |
2766 __ add(dst, reg, dst); | |
2767 } | |
2768 } | |
2769 | |
2770 | |
2771 void LIR_Assembler::emit_lock(LIR_OpLock* op) { | |
2772 Register obj = op->obj_opr()->as_register(); | |
2773 Register hdr = op->hdr_opr()->as_register(); | |
2774 Register lock = op->lock_opr()->as_register(); | |
2775 | |
2776 // obj may not be an oop | |
2777 if (op->code() == lir_lock) { | |
2778 MonitorEnterStub* stub = (MonitorEnterStub*)op->stub(); | |
2779 if (UseFastLocking) { | |
2780 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); | |
2781 // add debug info for NullPointerException only if one is possible | |
2782 if (op->info() != NULL) { | |
2783 add_debug_info_for_null_check_here(op->info()); | |
2784 } | |
2785 __ lock_object(hdr, obj, lock, op->scratch_opr()->as_register(), *op->stub()->entry()); | |
2786 } else { | |
2787 // always do slow locking | |
2788 // note: the slow locking code could be inlined here, however if we use | |
2789 // slow locking, speed doesn't matter anyway and this solution is | |
2790 // simpler and requires less duplicated code - additionally, the | |
2791 // slow locking code is the same in either case which simplifies | |
2792 // debugging | |
2793 __ br(Assembler::always, false, Assembler::pt, *op->stub()->entry()); | |
2794 __ delayed()->nop(); | |
2795 } | |
2796 } else { | |
2797 assert (op->code() == lir_unlock, "Invalid code, expected lir_unlock"); | |
2798 if (UseFastLocking) { | |
2799 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); | |
2800 __ unlock_object(hdr, obj, lock, *op->stub()->entry()); | |
2801 } else { | |
2802 // always do slow unlocking | |
2803 // note: the slow unlocking code could be inlined here, however if we use | |
2804 // slow unlocking, speed doesn't matter anyway and this solution is | |
2805 // simpler and requires less duplicated code - additionally, the | |
2806 // slow unlocking code is the same in either case which simplifies | |
2807 // debugging | |
2808 __ br(Assembler::always, false, Assembler::pt, *op->stub()->entry()); | |
2809 __ delayed()->nop(); | |
2810 } | |
2811 } | |
2812 __ bind(*op->stub()->continuation()); | |
2813 } | |
2814 | |
2815 | |
2816 void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { | |
2817 ciMethod* method = op->profiled_method(); | |
2818 int bci = op->profiled_bci(); | |
2819 | |
2820 // Update counter for all call types | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
2821 ciMethodData* md = method->method_data_or_null(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
2822 assert(md != NULL, "Sanity"); |
0 | 2823 ciProfileData* data = md->bci_to_data(bci); |
2824 assert(data->is_CounterData(), "need CounterData for calls"); | |
2825 assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); | |
1783 | 2826 Register mdo = op->mdo()->as_register(); |
2827 #ifdef _LP64 | |
2828 assert(op->tmp1()->is_double_cpu(), "tmp1 must be allocated"); | |
2829 Register tmp1 = op->tmp1()->as_register_lo(); | |
2830 #else | |
0 | 2831 assert(op->tmp1()->is_single_cpu(), "tmp1 must be allocated"); |
2832 Register tmp1 = op->tmp1()->as_register(); | |
1783 | 2833 #endif |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
780
diff
changeset
|
2834 jobject2reg(md->constant_encoding(), mdo); |
0 | 2835 int mdo_offset_bias = 0; |
2836 if (!Assembler::is_simm13(md->byte_offset_of_slot(data, CounterData::count_offset()) + | |
2837 data->size_in_bytes())) { | |
2838 // The offset is large so bias the mdo by the base of the slot so | |
2839 // that the ld can use simm13s to reference the slots of the data | |
2840 mdo_offset_bias = md->byte_offset_of_slot(data, CounterData::count_offset()); | |
2841 __ set(mdo_offset_bias, O7); | |
2842 __ add(mdo, O7, mdo); | |
2843 } | |
2844 | |
727 | 2845 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); |
0 | 2846 Bytecodes::Code bc = method->java_code_at_bci(bci); |
2847 // Perform additional virtual call profiling for invokevirtual and | |
2848 // invokeinterface bytecodes | |
2849 if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) && | |
1783 | 2850 C1ProfileVirtualCalls) { |
0 | 2851 assert(op->recv()->is_single_cpu(), "recv must be allocated"); |
2852 Register recv = op->recv()->as_register(); | |
2853 assert_different_registers(mdo, tmp1, recv); | |
2854 assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); | |
2855 ciKlass* known_klass = op->known_holder(); | |
1783 | 2856 if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { |
0 | 2857 // We know the type that will be seen at this call site; we can |
2858 // statically update the methodDataOop rather than needing to do | |
2859 // dynamic tests on the receiver type | |
2860 | |
2861 // NOTE: we should probably put a lock around this search to | |
2862 // avoid collisions by concurrent compilations | |
2863 ciVirtualCallData* vc_data = (ciVirtualCallData*) data; | |
2864 uint i; | |
2865 for (i = 0; i < VirtualCallData::row_limit(); i++) { | |
2866 ciKlass* receiver = vc_data->receiver(i); | |
2867 if (known_klass->equals(receiver)) { | |
727 | 2868 Address data_addr(mdo, md->byte_offset_of_slot(data, |
2869 VirtualCallData::receiver_count_offset(i)) - | |
0 | 2870 mdo_offset_bias); |
1783 | 2871 __ ld_ptr(data_addr, tmp1); |
0 | 2872 __ add(tmp1, DataLayout::counter_increment, tmp1); |
1783 | 2873 __ st_ptr(tmp1, data_addr); |
0 | 2874 return; |
2875 } | |
2876 } | |
2877 | |
2878 // Receiver type not found in profile data; select an empty slot | |
2879 | |
2880 // Note that this is less efficient than it should be because it | |
2881 // always does a write to the receiver part of the | |
2882 // VirtualCallData rather than just the first time | |
2883 for (i = 0; i < VirtualCallData::row_limit(); i++) { | |
2884 ciKlass* receiver = vc_data->receiver(i); | |
2885 if (receiver == NULL) { | |
727 | 2886 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)) - |
0 | 2887 mdo_offset_bias); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
780
diff
changeset
|
2888 jobject2reg(known_klass->constant_encoding(), tmp1); |
0 | 2889 __ st_ptr(tmp1, recv_addr); |
727 | 2890 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)) - |
0 | 2891 mdo_offset_bias); |
1783 | 2892 __ ld_ptr(data_addr, tmp1); |
0 | 2893 __ add(tmp1, DataLayout::counter_increment, tmp1); |
1783 | 2894 __ st_ptr(tmp1, data_addr); |
0 | 2895 return; |
2896 } | |
2897 } | |
2898 } else { | |
2002 | 2899 __ load_klass(recv, recv); |
0 | 2900 Label update_done; |
1783 | 2901 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done); |
1251
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1204
diff
changeset
|
2902 // Receiver did not match any saved receiver and there is no empty row for it. |
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1204
diff
changeset
|
2903 // Increment total counter to indicate polymorphic case. |
1783 | 2904 __ ld_ptr(counter_addr, tmp1); |
1251
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1204
diff
changeset
|
2905 __ add(tmp1, DataLayout::counter_increment, tmp1); |
1783 | 2906 __ st_ptr(tmp1, counter_addr); |
0 | 2907 |
2908 __ bind(update_done); | |
2909 } | |
1251
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1204
diff
changeset
|
2910 } else { |
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1204
diff
changeset
|
2911 // Static call |
1783 | 2912 __ ld_ptr(counter_addr, tmp1); |
1251
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1204
diff
changeset
|
2913 __ add(tmp1, DataLayout::counter_increment, tmp1); |
1783 | 2914 __ st_ptr(tmp1, counter_addr); |
0 | 2915 } |
2916 } | |
2917 | |
2918 void LIR_Assembler::align_backward_branch_target() { | |
1365 | 2919 __ align(OptoLoopAlignment); |
0 | 2920 } |
2921 | |
2922 | |
2923 void LIR_Assembler::emit_delay(LIR_OpDelay* op) { | |
2924 // make sure we are expecting a delay | |
2925 // this has the side effect of clearing the delay state | |
2926 // so we can use _masm instead of _masm->delayed() to do the | |
2927 // code generation. | |
2928 __ delayed(); | |
2929 | |
2930 // make sure we only emit one instruction | |
2931 int offset = code_offset(); | |
2932 op->delay_op()->emit_code(this); | |
2933 #ifdef ASSERT | |
2934 if (code_offset() - offset != NativeInstruction::nop_instruction_size) { | |
2935 op->delay_op()->print(); | |
2936 } | |
2937 assert(code_offset() - offset == NativeInstruction::nop_instruction_size, | |
2938 "only one instruction can go in a delay slot"); | |
2939 #endif | |
2940 | |
2941 // we may also be emitting the call info for the instruction | |
2942 // which we are the delay slot of. | |
1564 | 2943 CodeEmitInfo* call_info = op->call_info(); |
0 | 2944 if (call_info) { |
2945 add_call_info(code_offset(), call_info); | |
2946 } | |
2947 | |
2948 if (VerifyStackAtCalls) { | |
2949 _masm->sub(FP, SP, O7); | |
2950 _masm->cmp(O7, initial_frame_size_in_bytes()); | |
2951 _masm->trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0+2 ); | |
2952 } | |
2953 } | |
2954 | |
2955 | |
2956 void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { | |
2957 assert(left->is_register(), "can only handle registers"); | |
2958 | |
2959 if (left->is_single_cpu()) { | |
2960 __ neg(left->as_register(), dest->as_register()); | |
2961 } else if (left->is_single_fpu()) { | |
2962 __ fneg(FloatRegisterImpl::S, left->as_float_reg(), dest->as_float_reg()); | |
2963 } else if (left->is_double_fpu()) { | |
2964 __ fneg(FloatRegisterImpl::D, left->as_double_reg(), dest->as_double_reg()); | |
2965 } else { | |
2966 assert (left->is_double_cpu(), "Must be a long"); | |
2967 Register Rlow = left->as_register_lo(); | |
2968 Register Rhi = left->as_register_hi(); | |
2969 #ifdef _LP64 | |
2970 __ sub(G0, Rlow, dest->as_register_lo()); | |
2971 #else | |
2972 __ subcc(G0, Rlow, dest->as_register_lo()); | |
2973 __ subc (G0, Rhi, dest->as_register_hi()); | |
2974 #endif | |
2975 } | |
2976 } | |
2977 | |
2978 | |
2979 void LIR_Assembler::fxch(int i) { | |
2980 Unimplemented(); | |
2981 } | |
2982 | |
2983 void LIR_Assembler::fld(int i) { | |
2984 Unimplemented(); | |
2985 } | |
2986 | |
2987 void LIR_Assembler::ffree(int i) { | |
2988 Unimplemented(); | |
2989 } | |
2990 | |
2991 void LIR_Assembler::rt_call(LIR_Opr result, address dest, | |
2992 const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) { | |
2993 | |
2994 // if tmp is invalid, then the function being called doesn't destroy the thread | |
2995 if (tmp->is_valid()) { | |
2996 __ save_thread(tmp->as_register()); | |
2997 } | |
2998 __ call(dest, relocInfo::runtime_call_type); | |
2999 __ delayed()->nop(); | |
3000 if (info != NULL) { | |
3001 add_call_info_here(info); | |
3002 } | |
3003 if (tmp->is_valid()) { | |
3004 __ restore_thread(tmp->as_register()); | |
3005 } | |
3006 | |
3007 #ifdef ASSERT | |
3008 __ verify_thread(); | |
3009 #endif // ASSERT | |
3010 } | |
3011 | |
3012 | |
3013 void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) { | |
3014 #ifdef _LP64 | |
3015 ShouldNotReachHere(); | |
3016 #endif | |
3017 | |
3018 NEEDS_CLEANUP; | |
3019 if (type == T_LONG) { | |
3020 LIR_Address* mem_addr = dest->is_address() ? dest->as_address_ptr() : src->as_address_ptr(); | |
3021 | |
3022 // (extended to allow indexed as well as constant displaced for JSR-166) | |
3023 Register idx = noreg; // contains either constant offset or index | |
3024 | |
3025 int disp = mem_addr->disp(); | |
3026 if (mem_addr->index() == LIR_OprFact::illegalOpr) { | |
3027 if (!Assembler::is_simm13(disp)) { | |
3028 idx = O7; | |
3029 __ set(disp, idx); | |
3030 } | |
3031 } else { | |
3032 assert(disp == 0, "not both indexed and disp"); | |
3033 idx = mem_addr->index()->as_register(); | |
3034 } | |
3035 | |
3036 int null_check_offset = -1; | |
3037 | |
3038 Register base = mem_addr->base()->as_register(); | |
3039 if (src->is_register() && dest->is_address()) { | |
3040 // G4 is high half, G5 is low half | |
3041 if (VM_Version::v9_instructions_work()) { | |
3042 // clear the top bits of G5, and scale up G4 | |
3043 __ srl (src->as_register_lo(), 0, G5); | |
3044 __ sllx(src->as_register_hi(), 32, G4); | |
3045 // combine the two halves into the 64 bits of G4 | |
3046 __ or3(G4, G5, G4); | |
3047 null_check_offset = __ offset(); | |
3048 if (idx == noreg) { | |
3049 __ stx(G4, base, disp); | |
3050 } else { | |
3051 __ stx(G4, base, idx); | |
3052 } | |
3053 } else { | |
3054 __ mov (src->as_register_hi(), G4); | |
3055 __ mov (src->as_register_lo(), G5); | |
3056 null_check_offset = __ offset(); | |
3057 if (idx == noreg) { | |
3058 __ std(G4, base, disp); | |
3059 } else { | |
3060 __ std(G4, base, idx); | |
3061 } | |
3062 } | |
3063 } else if (src->is_address() && dest->is_register()) { | |
3064 null_check_offset = __ offset(); | |
3065 if (VM_Version::v9_instructions_work()) { | |
3066 if (idx == noreg) { | |
3067 __ ldx(base, disp, G5); | |
3068 } else { | |
3069 __ ldx(base, idx, G5); | |
3070 } | |
3071 __ srax(G5, 32, dest->as_register_hi()); // fetch the high half into hi | |
3072 __ mov (G5, dest->as_register_lo()); // copy low half into lo | |
3073 } else { | |
3074 if (idx == noreg) { | |
3075 __ ldd(base, disp, G4); | |
3076 } else { | |
3077 __ ldd(base, idx, G4); | |
3078 } | |
3079 // G4 is high half, G5 is low half | |
3080 __ mov (G4, dest->as_register_hi()); | |
3081 __ mov (G5, dest->as_register_lo()); | |
3082 } | |
3083 } else { | |
3084 Unimplemented(); | |
3085 } | |
3086 if (info != NULL) { | |
3087 add_debug_info_for_null_check(null_check_offset, info); | |
3088 } | |
3089 | |
3090 } else { | |
3091 // use normal move for all other volatiles since they don't need | |
3092 // special handling to remain atomic. | |
2002 | 3093 move_op(src, dest, type, lir_patch_none, info, false, false, false); |
0 | 3094 } |
3095 } | |
3096 | |
3097 void LIR_Assembler::membar() { | |
3098 // only StoreLoad membars are ever explicitly needed on sparcs in TSO mode | |
3099 __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) ); | |
3100 } | |
3101 | |
3102 void LIR_Assembler::membar_acquire() { | |
3103 // no-op on TSO | |
3104 } | |
3105 | |
3106 void LIR_Assembler::membar_release() { | |
3107 // no-op on TSO | |
3108 } | |
3109 | |
1783 | 3110 // Pack two sequential registers containing 32 bit values |
0 | 3111 // into a single 64 bit register. |
1783 | 3112 // src and src->successor() are packed into dst |
3113 // src and dst may be the same register. | |
3114 // Note: src is destroyed | |
3115 void LIR_Assembler::pack64(LIR_Opr src, LIR_Opr dst) { | |
3116 Register rs = src->as_register(); | |
3117 Register rd = dst->as_register_lo(); | |
0 | 3118 __ sllx(rs, 32, rs); |
3119 __ srl(rs->successor(), 0, rs->successor()); | |
3120 __ or3(rs, rs->successor(), rd); | |
3121 } | |
3122 | |
1783 | 3123 // Unpack a 64 bit value in a register into |
0 | 3124 // two sequential registers. |
1783 | 3125 // src is unpacked into dst and dst->successor() |
3126 void LIR_Assembler::unpack64(LIR_Opr src, LIR_Opr dst) { | |
3127 Register rs = src->as_register_lo(); | |
3128 Register rd = dst->as_register_hi(); | |
3129 assert_different_registers(rs, rd, rd->successor()); | |
3130 __ srlx(rs, 32, rd); | |
3131 __ srl (rs, 0, rd->successor()); | |
0 | 3132 } |
3133 | |
3134 | |
3135 void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) { | |
3136 LIR_Address* addr = addr_opr->as_address_ptr(); | |
3137 assert(addr->index()->is_illegal() && addr->scale() == LIR_Address::times_1 && Assembler::is_simm13(addr->disp()), "can't handle complex addresses yet"); | |
1783 | 3138 |
3139 __ add(addr->base()->as_pointer_register(), addr->disp(), dest->as_pointer_register()); | |
0 | 3140 } |
3141 | |
3142 | |
3143 void LIR_Assembler::get_thread(LIR_Opr result_reg) { | |
3144 assert(result_reg->is_register(), "check"); | |
3145 __ mov(G2_thread, result_reg->as_register()); | |
3146 } | |
3147 | |
3148 | |
3149 void LIR_Assembler::peephole(LIR_List* lir) { | |
3150 LIR_OpList* inst = lir->instructions_list(); | |
3151 for (int i = 0; i < inst->length(); i++) { | |
3152 LIR_Op* op = inst->at(i); | |
3153 switch (op->code()) { | |
3154 case lir_cond_float_branch: | |
3155 case lir_branch: { | |
3156 LIR_OpBranch* branch = op->as_OpBranch(); | |
3157 assert(branch->info() == NULL, "shouldn't be state on branches anymore"); | |
3158 LIR_Op* delay_op = NULL; | |
3159 // we'd like to be able to pull following instructions into | |
3160 // this slot but we don't know enough to do it safely yet so | |
3161 // only optimize block to block control flow. | |
3162 if (LIRFillDelaySlots && branch->block()) { | |
3163 LIR_Op* prev = inst->at(i - 1); | |
3164 if (prev && LIR_Assembler::is_single_instruction(prev) && prev->info() == NULL) { | |
3165 // swap previous instruction into delay slot | |
3166 inst->at_put(i - 1, op); | |
3167 inst->at_put(i, new LIR_OpDelay(prev, op->info())); | |
3168 #ifndef PRODUCT | |
3169 if (LIRTracePeephole) { | |
3170 tty->print_cr("delayed"); | |
3171 inst->at(i - 1)->print(); | |
3172 inst->at(i)->print(); | |
1564 | 3173 tty->cr(); |
0 | 3174 } |
3175 #endif | |
3176 continue; | |
3177 } | |
3178 } | |
3179 | |
3180 if (!delay_op) { | |
3181 delay_op = new LIR_OpDelay(new LIR_Op0(lir_nop), NULL); | |
3182 } | |
3183 inst->insert_before(i + 1, delay_op); | |
3184 break; | |
3185 } | |
3186 case lir_static_call: | |
3187 case lir_virtual_call: | |
3188 case lir_icvirtual_call: | |
1564 | 3189 case lir_optvirtual_call: |
3190 case lir_dynamic_call: { | |
0 | 3191 LIR_Op* prev = inst->at(i - 1); |
3192 if (LIRFillDelaySlots && prev && prev->code() == lir_move && prev->info() == NULL && | |
3193 (op->code() != lir_virtual_call || | |
3194 !prev->result_opr()->is_single_cpu() || | |
3195 prev->result_opr()->as_register() != O0) && | |
3196 LIR_Assembler::is_single_instruction(prev)) { | |
3197 // Only moves without info can be put into the delay slot. | |
3198 // Also don't allow the setup of the receiver in the delay | |
3199 // slot for vtable calls. | |
3200 inst->at_put(i - 1, op); | |
3201 inst->at_put(i, new LIR_OpDelay(prev, op->info())); | |
3202 #ifndef PRODUCT | |
3203 if (LIRTracePeephole) { | |
3204 tty->print_cr("delayed"); | |
3205 inst->at(i - 1)->print(); | |
3206 inst->at(i)->print(); | |
1564 | 3207 tty->cr(); |
0 | 3208 } |
3209 #endif | |
1783 | 3210 } else { |
3211 LIR_Op* delay_op = new LIR_OpDelay(new LIR_Op0(lir_nop), op->as_OpJavaCall()->info()); | |
3212 inst->insert_before(i + 1, delay_op); | |
3213 i++; | |
0 | 3214 } |
3215 | |
1783 | 3216 #if defined(TIERED) && !defined(_LP64) |
3217 // fixup the return value from G1 to O0/O1 for long returns. | |
3218 // It's done here instead of in LIRGenerator because there's | |
3219 // such a mismatch between the single reg and double reg | |
3220 // calling convention. | |
3221 LIR_OpJavaCall* callop = op->as_OpJavaCall(); | |
3222 if (callop->result_opr() == FrameMap::out_long_opr) { | |
3223 LIR_OpJavaCall* call; | |
3224 LIR_OprList* arguments = new LIR_OprList(callop->arguments()->length()); | |
3225 for (int a = 0; a < arguments->length(); a++) { | |
3226 arguments[a] = callop->arguments()[a]; | |
3227 } | |
3228 if (op->code() == lir_virtual_call) { | |
3229 call = new LIR_OpJavaCall(op->code(), callop->method(), callop->receiver(), FrameMap::g1_long_single_opr, | |
3230 callop->vtable_offset(), arguments, callop->info()); | |
3231 } else { | |
3232 call = new LIR_OpJavaCall(op->code(), callop->method(), callop->receiver(), FrameMap::g1_long_single_opr, | |
3233 callop->addr(), arguments, callop->info()); | |
3234 } | |
3235 inst->at_put(i - 1, call); | |
3236 inst->insert_before(i + 1, new LIR_Op1(lir_unpack64, FrameMap::g1_long_single_opr, callop->result_opr(), | |
3237 T_LONG, lir_patch_none, NULL)); | |
3238 } | |
3239 #endif | |
0 | 3240 break; |
3241 } | |
3242 } | |
3243 } | |
3244 } | |
3245 | |
3246 | |
3247 | |
3248 | |
3249 #undef __ |