comparison src/share/vm/c1x/c1x_VMEntries.cpp @ 1427:149b1d2316de

basic invokeinterface and invokevirtual support
author Lukas Stadler <lukas.stadler@oracle.com>
date Wed, 18 Aug 2010 16:47:06 -0700
parents 98fffb304868
children 695451afc619
comparison
equal deleted inserted replaced
1426:ed6bd46ad55e 1427:149b1d2316de
320 static OopMap* create_oop_map(jint frame_size, jint parameter_count, oop debug_info) { 320 static OopMap* create_oop_map(jint frame_size, jint parameter_count, oop debug_info) {
321 OopMap* map = new OopMap(frame_size, parameter_count); 321 OopMap* map = new OopMap(frame_size, parameter_count);
322 arrayOop register_map = (arrayOop)CiDebugInfo::registerRefMap(debug_info); 322 arrayOop register_map = (arrayOop)CiDebugInfo::registerRefMap(debug_info);
323 arrayOop frame_map = (arrayOop)CiDebugInfo::frameRefMap(debug_info); 323 arrayOop frame_map = (arrayOop)CiDebugInfo::frameRefMap(debug_info);
324 324
325 jint register_count = VMRegImpl::stack2reg(0)->value();
326 tty->print_cr("register count: %i", register_count);
327
328 for (jint i=0; i<C1X_REGISTER_COUNT; i++) { 325 for (jint i=0; i<C1X_REGISTER_COUNT; i++) {
329 unsigned char byte = ((unsigned char*)register_map->base(T_BYTE))[i / 8]; 326 unsigned char byte = ((unsigned char*)register_map->base(T_BYTE))[i / 8];
330 bool is_oop = (byte & (1 << (i % 8))) != 0; 327 bool is_oop = (byte & (1 << (i % 8))) != 0;
331 VMReg reg = get_hotspot_reg(i); 328 VMReg reg = get_hotspot_reg(i);
332 if (is_oop) { 329 if (is_oop) {
380 jint _frame_size; 377 jint _frame_size;
381 jint _parameter_count; 378 jint _parameter_count;
382 jint _constants_size; 379 jint _constants_size;
383 jint _total_size; 380 jint _total_size;
384 381
382 C1XCompiler::MarkId _next_call_type;
383 address _invoke_mark_pc;
384
385 CodeSection* _instructions; 385 CodeSection* _instructions;
386 CodeSection* _constants; 386 CodeSection* _constants;
387 387
388 OopRecorder* _oop_recorder; 388 OopRecorder* _oop_recorder;
389 DebugInformationRecorder* _debug_recorder; 389 DebugInformationRecorder* _debug_recorder;
449 _frame_size = CiTargetMethod::frameSize(_citarget_method); 449 _frame_size = CiTargetMethod::frameSize(_citarget_method);
450 450
451 // (very) conservative estimate: each site needs a constant section entry 451 // (very) conservative estimate: each site needs a constant section entry
452 _constants_size = _sites->length() * BytesPerLong; 452 _constants_size = _sites->length() * BytesPerLong;
453 _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size; 453 _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size;
454
455 _next_call_type = C1XCompiler::MARK_INVOKE_INVALID;
454 } 456 }
455 457
456 void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { 458 void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {
457 459
458 } 460 }
554 _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); 556 _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info));
555 oop code_pos = CiDebugInfo::codePos(debug_info); 557 oop code_pos = CiDebugInfo::codePos(debug_info);
556 oop frame = CiDebugInfo::frame(debug_info); 558 oop frame = CiDebugInfo::frame(debug_info);
557 record_frame(next_pc_offset, code_pos, frame); 559 record_frame(next_pc_offset, code_pos, frame);
558 560
559 if (method->is_static()) { 561 switch(_next_call_type) {
560 tty->print_cr("static method"); 562 case C1XCompiler::MARK_INVOKEVIRTUAL:
561 563 case C1XCompiler::MARK_INVOKEINTERFACE: {
562 address dest = SharedRuntime::get_resolve_static_call_stub(); 564 assert(!method->is_static(), "cannot call static method with invokeinterface");
563 long disp = dest - next_instruction; 565
564 assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); 566 address dest = SharedRuntime::get_resolve_virtual_call_stub();
565 *((jint*)operand) = (jint)disp; 567 long disp = dest - next_instruction;
566 568 assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
567 _instructions->relocate(instruction, relocInfo::static_call_type, Assembler::call32_operand); 569 *((jint*)operand) = (jint)disp;
568 tty->print_cr("relocating (Long) %016x/%016x", instruction, operand); 570
569 } else { 571 _instructions->relocate(instruction, virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand);
570 tty->print_cr("non-static method"); 572 break;
571 573 }
572 address dest = SharedRuntime::get_resolve_opt_virtual_call_stub(); 574 case C1XCompiler::MARK_INVOKESTATIC: {
573 long disp = dest - next_instruction; 575 assert(method->is_static(), "cannot call non-static method with invokestatic");
574 assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); 576
575 *((jint*)operand) = (jint)disp; 577 address dest = SharedRuntime::get_resolve_static_call_stub();
576 578 long disp = dest - next_instruction;
577 _instructions->relocate(instruction, relocInfo::opt_virtual_call_type, Assembler::call32_operand); 579 assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
578 tty->print_cr("relocating (Long) %016x/%016x", instruction, operand); 580 *((jint*)operand) = (jint)disp;
581
582 _instructions->relocate(instruction, relocInfo::static_call_type, Assembler::call32_operand);
583 break;
584 }
585 case C1XCompiler::MARK_INVOKESPECIAL: {
586 assert(!method->is_static(), "cannot call static method with invokespecial");
587
588 address dest = SharedRuntime::get_resolve_opt_virtual_call_stub();
589 long disp = dest - next_instruction;
590 assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
591 *((jint*)operand) = (jint)disp;
592
593 _instructions->relocate(instruction, relocInfo::opt_virtual_call_type, Assembler::call32_operand);
594 break;
595 }
596 case C1XCompiler::MARK_INVOKE_INVALID:
597 default:
598 ShouldNotReachHere();
599 break;
579 } 600 }
580 601 _next_call_type = C1XCompiler::MARK_INVOKE_INVALID;
581 _debug_recorder->end_safepoint(pc_offset); 602 _debug_recorder->end_safepoint(pc_offset);
582 } 603 }
583 } 604 }
584 605
585 void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { 606 void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
628 649
629 assert((id & C1XObjects::TYPE_MASK) == C1XObjects::CONSTANT, "unexpected DataPatch type"); 650 assert((id & C1XObjects::TYPE_MASK) == C1XObjects::CONSTANT, "unexpected DataPatch type");
630 651
631 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); 652 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
632 653
633 *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get<oop>(id)); 654 if (id == C1XObjects::DUMMY_CONSTANT) {
655 *((jobject*)operand) = (jobject)Universe::non_oop_word();
656 } else {
657 *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get<oop>(id));
658 }
634 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); 659 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
635 tty->print_cr("relocating (oop constant) at %016x/%016x", instruction, operand); 660 tty->print_cr("relocating (oop constant) at %016x/%016x", instruction, operand);
636 } 661 }
637
638 /*
639 jlong id = com_sun_hotspot_c1x_HotSpotProxy::get_id(obj);
640 switch (id & C1XObjects::TYPE_MASK) {
641 case C1XObjects::CONSTANT: {
642 address operand = Assembler::locate_operand(inst, Assembler::imm_operand);
643
644 *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get<oop>(id));
645 instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
646 tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand);
647 break;
648 }
649 case C1XObjects::STUB: {
650 address operand = Assembler::locate_operand(inst, Assembler::call32_operand);
651
652 long dest = (long)C1XObjects::getStub(id);
653 long disp = dest - (long)(operand + 4);
654 assert(disp == (int) disp, "disp doesn't fit in 32 bits");
655 *((int*)operand) = (int)disp;
656
657 instructions->relocate(inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
658 tty->print_cr("relocating (Long) %02x at %016x/%016x", inst_byte, inst, operand);
659 break;
660 }
661 }*/
662 break; 662 break;
663 } 663 }
664 default: 664 default:
665 fatal("unexpected CiKind in DataPatch"); 665 fatal("unexpected CiKind in DataPatch");
666 break; 666 break;
686 _offsets.set_value(CodeOffsets::Entry, pc_offset); 686 _offsets.set_value(CodeOffsets::Entry, pc_offset);
687 break; 687 break;
688 case C1XCompiler::MARK_VERIFIED_ENTRY: 688 case C1XCompiler::MARK_VERIFIED_ENTRY:
689 _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset); 689 _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset);
690 break; 690 break;
691 case C1XCompiler::MARK_OSR_ENTRY:
692 _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset);
693 break;
691 case C1XCompiler::MARK_STATIC_CALL_STUB: { 694 case C1XCompiler::MARK_STATIC_CALL_STUB: {
692 assert(references->length() == 1, "static call stub needs one reference"); 695 assert(references->length() == 1, "static call stub needs one reference");
693 oop ref = ((oop*)references->base(T_OBJECT))[0]; 696 oop ref = ((oop*)references->base(T_OBJECT))[0];
694 address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref); 697 address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref);
695 _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc)); 698 _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc));
696 break; 699 break;
697 } 700 }
701 case C1XCompiler::MARK_INVOKE_INVALID:
702 case C1XCompiler::MARK_INVOKEINTERFACE:
703 case C1XCompiler::MARK_INVOKESTATIC:
704 case C1XCompiler::MARK_INVOKESPECIAL:
705 case C1XCompiler::MARK_INVOKEVIRTUAL:
706 _next_call_type = (C1XCompiler::MarkId)id;
707 _invoke_mark_pc = instruction;
708 break;
709 default:
710 ShouldNotReachHere();
711 break;
698 } 712 }
699 } 713 }
700 } 714 }
701 715
702 // perform data and call relocation on the CodeBuffer 716 // perform data and call relocation on the CodeBuffer