< prev index next >

src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp

Print this page

312   OopMap* oop_map = save_live_registers(sasm);
313 
314   int call_offset;
315   if (arg1 == noreg) {
316     call_offset = __ call_RT(result, noreg, target);
317   } else if (arg2 == noreg) {
318     call_offset = __ call_RT(result, noreg, target, arg1);
319   } else if (arg3 == noreg) {
320     call_offset = __ call_RT(result, noreg, target, arg1, arg2);
321   } else {
322     call_offset = __ call_RT(result, noreg, target, arg1, arg2, arg3);
323   }
324   OopMapSet* oop_maps = new OopMapSet();
325   oop_maps->add_gc_map(call_offset, oop_map);
326 
327   restore_live_registers(sasm, result, noreg);
328   __ blr();
329   return oop_maps;
330 }
331 
332 static OopMapSet* stub_call_with_stack_parms(StubAssembler* sasm, Register result, address target,
333                                              int stack_parms, bool do_return = true) {
334   // Make a frame and preserve the caller's caller-save registers.
335   const int parm_size_in_bytes = align_up(stack_parms << LogBytesPerWord, frame::alignment_in_bytes);
336   const int padding = parm_size_in_bytes - (stack_parms << LogBytesPerWord);
337   OopMap* oop_map = save_live_registers(sasm, true, noreg, parm_size_in_bytes);
338 
339   int call_offset = 0;
340   switch (stack_parms) {
341     case 3:
342     __ ld(R6_ARG4, frame_size_in_bytes + padding + 16, R1_SP);
343     case 2:
344     __ ld(R5_ARG3, frame_size_in_bytes + padding + 8, R1_SP);
345     case 1:
346     __ ld(R4_ARG2, frame_size_in_bytes + padding + 0, R1_SP);
347     case 0:
348     call_offset = __ call_RT(result, noreg, target);
349     break;
350     default: Unimplemented(); break;
351   }
352   OopMapSet* oop_maps = new OopMapSet();
353   oop_maps->add_gc_map(call_offset, oop_map);
354 
355   restore_live_registers(sasm, result, noreg);
356   if (do_return) __ blr();
357   return oop_maps;
358 }
359 
360 
361 OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
362   // Make a frame and preserve the caller's caller-save registers.
363   OopMap* oop_map = save_live_registers(sasm);
364 
365   // Call the runtime patching routine, returns non-zero if nmethod got deopted.
366   int call_offset = __ call_RT(noreg, noreg, target);
367   OopMapSet* oop_maps = new OopMapSet();
368   oop_maps->add_gc_map(call_offset, oop_map);
369   __ cmpdi(CR0, R3_RET, 0);
370 
371   // Re-execute the patched instruction or, if the nmethod was deoptmized,
372   // return to the deoptimization handler entry that will cause re-execution
373   // of the current bytecode.
374   DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
375   assert(deopt_blob != nullptr, "deoptimization blob must have been created");

415         } else if (id == StubId::c1_fast_new_instance_id) {
416           __ set_info("fast new_instance", dont_gc_arguments);
417         } else {
418           assert(id == StubId::c1_fast_new_instance_init_check_id, "bad StubId");
419           __ set_info("fast new_instance init check", dont_gc_arguments);
420         }
421 
422         // We don't support eden allocation.
423 
424         oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_instance), R4_ARG2);
425       }
426       break;
427 
428     case StubId::c1_counter_overflow_id:
429         // Bci and method are on stack.
430         oop_maps = stub_call_with_stack_parms(sasm, noreg, CAST_FROM_FN_PTR(address, counter_overflow), 2);
431       break;
432 
433     case StubId::c1_new_type_array_id:
434     case StubId::c1_new_object_array_id:

435       {
436         if (id == StubId::c1_new_type_array_id) {
437           __ set_info("new_type_array", dont_gc_arguments);
438         } else {
439           __ set_info("new_object_array", dont_gc_arguments);


440         }
441 
442 #ifdef ASSERT
443         // Assert object type is really an array of the proper kind.
444         {
445           int tag = (id == StubId::c1_new_type_array_id) ? Klass::_lh_array_tag_type_value : Klass::_lh_array_tag_obj_value;
446           Label ok;
447           __ lwz(R0, in_bytes(Klass::layout_helper_offset()), R4_ARG2);
448           __ srawi(R0, R0, Klass::_lh_array_tag_shift);
449           __ cmpwi(CR0, R0, tag);
450           __ beq(CR0, ok);
451           __ stop("assert(is an array klass)");
452           __ should_not_reach_here();
453           __ bind(ok);










454         }
455 #endif // ASSERT
456 
457         // We don't support eden allocation.
458 
459         if (id == StubId::c1_new_type_array_id) {
460           oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_type_array), R4_ARG2, R5_ARG3);
461         } else {
462           oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_object_array), R4_ARG2, R5_ARG3);



463         }
464       }
465       break;
466 
467     case StubId::c1_new_multi_array_id:
468       {
469         // R4: klass
470         // R5: rank
471         // R6: address of 1st dimension
472         __ set_info("new_multi_array", dont_gc_arguments);
473         oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_multi_array), R4_ARG2, R5_ARG3, R6_ARG4);
474       }
475       break;
476 






























477     case StubId::c1_register_finalizer_id:
478       {
479         __ set_info("register_finalizer", dont_gc_arguments);
480         // This code is called via rt_call. Hence, caller-save registers have been saved.
481         Register t = R11_scratch1;
482 
483         // Load the klass and check the has finalizer flag.
484         __ load_klass(t, R3_ARG1);
485         __ lbz(t, in_bytes(Klass::misc_flags_offset()), t);
486         __ testbitdi(CR0, R0, t, exact_log2(KlassFlags::_misc_has_finalizer));
487         // Return if has_finalizer bit == 0 (CR0.eq).
488         __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CR0, Assembler::equal), Assembler::bhintbhBCLRisReturn);
489 
490         __ mflr(R0);
491         __ std(R0, _abi0(lr), R1_SP);
492         __ push_frame(frame::native_abi_reg_args_size, R0); // Empty dummy frame (no callee-save regs).
493         sasm->set_frame_size(frame::native_abi_reg_args_size / BytesPerWord);
494         OopMap* oop_map = new OopMap(frame::native_abi_reg_args_size / sizeof(jint), 0);
495         int call_offset = __ call_RT(noreg, noreg,
496                                      CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), R3_ARG1);

574         __ bctr();
575       }
576       break;
577 
578     case StubId::c1_throw_array_store_exception_id:
579       {
580         __ set_info("throw_array_store_exception", dont_gc_arguments);
581         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
582       }
583       break;
584 
585     case StubId::c1_throw_class_cast_exception_id:
586       {
587         __ set_info("throw_class_cast_exception", dont_gc_arguments);
588         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
589       }
590       break;
591 
592     case StubId::c1_throw_incompatible_class_change_error_id:
593       {
594         __ set_info("throw_incompatible_class_cast_exception", dont_gc_arguments);
595         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
596       }
597       break;
598 














599     case StubId::c1_slow_subtype_check_id:
600       { // Support for uint StubRoutine::partial_subtype_check( Klass sub, Klass super );
601         const Register sub_klass = R5,
602                        super_klass = R4,
603                        temp1_reg = R6;
604         __ check_klass_subtype_slow_path(sub_klass, super_klass, temp1_reg, noreg);
605         // Result is in CR0.
606         __ blr();
607       }
608       break;
609 
610     case StubId::c1_is_instance_of_id:
611       {
612         // Called like a C function, but without FunctionDescriptor (see LIR_Assembler::rt_call).
613 
614         // Arguments and return value.
615         Register mirror = R3_ARG1;
616         Register obj    = R4_ARG2;
617         Register result = R3_RET;
618 

312   OopMap* oop_map = save_live_registers(sasm);
313 
314   int call_offset;
315   if (arg1 == noreg) {
316     call_offset = __ call_RT(result, noreg, target);
317   } else if (arg2 == noreg) {
318     call_offset = __ call_RT(result, noreg, target, arg1);
319   } else if (arg3 == noreg) {
320     call_offset = __ call_RT(result, noreg, target, arg1, arg2);
321   } else {
322     call_offset = __ call_RT(result, noreg, target, arg1, arg2, arg3);
323   }
324   OopMapSet* oop_maps = new OopMapSet();
325   oop_maps->add_gc_map(call_offset, oop_map);
326 
327   restore_live_registers(sasm, result, noreg);
328   __ blr();
329   return oop_maps;
330 }
331 
332 static OopMapSet* stub_call_with_stack_parms(StubAssembler* sasm, Register oop_result, address target,
333                                              int stack_parms, bool do_return = true, Register result2 = noreg) {
334   // Make a frame and preserve the caller's caller-save registers.
335   const int parm_size_in_bytes = align_up(stack_parms << LogBytesPerWord, frame::alignment_in_bytes);
336   const int padding = parm_size_in_bytes - (stack_parms << LogBytesPerWord);
337   OopMap* oop_map = save_live_registers(sasm, true, noreg, parm_size_in_bytes);
338 
339   int call_offset = 0;
340   switch (stack_parms) {
341     case 3:
342     __ ld(R6_ARG4, frame_size_in_bytes + padding + 16, R1_SP);
343     case 2:
344     __ ld(R5_ARG3, frame_size_in_bytes + padding + 8, R1_SP);
345     case 1:
346     __ ld(R4_ARG2, frame_size_in_bytes + padding + 0, R1_SP);
347     case 0:
348     call_offset = __ call_RT(oop_result, noreg, target);
349     break;
350     default: Unimplemented(); break;
351   }
352   OopMapSet* oop_maps = new OopMapSet();
353   oop_maps->add_gc_map(call_offset, oop_map);
354 
355   restore_live_registers(sasm, oop_result, result2);
356   if (do_return) __ blr();
357   return oop_maps;
358 }
359 
360 
361 OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
362   // Make a frame and preserve the caller's caller-save registers.
363   OopMap* oop_map = save_live_registers(sasm);
364 
365   // Call the runtime patching routine, returns non-zero if nmethod got deopted.
366   int call_offset = __ call_RT(noreg, noreg, target);
367   OopMapSet* oop_maps = new OopMapSet();
368   oop_maps->add_gc_map(call_offset, oop_map);
369   __ cmpdi(CR0, R3_RET, 0);
370 
371   // Re-execute the patched instruction or, if the nmethod was deoptmized,
372   // return to the deoptimization handler entry that will cause re-execution
373   // of the current bytecode.
374   DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
375   assert(deopt_blob != nullptr, "deoptimization blob must have been created");

415         } else if (id == StubId::c1_fast_new_instance_id) {
416           __ set_info("fast new_instance", dont_gc_arguments);
417         } else {
418           assert(id == StubId::c1_fast_new_instance_init_check_id, "bad StubId");
419           __ set_info("fast new_instance init check", dont_gc_arguments);
420         }
421 
422         // We don't support eden allocation.
423 
424         oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_instance), R4_ARG2);
425       }
426       break;
427 
428     case StubId::c1_counter_overflow_id:
429         // Bci and method are on stack.
430         oop_maps = stub_call_with_stack_parms(sasm, noreg, CAST_FROM_FN_PTR(address, counter_overflow), 2);
431       break;
432 
433     case StubId::c1_new_type_array_id:
434     case StubId::c1_new_object_array_id:
435     case StubId::c1_new_null_free_array_id:
436       {
437         if (id == StubId::c1_new_type_array_id) {
438           __ set_info("new_type_array", dont_gc_arguments);
439         } else if (id == StubId::c1_new_object_array_id) {
440           __ set_info("new_object_array", dont_gc_arguments);
441         } else {
442           __ set_info("new_null_free_array", dont_gc_arguments);
443         }
444 
445 #ifdef ASSERT
446         // Assert object type is really an array of the proper kind.
447         __ lwz(R0, in_bytes(Klass::layout_helper_offset()), R4_ARG2);
448         __ srawi(R0, R0, Klass::_lh_array_tag_shift);
449         switch (id) {
450           case StubId::c1_new_type_array_id:
451             __ cmpwi(CR0, R0, Klass::_lh_array_tag_type_value);
452             __ asm_assert_eq("assert(is a type array klass)");
453             break;
454           case StubId::c1_new_object_array_id:
455             __ cmpwi(CR0, R0, Klass::_lh_array_tag_ref_value);  // new "[Ljava/lang/Object;"
456             __ cmpwi(CR1, R0, Klass::_lh_array_tag_flat_value); // new "[LVT;"
457             __ cror(CR0, Assembler::equal, CR1, Assembler::equal);
458             __ asm_assert_eq("assert(is an object or inline type array klass)");
459             break;
460           case StubId::c1_new_null_free_array_id:
461             __ cmpwi(CR0, R0, Klass::_lh_array_tag_flat_value); // the array can be a flat array.
462             __ cmpwi(CR1, R0, Klass::_lh_array_tag_ref_value);  // the array cannot be a flat array (due to the InlineArrayElementMaxFlatSize, etc.)
463             __ cror(CR0, Assembler::equal, CR1, Assembler::equal);
464             __ asm_assert_eq("assert(is an object or inline type array klass)");
465             break;
466           default: ShouldNotReachHere();
467         }
468 #endif // ASSERT
469 
470         // We don't support eden allocation.
471 
472         if (id == StubId::c1_new_type_array_id) {
473           oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_type_array), R4_ARG2, R5_ARG3);
474         } else if (id == StubId::c1_new_object_array_id) {
475           oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_object_array), R4_ARG2, R5_ARG3);
476         } else {
477           assert(id == StubId::c1_new_null_free_array_id, "must be");
478           oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_null_free_array), R4_ARG2, R5_ARG3);
479         }
480       }
481       break;
482 
483     case StubId::c1_new_multi_array_id:
484       {
485         // R4: klass
486         // R5: rank
487         // R6: address of 1st dimension
488         __ set_info("new_multi_array", dont_gc_arguments);
489         oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_multi_array), R4_ARG2, R5_ARG3, R6_ARG4);
490       }
491       break;
492 
493     case StubId::c1_buffer_inline_args_id:
494     case StubId::c1_buffer_inline_args_no_receiver_id:
495       {
496         address entry = (id == StubId::c1_buffer_inline_args_id) ?
497           CAST_FROM_FN_PTR(address, buffer_inline_args) :
498           CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
499 
500         __ unimplemented("c1_buffer_inline_args"); // TODO: handle arguments and return value
501         OopMap* oop_map = save_live_registers(sasm);
502         int call_offset = __ call_RT(noreg, noreg, entry, R3_ARG1);
503 
504         oop_maps = new OopMapSet();
505         oop_maps->add_gc_map(call_offset, oop_map);
506         restore_live_registers(sasm, R3_RET, noreg);
507         __ blr();
508       }
509       break;
510 
511     case StubId::c1_load_flat_array_id:
512       oop_maps = stub_call_with_stack_parms(sasm, R3_RET, CAST_FROM_FN_PTR(address, load_flat_array), 2);
513       break;
514 
515     case StubId::c1_store_flat_array_id:
516       oop_maps = stub_call_with_stack_parms(sasm, noreg, CAST_FROM_FN_PTR(address, store_flat_array), 3);
517       break;
518 
519     case StubId::c1_substitutability_check_id:
520       oop_maps = stub_call_with_stack_parms(sasm, noreg, CAST_FROM_FN_PTR(address, substitutability_check), 2, true, R3_RET);
521       break;
522 
523     case StubId::c1_register_finalizer_id:
524       {
525         __ set_info("register_finalizer", dont_gc_arguments);
526         // This code is called via rt_call. Hence, caller-save registers have been saved.
527         Register t = R11_scratch1;
528 
529         // Load the klass and check the has finalizer flag.
530         __ load_klass(t, R3_ARG1);
531         __ lbz(t, in_bytes(Klass::misc_flags_offset()), t);
532         __ testbitdi(CR0, R0, t, exact_log2(KlassFlags::_misc_has_finalizer));
533         // Return if has_finalizer bit == 0 (CR0.eq).
534         __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CR0, Assembler::equal), Assembler::bhintbhBCLRisReturn);
535 
536         __ mflr(R0);
537         __ std(R0, _abi0(lr), R1_SP);
538         __ push_frame(frame::native_abi_reg_args_size, R0); // Empty dummy frame (no callee-save regs).
539         sasm->set_frame_size(frame::native_abi_reg_args_size / BytesPerWord);
540         OopMap* oop_map = new OopMap(frame::native_abi_reg_args_size / sizeof(jint), 0);
541         int call_offset = __ call_RT(noreg, noreg,
542                                      CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), R3_ARG1);

620         __ bctr();
621       }
622       break;
623 
624     case StubId::c1_throw_array_store_exception_id:
625       {
626         __ set_info("throw_array_store_exception", dont_gc_arguments);
627         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
628       }
629       break;
630 
631     case StubId::c1_throw_class_cast_exception_id:
632       {
633         __ set_info("throw_class_cast_exception", dont_gc_arguments);
634         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
635       }
636       break;
637 
638     case StubId::c1_throw_incompatible_class_change_error_id:
639       {
640         __ set_info("throw_incompatible_class_change_error", dont_gc_arguments);
641         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
642       }
643       break;
644 
645     case StubId::c1_throw_illegal_monitor_state_exception_id:
646       {
647         __ set_info("c1_throw_illegal_monitor_state_exception", dont_gc_arguments);
648         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
649       }
650       break;
651 
652     case StubId::c1_throw_identity_exception_id:
653       {
654         __ set_info("throw_identity_exception", dont_gc_arguments);
655         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_identity_exception), true);
656       }
657       break;
658 
659     case StubId::c1_slow_subtype_check_id:
660       { // Support for uint StubRoutine::partial_subtype_check( Klass sub, Klass super );
661         const Register sub_klass = R5,
662                        super_klass = R4,
663                        temp1_reg = R6;
664         __ check_klass_subtype_slow_path(sub_klass, super_klass, temp1_reg, noreg);
665         // Result is in CR0.
666         __ blr();
667       }
668       break;
669 
670     case StubId::c1_is_instance_of_id:
671       {
672         // Called like a C function, but without FunctionDescriptor (see LIR_Assembler::rt_call).
673 
674         // Arguments and return value.
675         Register mirror = R3_ARG1;
676         Register obj    = R4_ARG2;
677         Register result = R3_RET;
678 
< prev index next >