comparison src/share/vm/graal/graalCodeInstaller.cpp @ 6521:2a0c9f20baa1

consolidated framework for runtime and stub calls and moved declaration of descriptors for such calls to the source file in which they are used
author Doug Simon <doug.simon@oracle.com>
date Fri, 05 Oct 2012 17:55:12 +0200
parents e722fa145b37
children 2463eb24b644
comparison
equal deleted inserted replaced
6520:14d158886ce0 6521:2a0c9f20baa1
527 record_scope(pc_offset, code_pos, new GrowableArray<ScopeValue*>()); 527 record_scope(pc_offset, code_pos, new GrowableArray<ScopeValue*>());
528 528
529 _debug_recorder->end_safepoint(pc_offset); 529 _debug_recorder->end_safepoint(pc_offset);
530 } 530 }
531 531
532 address CodeInstaller::runtime_call_target_address(oop runtime_call) {
533 address target_addr = 0x0;
534 if (runtime_call == RuntimeCall::Debug()) {
535 TRACE_graal_3("RuntimeCall::Debug()");
536 } else if (runtime_call == RuntimeCall::UnwindException()) {
537 target_addr = Runtime1::entry_for(Runtime1::graal_unwind_exception_call_id);
538 TRACE_graal_3("RuntimeCall::UnwindException()");
539 } else if (runtime_call == RuntimeCall::SetDeoptInfo()) {
540 target_addr = Runtime1::entry_for(Runtime1::graal_set_deopt_info_id);
541 TRACE_graal_3("RuntimeCall::SetDeoptInfo()");
542 } else if (runtime_call == RuntimeCall::CreateNullPointerException()) {
543 target_addr = Runtime1::entry_for(Runtime1::graal_create_null_pointer_exception_id);
544 TRACE_graal_3("RuntimeCall::CreateNullPointerException()");
545 } else if (runtime_call == RuntimeCall::CreateOutOfBoundsException()) {
546 target_addr = Runtime1::entry_for(Runtime1::graal_create_out_of_bounds_exception_id);
547 TRACE_graal_3("RuntimeCall::CreateOutOfBoundsException()");
548 } else if (runtime_call == RuntimeCall::JavaTimeMillis()) {
549 target_addr = CAST_FROM_FN_PTR(address, os::javaTimeMillis);
550 TRACE_graal_3("RuntimeCall::JavaTimeMillis()");
551 } else if (runtime_call == RuntimeCall::JavaTimeNanos()) {
552 target_addr = CAST_FROM_FN_PTR(address, os::javaTimeNanos);
553 TRACE_graal_3("RuntimeCall::JavaTimeNanos()");
554 } else if (runtime_call == RuntimeCall::ArithmeticFrem()) {
555 target_addr = Runtime1::entry_for(Runtime1::graal_arithmetic_frem_id);
556 TRACE_graal_3("RuntimeCall::ArithmeticFrem()");
557 } else if (runtime_call == RuntimeCall::ArithmeticDrem()) {
558 target_addr = Runtime1::entry_for(Runtime1::graal_arithmetic_drem_id);
559 TRACE_graal_3("RuntimeCall::ArithmeticDrem()");
560 } else if (runtime_call == RuntimeCall::ArithmeticSin()) {
561 target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
562 TRACE_graal_3("RuntimeCall::ArithmeticSin()");
563 } else if (runtime_call == RuntimeCall::ArithmeticCos()) {
564 target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
565 TRACE_graal_3("RuntimeCall::ArithmeticCos()");
566 } else if (runtime_call == RuntimeCall::ArithmeticTan()) {
567 target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
568 TRACE_graal_3("RuntimeCall::ArithmeticTan()");
569 } else if (runtime_call == RuntimeCall::RegisterFinalizer()) {
570 target_addr = Runtime1::entry_for(Runtime1::register_finalizer_id);
571 TRACE_graal_3("RuntimeCall::RegisterFinalizer()");
572 } else if (runtime_call == RuntimeCall::Deoptimize()) {
573 target_addr = SharedRuntime::deopt_blob()->uncommon_trap();
574 TRACE_graal_3("RuntimeCall::Deoptimize()");
575 } else if (runtime_call == RuntimeCall::GenericCallback()) {
576 target_addr = Runtime1::entry_for(Runtime1::graal_generic_callback_id);
577 TRACE_graal_3("RuntimeCall::GenericCallback()");
578 } else if (runtime_call == RuntimeCall::LogPrimitive()) {
579 target_addr = Runtime1::entry_for(Runtime1::graal_log_primitive_id);
580 TRACE_graal_3("RuntimeCall::LogPrimitive()");
581 } else if (runtime_call == RuntimeCall::LogPrintf()) {
582 target_addr = Runtime1::entry_for(Runtime1::graal_log_printf_id);
583 TRACE_graal_3("RuntimeCall::LogPrintf()");
584 } else if (runtime_call == RuntimeCall::LogObject()) {
585 target_addr = Runtime1::entry_for(Runtime1::graal_log_object_id);
586 TRACE_graal_3("RuntimeCall::LogObject()");
587 } else {
588 runtime_call->print();
589 fatal("runtime_call not implemented");
590 }
591 return target_addr;
592 }
593
594 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { 532 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) {
595 oop target = InstalledCode_Call::target(site); 533 oop target = InstalledCode_Call::target(site);
596 instanceKlass* target_klass = instanceKlass::cast(target->klass()); 534 instanceKlass* target_klass = instanceKlass::cast(target->klass());
597 535
598 oop runtime_call = NULL; // RuntimeCall
599 oop hotspot_method = NULL; // JavaMethod 536 oop hotspot_method = NULL; // JavaMethod
600 oop global_stub = NULL; 537 oop global_stub = NULL;
601 538
602 if (target_klass->is_subclass_of(SystemDictionary::Long_klass())) { 539 if (target_klass->is_subclass_of(SystemDictionary::Long_klass())) {
603 global_stub = target; 540 global_stub = target;
604 } else if (target->is_a(RuntimeCall::klass())) {
605 runtime_call = target;
606 } else { 541 } else {
607 hotspot_method = target; 542 hotspot_method = target;
608 } 543 }
609 544
610 oop debug_info = InstalledCode_Call::debugInfo(site); 545 oop debug_info = InstalledCode_Call::debugInfo(site);
611 546
612 assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type"); 547 assert((hotspot_method ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type");
613 548
614 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); 549 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
615 jint next_pc_offset = 0x0; 550 jint next_pc_offset = 0x0;
616 bool is_call_reg = false; 551 bool is_call_reg = false;
617 if (inst->is_call() || inst->is_jump()) { 552 if (inst->is_call() || inst->is_jump()) {
628 assert(hotspot_method != NULL, "only valid for virtual calls"); 563 assert(hotspot_method != NULL, "only valid for virtual calls");
629 is_call_reg = true; 564 is_call_reg = true;
630 next_pc_offset = pc_offset + ((NativeCallReg *) inst)->next_instruction_offset(); 565 next_pc_offset = pc_offset + ((NativeCallReg *) inst)->next_instruction_offset();
631 } else { 566 } else {
632 tty->print_cr("at pc_offset %d", pc_offset); 567 tty->print_cr("at pc_offset %d", pc_offset);
633 runtime_call->print();
634 fatal("unsupported type of instruction for call site"); 568 fatal("unsupported type of instruction for call site");
635 } 569 }
636 570
637 if (target->is_a(SystemDictionary::HotSpotCompiledMethod_klass())) { 571 if (target->is_a(SystemDictionary::HotSpotCompiledMethod_klass())) {
638 assert(inst->is_jump(), "jump expected"); 572 assert(inst->is_jump(), "jump expected");
648 oop frame = DebugInfo::bytecodePosition(debug_info); 582 oop frame = DebugInfo::bytecodePosition(debug_info);
649 _debug_recorder->add_safepoint(next_pc_offset, BytecodeFrame::leafGraphId(frame), create_oop_map(_total_frame_size, _parameter_count, debug_info)); 583 _debug_recorder->add_safepoint(next_pc_offset, BytecodeFrame::leafGraphId(frame), create_oop_map(_total_frame_size, _parameter_count, debug_info));
650 record_scope(next_pc_offset, frame, new GrowableArray<ScopeValue*>()); 584 record_scope(next_pc_offset, frame, new GrowableArray<ScopeValue*>());
651 } 585 }
652 586
653 if (runtime_call != NULL) { 587 if (global_stub != NULL) {
654 if (runtime_call != RuntimeCall::Debug()) {
655 address target_addr = runtime_call_target_address(runtime_call);
656
657 if (inst->is_call()) {
658 // NOTE: for call without a mov, the offset must fit a 32-bit immediate
659 // see also CompilerToVM.getMaxCallTargetOffset()
660 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
661 call->set_destination(target_addr);
662 _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
663 } else if (inst->is_mov_literal64()) {
664 NativeMovConstReg* mov = nativeMovConstReg_at(_instructions->start() + pc_offset);
665 mov->set_data((intptr_t) target_addr);
666 _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
667 } else {
668 runtime_call->print();
669 fatal("unknown type of instruction for runtime call");
670 }
671 }
672 } else if (global_stub != NULL) {
673 assert(java_lang_boxing_object::is_instance(global_stub, T_LONG), "global_stub needs to be of type Long"); 588 assert(java_lang_boxing_object::is_instance(global_stub, T_LONG), "global_stub needs to be of type Long");
674 589
675 if (inst->is_call()) { 590 if (inst->is_call()) {
676 nativeCall_at((address)inst)->set_destination(VmIds::getStub(global_stub)); 591 // NOTE: for call without a mov, the offset must fit a 32-bit immediate
592 // see also CompilerToVM.getMaxCallTargetOffset()
593 NativeCall* call = nativeCall_at((address) (inst));
594 call->set_destination(VmIds::getStub(global_stub));
595 _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
596 } else if (inst->is_mov_literal64()) {
597 NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst));
598 mov->set_data((intptr_t) VmIds::getStub(global_stub));
599 _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
677 } else { 600 } else {
678 nativeJump_at((address)inst)->set_jump_destination(VmIds::getStub(global_stub)); 601 NativeJump* jump = nativeJump_at((address) (inst));
679 } 602 jump->set_jump_destination(VmIds::getStub(global_stub));
680 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); 603 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
604 }
681 TRACE_graal_3("relocating (stub) at %016x", inst); 605 TRACE_graal_3("relocating (stub) at %016x", inst);
682 } else { // method != NULL 606 } else { // method != NULL
683 assert(hotspot_method != NULL, "unexpected JavaMethod"); 607 assert(hotspot_method != NULL, "unexpected JavaMethod");
684 assert(debug_info != NULL, "debug info expected"); 608 assert(debug_info != NULL, "debug info expected");
685 609