| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 mov(esp, Operand(ebp)); | 620 mov(esp, Operand(ebp)); |
| 621 pop(ebp); | 621 pop(ebp); |
| 622 | 622 |
| 623 LeaveExitFrameEpilogue(); | 623 LeaveExitFrameEpilogue(); |
| 624 } | 624 } |
| 625 | 625 |
| 626 | 626 |
| 627 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 627 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
| 628 HandlerType type) { | 628 HandlerType type) { |
| 629 // Adjust this code if not the case. | 629 // Adjust this code if not the case. |
| 630 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 630 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 631 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 632 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 633 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 634 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 635 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 631 // The pc (return address) is already on TOS. | 636 // The pc (return address) is already on TOS. |
| 632 if (try_location == IN_JAVASCRIPT) { | 637 if (try_location == IN_JAVASCRIPT) { |
| 633 if (type == TRY_CATCH_HANDLER) { | 638 if (type == TRY_CATCH_HANDLER) { |
| 634 push(Immediate(StackHandler::TRY_CATCH)); | 639 push(Immediate(StackHandler::TRY_CATCH)); |
| 635 } else { | 640 } else { |
| 636 push(Immediate(StackHandler::TRY_FINALLY)); | 641 push(Immediate(StackHandler::TRY_FINALLY)); |
| 637 } | 642 } |
| 638 push(ebp); | 643 push(ebp); |
| 644 push(esi); |
| 639 } else { | 645 } else { |
| 640 ASSERT(try_location == IN_JS_ENTRY); | 646 ASSERT(try_location == IN_JS_ENTRY); |
| 641 // The frame pointer does not point to a JS frame so we save NULL | 647 // The frame pointer does not point to a JS frame so we save NULL |
| 642 // for ebp. We expect the code throwing an exception to check ebp | 648 // for ebp. We expect the code throwing an exception to check ebp |
| 643 // before dereferencing it to restore the context. | 649 // before dereferencing it to restore the context. |
| 644 push(Immediate(StackHandler::ENTRY)); | 650 push(Immediate(StackHandler::ENTRY)); |
| 645 push(Immediate(0)); // NULL frame pointer. | 651 push(Immediate(0)); // NULL frame pointer. |
| 652 push(Immediate(Smi::FromInt(0))); // No context. |
| 646 } | 653 } |
| 647 // Save the current handler as the next handler. | 654 // Save the current handler as the next handler. |
| 648 push(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, | 655 push(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 649 isolate()))); | 656 isolate()))); |
| 650 // Link this handler as the new current one. | 657 // Link this handler as the new current one. |
| 651 mov(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, | 658 mov(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 652 isolate())), | 659 isolate())), |
| 653 esp); | 660 esp); |
| 654 } | 661 } |
| 655 | 662 |
| 656 | 663 |
| 657 void MacroAssembler::PopTryHandler() { | 664 void MacroAssembler::PopTryHandler() { |
| 658 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 665 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 659 pop(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, | 666 pop(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 660 isolate()))); | 667 isolate()))); |
| 661 add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); | 668 add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); |
| 662 } | 669 } |
| 663 | 670 |
| 664 | 671 |
| 665 void MacroAssembler::Throw(Register value) { | 672 void MacroAssembler::Throw(Register value) { |
| 666 // Adjust this code if not the case. | 673 // Adjust this code if not the case. |
| 667 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 674 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 668 | 675 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 676 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 677 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 678 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 679 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 669 // eax must hold the exception. | 680 // eax must hold the exception. |
| 670 if (!value.is(eax)) { | 681 if (!value.is(eax)) { |
| 671 mov(eax, value); | 682 mov(eax, value); |
| 672 } | 683 } |
| 673 | 684 |
| 674 // Drop the sp to the top of the handler. | 685 // Drop the sp to the top of the handler. |
| 675 ExternalReference handler_address(Isolate::k_handler_address, | 686 ExternalReference handler_address(Isolate::k_handler_address, |
| 676 isolate()); | 687 isolate()); |
| 677 mov(esp, Operand::StaticVariable(handler_address)); | 688 mov(esp, Operand::StaticVariable(handler_address)); |
| 678 | 689 |
| 679 // Restore next handler and frame pointer, discard handler state. | 690 // Restore next handler, context, and frame pointer; discard handler state. |
| 680 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
| 681 pop(Operand::StaticVariable(handler_address)); | 691 pop(Operand::StaticVariable(handler_address)); |
| 682 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | 692 pop(esi); // Context. |
| 683 pop(ebp); | 693 pop(ebp); // Frame pointer. |
| 684 pop(edx); // Remove state. | 694 pop(edx); // State. |
| 685 | 695 |
| 686 // Before returning we restore the context from the frame pointer if | 696 // If the handler is a JS frame, restore the context to the frame. |
| 687 // not NULL. The frame pointer is NULL in the exception handler of | 697 // (edx == ENTRY) == (ebp == 0) == (esi == 0), so we could test any |
| 688 // a JS entry frame. | 698 // of them. |
| 689 Set(esi, Immediate(0)); // Tentatively set context pointer to NULL. | |
| 690 Label skip; | 699 Label skip; |
| 691 cmp(ebp, 0); | 700 cmp(Operand(edx), Immediate(StackHandler::ENTRY)); |
| 692 j(equal, &skip, Label::kNear); | 701 j(equal, &skip, Label::kNear); |
| 693 mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 702 mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); |
| 694 bind(&skip); | 703 bind(&skip); |
| 695 | 704 |
| 696 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
| 697 ret(0); | 705 ret(0); |
| 698 } | 706 } |
| 699 | 707 |
| 700 | 708 |
| 701 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, | 709 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, |
| 702 Register value) { | 710 Register value) { |
| 703 // Adjust this code if not the case. | 711 // Adjust this code if not the case. |
| 704 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 712 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 713 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 714 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 715 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 716 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 717 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 705 | 718 |
| 706 // eax must hold the exception. | 719 // eax must hold the exception. |
| 707 if (!value.is(eax)) { | 720 if (!value.is(eax)) { |
| 708 mov(eax, value); | 721 mov(eax, value); |
| 709 } | 722 } |
| 710 | 723 |
| 711 // Drop sp to the top stack handler. | 724 // Drop sp to the top stack handler. |
| 712 ExternalReference handler_address(Isolate::k_handler_address, | 725 ExternalReference handler_address(Isolate::k_handler_address, |
| 713 isolate()); | 726 isolate()); |
| 714 mov(esp, Operand::StaticVariable(handler_address)); | 727 mov(esp, Operand::StaticVariable(handler_address)); |
| 715 | 728 |
| 716 // Unwind the handlers until the ENTRY handler is found. | 729 // Unwind the handlers until the ENTRY handler is found. |
| 717 Label loop, done; | 730 Label loop, done; |
| 718 bind(&loop); | 731 bind(&loop); |
| 719 // Load the type of the current stack handler. | 732 // Load the type of the current stack handler. |
| 720 const int kStateOffset = StackHandlerConstants::kStateOffset; | 733 const int kStateOffset = StackHandlerConstants::kStateOffset; |
| 721 cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); | 734 cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); |
| 722 j(equal, &done, Label::kNear); | 735 j(equal, &done, Label::kNear); |
| 723 // Fetch the next handler in the list. | 736 // Fetch the next handler in the list. |
| 724 const int kNextOffset = StackHandlerConstants::kNextOffset; | 737 const int kNextOffset = StackHandlerConstants::kNextOffset; |
| 725 mov(esp, Operand(esp, kNextOffset)); | 738 mov(esp, Operand(esp, kNextOffset)); |
| 726 jmp(&loop); | 739 jmp(&loop); |
| 727 bind(&done); | 740 bind(&done); |
| 728 | 741 |
| 729 // Set the top handler address to next handler past the current ENTRY handler. | 742 // Set the top handler address to next handler past the current ENTRY handler. |
| 730 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
| 731 pop(Operand::StaticVariable(handler_address)); | 743 pop(Operand::StaticVariable(handler_address)); |
| 732 | 744 |
| 733 if (type == OUT_OF_MEMORY) { | 745 if (type == OUT_OF_MEMORY) { |
| 734 // Set external caught exception to false. | 746 // Set external caught exception to false. |
| 735 ExternalReference external_caught( | 747 ExternalReference external_caught( |
| 736 Isolate::k_external_caught_exception_address, | 748 Isolate::k_external_caught_exception_address, |
| 737 isolate()); | 749 isolate()); |
| 738 mov(eax, false); | 750 mov(eax, false); |
| 739 mov(Operand::StaticVariable(external_caught), eax); | 751 mov(Operand::StaticVariable(external_caught), eax); |
| 740 | 752 |
| 741 // Set pending exception and eax to out of memory exception. | 753 // Set pending exception and eax to out of memory exception. |
| 742 ExternalReference pending_exception(Isolate::k_pending_exception_address, | 754 ExternalReference pending_exception(Isolate::k_pending_exception_address, |
| 743 isolate()); | 755 isolate()); |
| 744 mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | 756 mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |
| 745 mov(Operand::StaticVariable(pending_exception), eax); | 757 mov(Operand::StaticVariable(pending_exception), eax); |
| 746 } | 758 } |
| 747 | 759 |
| 748 // Clear the context pointer. | 760 // Discard the context saved in the handler and clear the context pointer. |
| 761 pop(edx); |
| 749 Set(esi, Immediate(0)); | 762 Set(esi, Immediate(0)); |
| 750 | 763 |
| 751 // Restore fp from handler and discard handler state. | 764 // Restore fp from handler and discard handler state. |
| 752 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | |
| 753 pop(ebp); | 765 pop(ebp); |
| 754 pop(edx); // State. | 766 pop(edx); // State. |
| 755 | 767 |
| 756 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
| 757 ret(0); | 768 ret(0); |
| 758 } | 769 } |
| 759 | 770 |
| 760 | 771 |
| 761 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 772 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
| 762 Register scratch, | 773 Register scratch, |
| 763 Label* miss) { | 774 Label* miss) { |
| 764 Label same_contexts; | 775 Label same_contexts; |
| 765 | 776 |
| 766 ASSERT(!holder_reg.is(scratch)); | 777 ASSERT(!holder_reg.is(scratch)); |
| (...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2522 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); | 2533 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); |
| 2523 add(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), | 2534 add(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), |
| 2524 length); | 2535 length); |
| 2525 | 2536 |
| 2526 bind(&done); | 2537 bind(&done); |
| 2527 } | 2538 } |
| 2528 | 2539 |
| 2529 } } // namespace v8::internal | 2540 } } // namespace v8::internal |
| 2530 | 2541 |
| 2531 #endif // V8_TARGET_ARCH_IA32 | 2542 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |