Thu, 07 Apr 2011 09:53:20 -0700
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes
1 /*
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #include "precompiled.hpp"
26 #include "c1/c1_Defs.hpp"
27 #include "c1/c1_MacroAssembler.hpp"
28 #include "c1/c1_Runtime1.hpp"
29 #include "interpreter/interpreter.hpp"
30 #include "nativeInst_sparc.hpp"
31 #include "oops/compiledICHolderOop.hpp"
32 #include "oops/oop.inline.hpp"
33 #include "prims/jvmtiExport.hpp"
34 #include "register_sparc.hpp"
35 #include "runtime/sharedRuntime.hpp"
36 #include "runtime/signature.hpp"
37 #include "runtime/vframeArray.hpp"
38 #include "vmreg_sparc.inline.hpp"
40 // Implementation of StubAssembler
42 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry_point, int number_of_arguments) {
43 // for sparc changing the number of arguments doesn't change
44 // anything about the frame size so we'll always lie and claim that
45 // we are only passing 1 argument.
46 set_num_rt_args(1);
48 assert_not_delayed();
49 // bang stack before going to runtime
50 set(-os::vm_page_size() + STACK_BIAS, G3_scratch);
51 st(G0, SP, G3_scratch);
53 // debugging support
54 assert(number_of_arguments >= 0 , "cannot have negative number of arguments");
56 set_last_Java_frame(SP, noreg);
57 if (VerifyThread) mov(G2_thread, O0); // about to be smashed; pass early
58 save_thread(L7_thread_cache);
59 // do the call
60 call(entry_point, relocInfo::runtime_call_type);
61 if (!VerifyThread) {
62 delayed()->mov(G2_thread, O0); // pass thread as first argument
63 } else {
64 delayed()->nop(); // (thread already passed)
65 }
66 int call_offset = offset(); // offset of return address
67 restore_thread(L7_thread_cache);
68 reset_last_Java_frame();
70 // check for pending exceptions
71 { Label L;
72 Address exception_addr(G2_thread, Thread::pending_exception_offset());
73 ld_ptr(exception_addr, Gtemp);
74 br_null(Gtemp, false, pt, L);
75 delayed()->nop();
76 Address vm_result_addr(G2_thread, JavaThread::vm_result_offset());
77 st_ptr(G0, vm_result_addr);
78 Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset());
79 st_ptr(G0, vm_result_addr_2);
81 if (frame_size() == no_frame_size) {
82 // we use O7 linkage so that forward_exception_entry has the issuing PC
83 call(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
84 delayed()->restore();
85 } else if (_stub_id == Runtime1::forward_exception_id) {
86 should_not_reach_here();
87 } else {
88 AddressLiteral exc(Runtime1::entry_for(Runtime1::forward_exception_id));
89 jump_to(exc, G4);
90 delayed()->nop();
91 }
92 bind(L);
93 }
95 // get oop result if there is one and reset the value in the thread
96 if (oop_result1->is_valid()) { // get oop result if there is one and reset it in the thread
97 get_vm_result (oop_result1);
98 } else {
99 // be a little paranoid and clear the result
100 Address vm_result_addr(G2_thread, JavaThread::vm_result_offset());
101 st_ptr(G0, vm_result_addr);
102 }
104 if (oop_result2->is_valid()) {
105 get_vm_result_2(oop_result2);
106 } else {
107 // be a little paranoid and clear the result
108 Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset());
109 st_ptr(G0, vm_result_addr_2);
110 }
112 return call_offset;
113 }
116 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) {
117 // O0 is reserved for the thread
118 mov(arg1, O1);
119 return call_RT(oop_result1, oop_result2, entry, 1);
120 }
123 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) {
124 // O0 is reserved for the thread
125 mov(arg1, O1);
126 mov(arg2, O2); assert(arg2 != O1, "smashed argument");
127 return call_RT(oop_result1, oop_result2, entry, 2);
128 }
131 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3) {
132 // O0 is reserved for the thread
133 mov(arg1, O1);
134 mov(arg2, O2); assert(arg2 != O1, "smashed argument");
135 mov(arg3, O3); assert(arg3 != O1 && arg3 != O2, "smashed argument");
136 return call_RT(oop_result1, oop_result2, entry, 3);
137 }
140 // Implementation of Runtime1
142 #define __ sasm->
144 static int cpu_reg_save_offsets[FrameMap::nof_cpu_regs];
145 static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs];
146 static int reg_save_size_in_words;
147 static int frame_size_in_bytes = -1;
149 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
150 assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
151 "mismatch in calculation");
152 sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
153 int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
154 OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
156 int i;
157 for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
158 Register r = as_Register(i);
159 if (r == G1 || r == G3 || r == G4 || r == G5) {
160 int sp_offset = cpu_reg_save_offsets[i];
161 oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
162 r->as_VMReg());
163 }
164 }
166 if (save_fpu_registers) {
167 for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
168 FloatRegister r = as_FloatRegister(i);
169 int sp_offset = fpu_reg_save_offsets[i];
170 oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
171 r->as_VMReg());
172 }
173 }
174 return oop_map;
175 }
177 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
178 assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
179 "mismatch in calculation");
180 __ save_frame_c1(frame_size_in_bytes);
182 // Record volatile registers as callee-save values in an OopMap so their save locations will be
183 // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
184 // deoptimization; see compiledVFrame::create_stack_value). The caller's I, L and O registers
185 // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
186 // (as the stub's I's) when the runtime routine called by the stub creates its frame.
187 // OopMap frame sizes are in c2 stack slot sizes (sizeof(jint))
189 int i;
190 for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
191 Register r = as_Register(i);
192 if (r == G1 || r == G3 || r == G4 || r == G5) {
193 int sp_offset = cpu_reg_save_offsets[i];
194 __ st_ptr(r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
195 }
196 }
198 if (save_fpu_registers) {
199 for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
200 FloatRegister r = as_FloatRegister(i);
201 int sp_offset = fpu_reg_save_offsets[i];
202 __ stf(FloatRegisterImpl::S, r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
203 }
204 }
206 return generate_oop_map(sasm, save_fpu_registers);
207 }
209 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
210 for (int i = 0; i < FrameMap::nof_cpu_regs; i++) {
211 Register r = as_Register(i);
212 if (r == G1 || r == G3 || r == G4 || r == G5) {
213 __ ld_ptr(SP, (cpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
214 }
215 }
217 if (restore_fpu_registers) {
218 for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
219 FloatRegister r = as_FloatRegister(i);
220 __ ldf(FloatRegisterImpl::S, SP, (fpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
221 }
222 }
223 }
226 void Runtime1::initialize_pd() {
227 // compute word offsets from SP at which live (non-windowed) registers are captured by stub routines
228 //
229 // A stub routine will have a frame that is at least large enough to hold
230 // a register window save area (obviously) and the volatile g registers
231 // and floating registers. A user of save_live_registers can have a frame
232 // that has more scratch area in it (although typically they will use L-regs).
233 // in that case the frame will look like this (stack growing down)
234 //
235 // FP -> | |
236 // | scratch mem |
237 // | " " |
238 // --------------
239 // | float regs |
240 // | " " |
241 // ---------------
242 // | G regs |
243 // | " " |
244 // ---------------
245 // | abi reg. |
246 // | window save |
247 // | area |
248 // SP -> ---------------
249 //
250 int i;
251 int sp_offset = round_to(frame::register_save_words, 2); // start doubleword aligned
253 // only G int registers are saved explicitly; others are found in register windows
254 for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
255 Register r = as_Register(i);
256 if (r == G1 || r == G3 || r == G4 || r == G5) {
257 cpu_reg_save_offsets[i] = sp_offset;
258 sp_offset++;
259 }
260 }
262 // all float registers are saved explicitly
263 assert(FrameMap::nof_fpu_regs == 32, "double registers not handled here");
264 for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
265 fpu_reg_save_offsets[i] = sp_offset;
266 sp_offset++;
267 }
268 reg_save_size_in_words = sp_offset - frame::memory_parameter_word_sp_offset;
269 // this should match assembler::total_frame_size_in_bytes, which
270 // isn't callable from this context. It's checked by an assert when
271 // it's used though.
272 frame_size_in_bytes = align_size_up(sp_offset * wordSize, 8);
273 }
276 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
277 // make a frame and preserve the caller's caller-save registers
278 OopMap* oop_map = save_live_registers(sasm);
279 int call_offset;
280 if (!has_argument) {
281 call_offset = __ call_RT(noreg, noreg, target);
282 } else {
283 call_offset = __ call_RT(noreg, noreg, target, G4);
284 }
285 OopMapSet* oop_maps = new OopMapSet();
286 oop_maps->add_gc_map(call_offset, oop_map);
288 __ should_not_reach_here();
289 return oop_maps;
290 }
293 OopMapSet* Runtime1::generate_stub_call(StubAssembler* sasm, Register result, address target,
294 Register arg1, Register arg2, Register arg3) {
295 // make a frame and preserve the caller's caller-save registers
296 OopMap* oop_map = save_live_registers(sasm);
298 int call_offset;
299 if (arg1 == noreg) {
300 call_offset = __ call_RT(result, noreg, target);
301 } else if (arg2 == noreg) {
302 call_offset = __ call_RT(result, noreg, target, arg1);
303 } else if (arg3 == noreg) {
304 call_offset = __ call_RT(result, noreg, target, arg1, arg2);
305 } else {
306 call_offset = __ call_RT(result, noreg, target, arg1, arg2, arg3);
307 }
308 OopMapSet* oop_maps = NULL;
310 oop_maps = new OopMapSet();
311 oop_maps->add_gc_map(call_offset, oop_map);
312 restore_live_registers(sasm);
314 __ ret();
315 __ delayed()->restore();
317 return oop_maps;
318 }
321 OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
322 // make a frame and preserve the caller's caller-save registers
323 OopMap* oop_map = save_live_registers(sasm);
325 // call the runtime patching routine, returns non-zero if nmethod got deopted.
326 int call_offset = __ call_RT(noreg, noreg, target);
327 OopMapSet* oop_maps = new OopMapSet();
328 oop_maps->add_gc_map(call_offset, oop_map);
330 // re-execute the patched instruction or, if the nmethod was deoptmized, return to the
331 // deoptimization handler entry that will cause re-execution of the current bytecode
332 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
333 assert(deopt_blob != NULL, "deoptimization blob must have been created");
335 Label no_deopt;
336 __ tst(O0);
337 __ brx(Assembler::equal, false, Assembler::pt, no_deopt);
338 __ delayed()->nop();
340 // return to the deoptimization handler entry for unpacking and rexecute
341 // if we simply returned the we'd deopt as if any call we patched had just
342 // returned.
344 restore_live_registers(sasm);
346 AddressLiteral dest(deopt_blob->unpack_with_reexecution());
347 __ jump_to(dest, O0);
348 __ delayed()->restore();
350 __ bind(no_deopt);
351 restore_live_registers(sasm);
352 __ ret();
353 __ delayed()->restore();
355 return oop_maps;
356 }
358 OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
360 OopMapSet* oop_maps = NULL;
361 // for better readability
362 const bool must_gc_arguments = true;
363 const bool dont_gc_arguments = false;
365 // stub code & info for the different stubs
366 switch (id) {
367 case forward_exception_id:
368 {
369 oop_maps = generate_handle_exception(id, sasm);
370 }
371 break;
373 case new_instance_id:
374 case fast_new_instance_id:
375 case fast_new_instance_init_check_id:
376 {
377 Register G5_klass = G5; // Incoming
378 Register O0_obj = O0; // Outgoing
380 if (id == new_instance_id) {
381 __ set_info("new_instance", dont_gc_arguments);
382 } else if (id == fast_new_instance_id) {
383 __ set_info("fast new_instance", dont_gc_arguments);
384 } else {
385 assert(id == fast_new_instance_init_check_id, "bad StubID");
386 __ set_info("fast new_instance init check", dont_gc_arguments);
387 }
389 if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
390 UseTLAB && FastTLABRefill) {
391 Label slow_path;
392 Register G1_obj_size = G1;
393 Register G3_t1 = G3;
394 Register G4_t2 = G4;
395 assert_different_registers(G5_klass, G1_obj_size, G3_t1, G4_t2);
397 // Push a frame since we may do dtrace notification for the
398 // allocation which requires calling out and we don't want
399 // to stomp the real return address.
400 __ save_frame(0);
402 if (id == fast_new_instance_init_check_id) {
403 // make sure the klass is initialized
404 __ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1);
405 __ cmp(G3_t1, instanceKlass::fully_initialized);
406 __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
407 __ delayed()->nop();
408 }
409 #ifdef ASSERT
410 // assert object can be fast path allocated
411 {
412 Label ok, not_ok;
413 __ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size);
414 __ cmp(G1_obj_size, 0); // make sure it's an instance (LH > 0)
415 __ br(Assembler::lessEqual, false, Assembler::pn, not_ok);
416 __ delayed()->nop();
417 __ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size);
418 __ br(Assembler::zero, false, Assembler::pn, ok);
419 __ delayed()->nop();
420 __ bind(not_ok);
421 __ stop("assert(can be fast path allocated)");
422 __ should_not_reach_here();
423 __ bind(ok);
424 }
425 #endif // ASSERT
426 // if we got here then the TLAB allocation failed, so try
427 // refilling the TLAB or allocating directly from eden.
428 Label retry_tlab, try_eden;
429 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass
431 __ bind(retry_tlab);
433 // get the instance size
434 __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
436 __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
438 __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
439 __ verify_oop(O0_obj);
440 __ mov(O0, I0);
441 __ ret();
442 __ delayed()->restore();
444 __ bind(try_eden);
445 // get the instance size
446 __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
447 __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
448 __ incr_allocated_bytes(G1_obj_size, G3_t1, G4_t2);
450 __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
451 __ verify_oop(O0_obj);
452 __ mov(O0, I0);
453 __ ret();
454 __ delayed()->restore();
456 __ bind(slow_path);
458 // pop this frame so generate_stub_call can push it's own
459 __ restore();
460 }
462 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_instance), G5_klass);
463 // I0->O0: new instance
464 }
466 break;
468 case counter_overflow_id:
469 // G4 contains bci, G5 contains method
470 oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, counter_overflow), G4, G5);
471 break;
473 case new_type_array_id:
474 case new_object_array_id:
475 {
476 Register G5_klass = G5; // Incoming
477 Register G4_length = G4; // Incoming
478 Register O0_obj = O0; // Outgoing
480 Address klass_lh(G5_klass, ((klassOopDesc::header_size() * HeapWordSize)
481 + Klass::layout_helper_offset_in_bytes()));
482 assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
483 assert(Klass::_lh_header_size_mask == 0xFF, "bytewise");
484 // Use this offset to pick out an individual byte of the layout_helper:
485 const int klass_lh_header_size_offset = ((BytesPerInt - 1) // 3 - 2 selects byte {0,1,0,0}
486 - Klass::_lh_header_size_shift / BitsPerByte);
488 if (id == new_type_array_id) {
489 __ set_info("new_type_array", dont_gc_arguments);
490 } else {
491 __ set_info("new_object_array", dont_gc_arguments);
492 }
494 #ifdef ASSERT
495 // assert object type is really an array of the proper kind
496 {
497 Label ok;
498 Register G3_t1 = G3;
499 __ ld(klass_lh, G3_t1);
500 __ sra(G3_t1, Klass::_lh_array_tag_shift, G3_t1);
501 int tag = ((id == new_type_array_id)
502 ? Klass::_lh_array_tag_type_value
503 : Klass::_lh_array_tag_obj_value);
504 __ cmp(G3_t1, tag);
505 __ brx(Assembler::equal, false, Assembler::pt, ok);
506 __ delayed()->nop();
507 __ stop("assert(is an array klass)");
508 __ should_not_reach_here();
509 __ bind(ok);
510 }
511 #endif // ASSERT
513 if (UseTLAB && FastTLABRefill) {
514 Label slow_path;
515 Register G1_arr_size = G1;
516 Register G3_t1 = G3;
517 Register O1_t2 = O1;
518 assert_different_registers(G5_klass, G4_length, G1_arr_size, G3_t1, O1_t2);
520 // check that array length is small enough for fast path
521 __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
522 __ cmp(G4_length, G3_t1);
523 __ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
524 __ delayed()->nop();
526 // if we got here then the TLAB allocation failed, so try
527 // refilling the TLAB or allocating directly from eden.
528 Label retry_tlab, try_eden;
529 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass
531 __ bind(retry_tlab);
533 // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
534 __ ld(klass_lh, G3_t1);
535 __ sll(G4_length, G3_t1, G1_arr_size);
536 __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
537 __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
538 __ add(G1_arr_size, G3_t1, G1_arr_size);
539 __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size); // align up
540 __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
542 __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path); // preserves G1_arr_size
544 __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
545 __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
546 __ sub(G1_arr_size, G3_t1, O1_t2); // body length
547 __ add(O0_obj, G3_t1, G3_t1); // body start
548 __ initialize_body(G3_t1, O1_t2);
549 __ verify_oop(O0_obj);
550 __ retl();
551 __ delayed()->nop();
553 __ bind(try_eden);
554 // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
555 __ ld(klass_lh, G3_t1);
556 __ sll(G4_length, G3_t1, G1_arr_size);
557 __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
558 __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
559 __ add(G1_arr_size, G3_t1, G1_arr_size);
560 __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size);
561 __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
563 __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size
564 __ incr_allocated_bytes(G1_arr_size, G3_t1, O1_t2);
566 __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
567 __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
568 __ sub(G1_arr_size, G3_t1, O1_t2); // body length
569 __ add(O0_obj, G3_t1, G3_t1); // body start
570 __ initialize_body(G3_t1, O1_t2);
571 __ verify_oop(O0_obj);
572 __ retl();
573 __ delayed()->nop();
575 __ bind(slow_path);
576 }
578 if (id == new_type_array_id) {
579 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length);
580 } else {
581 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_object_array), G5_klass, G4_length);
582 }
583 // I0 -> O0: new array
584 }
585 break;
587 case new_multi_array_id:
588 { // O0: klass
589 // O1: rank
590 // O2: address of 1st dimension
591 __ set_info("new_multi_array", dont_gc_arguments);
592 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_multi_array), I0, I1, I2);
593 // I0 -> O0: new multi array
594 }
595 break;
597 case register_finalizer_id:
598 {
599 __ set_info("register_finalizer", dont_gc_arguments);
601 // load the klass and check the has finalizer flag
602 Label register_finalizer;
603 Register t = O1;
604 __ load_klass(O0, t);
605 __ ld(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc), t);
606 __ set(JVM_ACC_HAS_FINALIZER, G3);
607 __ andcc(G3, t, G0);
608 __ br(Assembler::notZero, false, Assembler::pt, register_finalizer);
609 __ delayed()->nop();
611 // do a leaf return
612 __ retl();
613 __ delayed()->nop();
615 __ bind(register_finalizer);
616 OopMap* oop_map = save_live_registers(sasm);
617 int call_offset = __ call_RT(noreg, noreg,
618 CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), I0);
619 oop_maps = new OopMapSet();
620 oop_maps->add_gc_map(call_offset, oop_map);
622 // Now restore all the live registers
623 restore_live_registers(sasm);
625 __ ret();
626 __ delayed()->restore();
627 }
628 break;
630 case throw_range_check_failed_id:
631 { __ set_info("range_check_failed", dont_gc_arguments); // arguments will be discarded
632 // G4: index
633 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), true);
634 }
635 break;
637 case throw_index_exception_id:
638 { __ set_info("index_range_check_failed", dont_gc_arguments); // arguments will be discarded
639 // G4: index
640 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
641 }
642 break;
644 case throw_div0_exception_id:
645 { __ set_info("throw_div0_exception", dont_gc_arguments);
646 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false);
647 }
648 break;
650 case throw_null_pointer_exception_id:
651 { __ set_info("throw_null_pointer_exception", dont_gc_arguments);
652 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
653 }
654 break;
656 case handle_exception_id:
657 { __ set_info("handle_exception", dont_gc_arguments);
658 oop_maps = generate_handle_exception(id, sasm);
659 }
660 break;
662 case handle_exception_from_callee_id:
663 { __ set_info("handle_exception_from_callee", dont_gc_arguments);
664 oop_maps = generate_handle_exception(id, sasm);
665 }
666 break;
668 case unwind_exception_id:
669 {
670 // O0: exception
671 // I7: address of call to this method
673 __ set_info("unwind_exception", dont_gc_arguments);
674 __ mov(Oexception, Oexception->after_save());
675 __ add(I7, frame::pc_return_offset, Oissuing_pc->after_save());
677 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
678 G2_thread, Oissuing_pc->after_save());
679 __ verify_not_null_oop(Oexception->after_save());
681 // Restore SP from L7 if the exception PC is a method handle call site.
682 __ mov(O0, G5); // Save the target address.
683 __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
684 __ tst(L0); // Condition codes are preserved over the restore.
685 __ restore();
687 __ jmp(G5, 0);
688 __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP); // Restore SP if required.
689 }
690 break;
692 case throw_array_store_exception_id:
693 {
694 __ set_info("throw_array_store_exception", dont_gc_arguments);
695 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
696 }
697 break;
699 case throw_class_cast_exception_id:
700 {
701 // G4: object
702 __ set_info("throw_class_cast_exception", dont_gc_arguments);
703 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
704 }
705 break;
707 case throw_incompatible_class_change_error_id:
708 {
709 __ set_info("throw_incompatible_class_cast_exception", dont_gc_arguments);
710 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
711 }
712 break;
714 case slow_subtype_check_id:
715 { // Support for uint StubRoutine::partial_subtype_check( Klass sub, Klass super );
716 // Arguments :
717 //
718 // ret : G3
719 // sub : G3, argument, destroyed
720 // super: G1, argument, not changed
721 // raddr: O7, blown by call
722 Label miss;
724 __ save_frame(0); // Blow no registers!
726 __ check_klass_subtype_slow_path(G3, G1, L0, L1, L2, L4, NULL, &miss);
728 __ mov(1, G3);
729 __ ret(); // Result in G5 is 'true'
730 __ delayed()->restore(); // free copy or add can go here
732 __ bind(miss);
733 __ mov(0, G3);
734 __ ret(); // Result in G5 is 'false'
735 __ delayed()->restore(); // free copy or add can go here
736 }
738 case monitorenter_nofpu_id:
739 case monitorenter_id:
740 { // G4: object
741 // G5: lock address
742 __ set_info("monitorenter", dont_gc_arguments);
744 int save_fpu_registers = (id == monitorenter_id);
745 // make a frame and preserve the caller's caller-save registers
746 OopMap* oop_map = save_live_registers(sasm, save_fpu_registers);
748 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), G4, G5);
750 oop_maps = new OopMapSet();
751 oop_maps->add_gc_map(call_offset, oop_map);
752 restore_live_registers(sasm, save_fpu_registers);
754 __ ret();
755 __ delayed()->restore();
756 }
757 break;
759 case monitorexit_nofpu_id:
760 case monitorexit_id:
761 { // G4: lock address
762 // note: really a leaf routine but must setup last java sp
763 // => use call_RT for now (speed can be improved by
764 // doing last java sp setup manually)
765 __ set_info("monitorexit", dont_gc_arguments);
767 int save_fpu_registers = (id == monitorexit_id);
768 // make a frame and preserve the caller's caller-save registers
769 OopMap* oop_map = save_live_registers(sasm, save_fpu_registers);
771 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), G4);
773 oop_maps = new OopMapSet();
774 oop_maps->add_gc_map(call_offset, oop_map);
775 restore_live_registers(sasm, save_fpu_registers);
777 __ ret();
778 __ delayed()->restore();
780 }
781 break;
783 case access_field_patching_id:
784 { __ set_info("access_field_patching", dont_gc_arguments);
785 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, access_field_patching));
786 }
787 break;
789 case load_klass_patching_id:
790 { __ set_info("load_klass_patching", dont_gc_arguments);
791 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching));
792 }
793 break;
795 case jvmti_exception_throw_id:
796 { // Oexception : exception
797 __ set_info("jvmti_exception_throw", dont_gc_arguments);
798 oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, Runtime1::post_jvmti_exception_throw), I0);
799 }
800 break;
802 case dtrace_object_alloc_id:
803 { // O0: object
804 __ set_info("dtrace_object_alloc", dont_gc_arguments);
805 // we can't gc here so skip the oopmap but make sure that all
806 // the live registers get saved.
807 save_live_registers(sasm);
809 __ save_thread(L7_thread_cache);
810 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc),
811 relocInfo::runtime_call_type);
812 __ delayed()->mov(I0, O0);
813 __ restore_thread(L7_thread_cache);
815 restore_live_registers(sasm);
816 __ ret();
817 __ delayed()->restore();
818 }
819 break;
821 #ifndef SERIALGC
822 case g1_pre_barrier_slow_id:
823 { // G4: previous value of memory
824 BarrierSet* bs = Universe::heap()->barrier_set();
825 if (bs->kind() != BarrierSet::G1SATBCTLogging) {
826 __ save_frame(0);
827 __ set((int)id, O1);
828 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0);
829 __ should_not_reach_here();
830 break;
831 }
833 __ set_info("g1_pre_barrier_slow_id", dont_gc_arguments);
835 Register pre_val = G4;
836 Register tmp = G1_scratch;
837 Register tmp2 = G3_scratch;
839 Label refill, restart;
840 bool with_frame = false; // I don't know if we can do with-frame.
841 int satb_q_index_byte_offset =
842 in_bytes(JavaThread::satb_mark_queue_offset() +
843 PtrQueue::byte_offset_of_index());
844 int satb_q_buf_byte_offset =
845 in_bytes(JavaThread::satb_mark_queue_offset() +
846 PtrQueue::byte_offset_of_buf());
847 __ bind(restart);
848 __ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp);
850 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false,
851 Assembler::pn, tmp, refill);
853 // If the branch is taken, no harm in executing this in the delay slot.
854 __ delayed()->ld_ptr(G2_thread, satb_q_buf_byte_offset, tmp2);
855 __ sub(tmp, oopSize, tmp);
857 __ st_ptr(pre_val, tmp2, tmp); // [_buf + index] := <address_of_card>
858 // Use return-from-leaf
859 __ retl();
860 __ delayed()->st_ptr(tmp, G2_thread, satb_q_index_byte_offset);
862 __ bind(refill);
863 __ save_frame(0);
865 __ mov(pre_val, L0);
866 __ mov(tmp, L1);
867 __ mov(tmp2, L2);
869 __ call_VM_leaf(L7_thread_cache,
870 CAST_FROM_FN_PTR(address,
871 SATBMarkQueueSet::handle_zero_index_for_thread),
872 G2_thread);
874 __ mov(L0, pre_val);
875 __ mov(L1, tmp);
876 __ mov(L2, tmp2);
878 __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
879 __ delayed()->restore();
880 }
881 break;
883 case g1_post_barrier_slow_id:
884 {
885 BarrierSet* bs = Universe::heap()->barrier_set();
886 if (bs->kind() != BarrierSet::G1SATBCTLogging) {
887 __ save_frame(0);
888 __ set((int)id, O1);
889 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0);
890 __ should_not_reach_here();
891 break;
892 }
894 __ set_info("g1_post_barrier_slow_id", dont_gc_arguments);
896 Register addr = G4;
897 Register cardtable = G5;
898 Register tmp = G1_scratch;
899 Register tmp2 = G3_scratch;
900 jbyte* byte_map_base = ((CardTableModRefBS*)bs)->byte_map_base;
902 Label not_already_dirty, restart, refill;
904 #ifdef _LP64
905 __ srlx(addr, CardTableModRefBS::card_shift, addr);
906 #else
907 __ srl(addr, CardTableModRefBS::card_shift, addr);
908 #endif
910 AddressLiteral rs(byte_map_base);
911 __ set(rs, cardtable); // cardtable := <card table base>
912 __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
914 __ br_on_reg_cond(Assembler::rc_nz, /*annul*/false, Assembler::pt,
915 tmp, not_already_dirty);
916 // Get cardtable + tmp into a reg by itself -- useful in the take-the-branch
917 // case, harmless if not.
918 __ delayed()->add(addr, cardtable, tmp2);
920 // We didn't take the branch, so we're already dirty: return.
921 // Use return-from-leaf
922 __ retl();
923 __ delayed()->nop();
925 // Not dirty.
926 __ bind(not_already_dirty);
927 // First, dirty it.
928 __ stb(G0, tmp2, 0); // [cardPtr] := 0 (i.e., dirty).
930 Register tmp3 = cardtable;
931 Register tmp4 = tmp;
933 // these registers are now dead
934 addr = cardtable = tmp = noreg;
936 int dirty_card_q_index_byte_offset =
937 in_bytes(JavaThread::dirty_card_queue_offset() +
938 PtrQueue::byte_offset_of_index());
939 int dirty_card_q_buf_byte_offset =
940 in_bytes(JavaThread::dirty_card_queue_offset() +
941 PtrQueue::byte_offset_of_buf());
942 __ bind(restart);
943 __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3);
945 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pn,
946 tmp3, refill);
947 // If the branch is taken, no harm in executing this in the delay slot.
948 __ delayed()->ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, tmp4);
949 __ sub(tmp3, oopSize, tmp3);
951 __ st_ptr(tmp2, tmp4, tmp3); // [_buf + index] := <address_of_card>
952 // Use return-from-leaf
953 __ retl();
954 __ delayed()->st_ptr(tmp3, G2_thread, dirty_card_q_index_byte_offset);
956 __ bind(refill);
957 __ save_frame(0);
959 __ mov(tmp2, L0);
960 __ mov(tmp3, L1);
961 __ mov(tmp4, L2);
963 __ call_VM_leaf(L7_thread_cache,
964 CAST_FROM_FN_PTR(address,
965 DirtyCardQueueSet::handle_zero_index_for_thread),
966 G2_thread);
968 __ mov(L0, tmp2);
969 __ mov(L1, tmp3);
970 __ mov(L2, tmp4);
972 __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
973 __ delayed()->restore();
974 }
975 break;
976 #endif // !SERIALGC
978 default:
979 { __ set_info("unimplemented entry", dont_gc_arguments);
980 __ save_frame(0);
981 __ set((int)id, O1);
982 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), O1);
983 __ should_not_reach_here();
984 }
985 break;
986 }
987 return oop_maps;
988 }
991 OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler* sasm) {
992 __ block_comment("generate_handle_exception");
994 // Save registers, if required.
995 OopMapSet* oop_maps = new OopMapSet();
996 OopMap* oop_map = NULL;
997 switch (id) {
998 case forward_exception_id:
999 // We're handling an exception in the context of a compiled frame.
1000 // The registers have been saved in the standard places. Perform
1001 // an exception lookup in the caller and dispatch to the handler
1002 // if found. Otherwise unwind and dispatch to the callers
1003 // exception handler.
1004 oop_map = generate_oop_map(sasm, true);
1006 // transfer the pending exception to the exception_oop
1007 __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
1008 __ ld_ptr(Oexception, 0, G0);
1009 __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
1010 __ add(I7, frame::pc_return_offset, Oissuing_pc);
1011 break;
1012 case handle_exception_id:
1013 // At this point all registers MAY be live.
1014 oop_map = save_live_registers(sasm);
1015 __ mov(Oexception->after_save(), Oexception);
1016 __ mov(Oissuing_pc->after_save(), Oissuing_pc);
1017 break;
1018 case handle_exception_from_callee_id:
1019 // At this point all registers except exception oop (Oexception)
1020 // and exception pc (Oissuing_pc) are dead.
1021 oop_map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
1022 sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
1023 __ save_frame_c1(frame_size_in_bytes);
1024 __ mov(Oexception->after_save(), Oexception);
1025 __ mov(Oissuing_pc->after_save(), Oissuing_pc);
1026 break;
1027 default: ShouldNotReachHere();
1028 }
1030 __ verify_not_null_oop(Oexception);
1032 // save the exception and issuing pc in the thread
1033 __ st_ptr(Oexception, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
1034 __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset()));
1036 // use the throwing pc as the return address to lookup (has bci & oop map)
1037 __ mov(Oissuing_pc, I7);
1038 __ sub(I7, frame::pc_return_offset, I7);
1039 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
1040 oop_maps->add_gc_map(call_offset, oop_map);
1042 // Note: if nmethod has been deoptimized then regardless of
1043 // whether it had a handler or not we will deoptimize
1044 // by entering the deopt blob with a pending exception.
1046 // Restore the registers that were saved at the beginning, remove
1047 // the frame and jump to the exception handler.
1048 switch (id) {
1049 case forward_exception_id:
1050 case handle_exception_id:
1051 restore_live_registers(sasm);
1052 __ jmp(O0, 0);
1053 __ delayed()->restore();
1054 break;
1055 case handle_exception_from_callee_id:
1056 // Restore SP from L7 if the exception PC is a method handle call site.
1057 __ mov(O0, G5); // Save the target address.
1058 __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
1059 __ tst(L0); // Condition codes are preserved over the restore.
1060 __ restore();
1062 __ jmp(G5, 0); // jump to the exception handler
1063 __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP); // Restore SP if required.
1064 break;
1065 default: ShouldNotReachHere();
1066 }
1068 return oop_maps;
1069 }
1072 #undef __
1074 const char *Runtime1::pd_name_for_address(address entry) {
1075 return "<unknown function>";
1076 }