Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/x86_32.ad @ 4947:fd8114661503
7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
Summary: For C2 moved saving EBP after ESP adjustment. For C1 generated 5 byte nop instruction first if needed.
Reviewed-by: never, twisti, azeemj
author | kvn |
---|---|
date | Wed, 15 Feb 2012 21:37:49 -0800 |
parents | e9a5e0a812c8 |
children | 9b8ce46870df |
comparison
equal
deleted
inserted
replaced
4946:69333a2fbae2 | 4947:fd8114661503 |
---|---|
548 #endif | 548 #endif |
549 | 549 |
550 | 550 |
551 //============================================================================= | 551 //============================================================================= |
552 #ifndef PRODUCT | 552 #ifndef PRODUCT |
553 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { | 553 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { |
554 Compile* C = ra_->C; | 554 Compile* C = ra_->C; |
555 if( C->in_24_bit_fp_mode() ) { | |
556 st->print("FLDCW 24 bit fpu control word"); | |
557 st->print_cr(""); st->print("\t"); | |
558 } | |
559 | 555 |
560 int framesize = C->frame_slots() << LogBytesPerInt; | 556 int framesize = C->frame_slots() << LogBytesPerInt; |
561 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); | 557 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); |
562 // Remove two words for return addr and rbp, | 558 // Remove wordSize for return addr which is already pushed. |
563 framesize -= 2*wordSize; | 559 framesize -= wordSize; |
564 | 560 |
565 // Calls to C2R adapters often do not accept exceptional returns. | |
566 // We require that their callers must bang for them. But be careful, because | |
567 // some VM calls (such as call site linkage) can use several kilobytes of | |
568 // stack. But the stack safety zone should account for that. | |
569 // See bugs 4446381, 4468289, 4497237. | |
570 if (C->need_stack_bang(framesize)) { | 561 if (C->need_stack_bang(framesize)) { |
571 st->print_cr("# stack bang"); st->print("\t"); | |
572 } | |
573 st->print_cr("PUSHL EBP"); st->print("\t"); | |
574 | |
575 if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth | |
576 st->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check"); | |
577 st->print_cr(""); st->print("\t"); | |
578 framesize -= wordSize; | 562 framesize -= wordSize; |
579 } | 563 st->print("# stack bang"); |
580 | 564 st->print("\n\t"); |
581 if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) { | 565 st->print("PUSH EBP\t# Save EBP"); |
582 if (framesize) { | 566 if (framesize) { |
583 st->print("SUB ESP,%d\t# Create frame",framesize); | 567 st->print("\n\t"); |
568 st->print("SUB ESP, #%d\t# Create frame",framesize); | |
584 } | 569 } |
585 } else { | 570 } else { |
586 st->print("SUB ESP,%d\t# Create frame",framesize); | 571 st->print("SUB ESP, #%d\t# Create frame",framesize); |
572 st->print("\n\t"); | |
573 framesize -= wordSize; | |
574 st->print("MOV [ESP + #%d], EBP\t# Save EBP",framesize); | |
587 } | 575 } |
576 | |
577 if (VerifyStackAtCalls) { | |
578 st->print("\n\t"); | |
579 framesize -= wordSize; | |
580 st->print("MOV [ESP + #%d], 0xBADB100D\t# Majik cookie for stack depth check",framesize); | |
581 } | |
582 | |
583 if( C->in_24_bit_fp_mode() ) { | |
584 st->print("\n\t"); | |
585 st->print("FLDCW \t# load 24 bit fpu control word"); | |
586 } | |
587 if (UseSSE >= 2 && VerifyFPU) { | |
588 st->print("\n\t"); | |
589 st->print("# verify FPU stack (must be clean on entry)"); | |
590 } | |
591 | |
592 #ifdef ASSERT | |
593 if (VerifyStackAtCalls) { | |
594 st->print("\n\t"); | |
595 st->print("# stack alignment check"); | |
596 } | |
597 #endif | |
598 st->cr(); | |
588 } | 599 } |
589 #endif | 600 #endif |
590 | 601 |
591 | 602 |
592 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | 603 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
593 Compile* C = ra_->C; | 604 Compile* C = ra_->C; |
594 | 605 MacroAssembler _masm(&cbuf); |
595 if (UseSSE >= 2 && VerifyFPU) { | |
596 MacroAssembler masm(&cbuf); | |
597 masm.verify_FPU(0, "FPU stack must be clean on entry"); | |
598 } | |
599 | |
600 // WARNING: Initial instruction MUST be 5 bytes or longer so that | |
601 // NativeJump::patch_verified_entry will be able to patch out the entry | |
602 // code safely. The fldcw is ok at 6 bytes, the push to verify stack | |
603 // depth is ok at 5 bytes, the frame allocation can be either 3 or | |
604 // 6 bytes. So if we don't do the fldcw or the push then we must | |
605 // use the 6 byte frame allocation even if we have no frame. :-( | |
606 // If method sets FPU control word do it now | |
607 if( C->in_24_bit_fp_mode() ) { | |
608 MacroAssembler masm(&cbuf); | |
609 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24())); | |
610 } | |
611 | 606 |
612 int framesize = C->frame_slots() << LogBytesPerInt; | 607 int framesize = C->frame_slots() << LogBytesPerInt; |
613 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); | 608 |
614 // Remove two words for return addr and rbp, | 609 __ verified_entry(framesize, C->need_stack_bang(framesize), C->in_24_bit_fp_mode()); |
615 framesize -= 2*wordSize; | 610 |
616 | |
617 // Calls to C2R adapters often do not accept exceptional returns. | |
618 // We require that their callers must bang for them. But be careful, because | |
619 // some VM calls (such as call site linkage) can use several kilobytes of | |
620 // stack. But the stack safety zone should account for that. | |
621 // See bugs 4446381, 4468289, 4497237. | |
622 if (C->need_stack_bang(framesize)) { | |
623 MacroAssembler masm(&cbuf); | |
624 masm.generate_stack_overflow_check(framesize); | |
625 } | |
626 | |
627 // We always push rbp, so that on return to interpreter rbp, will be | |
628 // restored correctly and we can correct the stack. | |
629 emit_opcode(cbuf, 0x50 | EBP_enc); | |
630 | |
631 if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth | |
632 emit_opcode(cbuf, 0x68); // push 0xbadb100d | |
633 emit_d32(cbuf, 0xbadb100d); | |
634 framesize -= wordSize; | |
635 } | |
636 | |
637 if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) { | |
638 if (framesize) { | |
639 emit_opcode(cbuf, 0x83); // sub SP,#framesize | |
640 emit_rm(cbuf, 0x3, 0x05, ESP_enc); | |
641 emit_d8(cbuf, framesize); | |
642 } | |
643 } else { | |
644 emit_opcode(cbuf, 0x81); // sub SP,#framesize | |
645 emit_rm(cbuf, 0x3, 0x05, ESP_enc); | |
646 emit_d32(cbuf, framesize); | |
647 } | |
648 C->set_frame_complete(cbuf.insts_size()); | 611 C->set_frame_complete(cbuf.insts_size()); |
649 | |
650 #ifdef ASSERT | |
651 if (VerifyStackAtCalls) { | |
652 Label L; | |
653 MacroAssembler masm(&cbuf); | |
654 masm.push(rax); | |
655 masm.mov(rax, rsp); | |
656 masm.andptr(rax, StackAlignmentInBytes-1); | |
657 masm.cmpptr(rax, StackAlignmentInBytes-wordSize); | |
658 masm.pop(rax); | |
659 masm.jcc(Assembler::equal, L); | |
660 masm.stop("Stack is not properly aligned!"); | |
661 masm.bind(L); | |
662 } | |
663 #endif | |
664 | 612 |
665 if (C->has_mach_constant_base_node()) { | 613 if (C->has_mach_constant_base_node()) { |
666 // NOTE: We set the table base offset here because users might be | 614 // NOTE: We set the table base offset here because users might be |
667 // emitted before MachConstantBaseNode. | 615 // emitted before MachConstantBaseNode. |
668 Compile::ConstantTable& constant_table = C->constant_table(); | 616 Compile::ConstantTable& constant_table = C->constant_table(); |