| 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 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 mov(esp, Operand(ebp)); | 535 mov(esp, Operand(ebp)); |
| 536 pop(ebp); | 536 pop(ebp); |
| 537 | 537 |
| 538 LeaveExitFrameEpilogue(); | 538 LeaveExitFrameEpilogue(); |
| 539 } | 539 } |
| 540 | 540 |
| 541 | 541 |
| 542 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 542 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
| 543 HandlerType type) { | 543 HandlerType type) { |
| 544 // Adjust this code if not the case. | 544 // Adjust this code if not the case. |
| 545 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 545 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 546 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 547 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 548 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 549 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 550 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 546 // The pc (return address) is already on TOS. | 551 // The pc (return address) is already on TOS. |
| 547 if (try_location == IN_JAVASCRIPT) { | 552 if (try_location == IN_JAVASCRIPT) { |
| 548 if (type == TRY_CATCH_HANDLER) { | 553 if (type == TRY_CATCH_HANDLER) { |
| 549 push(Immediate(StackHandler::TRY_CATCH)); | 554 push(Immediate(StackHandler::TRY_CATCH)); |
| 550 } else { | 555 } else { |
| 551 push(Immediate(StackHandler::TRY_FINALLY)); | 556 push(Immediate(StackHandler::TRY_FINALLY)); |
| 552 } | 557 } |
| 553 push(ebp); | 558 push(ebp); |
| 559 push(esi); |
| 554 } else { | 560 } else { |
| 555 ASSERT(try_location == IN_JS_ENTRY); | 561 ASSERT(try_location == IN_JS_ENTRY); |
| 556 // The frame pointer does not point to a JS frame so we save NULL | 562 // The frame pointer does not point to a JS frame so we save NULL |
| 557 // for ebp. We expect the code throwing an exception to check ebp | 563 // for ebp. We expect the code throwing an exception to check ebp |
| 558 // before dereferencing it to restore the context. | 564 // before dereferencing it to restore the context. |
| 559 push(Immediate(StackHandler::ENTRY)); | 565 push(Immediate(StackHandler::ENTRY)); |
| 560 push(Immediate(0)); // NULL frame pointer. | 566 push(Immediate(0)); // NULL frame pointer. |
| 567 push(Immediate(Smi::FromInt(0))); // No context. |
| 561 } | 568 } |
| 562 // Save the current handler as the next handler. | 569 // Save the current handler as the next handler. |
| 563 push(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, | 570 push(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 564 isolate()))); | 571 isolate()))); |
| 565 // Link this handler as the new current one. | 572 // Link this handler as the new current one. |
| 566 mov(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, | 573 mov(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 567 isolate())), | 574 isolate())), |
| 568 esp); | 575 esp); |
| 569 } | 576 } |
| 570 | 577 |
| 571 | 578 |
| 572 void MacroAssembler::PopTryHandler() { | 579 void MacroAssembler::PopTryHandler() { |
| 573 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 580 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 574 pop(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, | 581 pop(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, |
| 575 isolate()))); | 582 isolate()))); |
| 576 add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); | 583 add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); |
| 577 } | 584 } |
| 578 | 585 |
| 579 | 586 |
| 580 void MacroAssembler::Throw(Register value) { | 587 void MacroAssembler::Throw(Register value) { |
| 581 // Adjust this code if not the case. | 588 // Adjust this code if not the case. |
| 582 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 589 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 583 | 590 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 591 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 592 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 593 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 594 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 584 // eax must hold the exception. | 595 // eax must hold the exception. |
| 585 if (!value.is(eax)) { | 596 if (!value.is(eax)) { |
| 586 mov(eax, value); | 597 mov(eax, value); |
| 587 } | 598 } |
| 588 | 599 |
| 589 // Drop the sp to the top of the handler. | 600 // Drop the sp to the top of the handler. |
| 590 ExternalReference handler_address(Isolate::k_handler_address, | 601 ExternalReference handler_address(Isolate::k_handler_address, |
| 591 isolate()); | 602 isolate()); |
| 592 mov(esp, Operand::StaticVariable(handler_address)); | 603 mov(esp, Operand::StaticVariable(handler_address)); |
| 593 | 604 |
| 594 // Restore next handler and frame pointer, discard handler state. | 605 // Restore next handler, context, and frame pointer; discard handler state. |
| 595 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
| 596 pop(Operand::StaticVariable(handler_address)); | 606 pop(Operand::StaticVariable(handler_address)); |
| 597 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | 607 pop(esi); // Context. |
| 598 pop(ebp); | 608 pop(ebp); // Frame pointer. |
| 599 pop(edx); // Remove state. | 609 pop(edx); // State. |
| 600 | 610 |
| 601 // Before returning we restore the context from the frame pointer if | 611 // If the handler is a JS frame, restore the context to the frame. |
| 602 // not NULL. The frame pointer is NULL in the exception handler of | 612 // (edx == ENTRY) == (ebp == 0) == (esi == 0), so we could test any |
| 603 // a JS entry frame. | 613 // of them. |
| 604 Set(esi, Immediate(0)); // Tentatively set context pointer to NULL. | |
| 605 Label skip; | 614 Label skip; |
| 606 cmp(ebp, 0); | 615 cmp(Operand(edx), Immediate(StackHandler::ENTRY)); |
| 607 j(equal, &skip, Label::kNear); | 616 j(equal, &skip, Label::kNear); |
| 608 mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 617 mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); |
| 609 bind(&skip); | 618 bind(&skip); |
| 610 | 619 |
| 611 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
| 612 ret(0); | 620 ret(0); |
| 613 } | 621 } |
| 614 | 622 |
| 615 | 623 |
| 616 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, | 624 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, |
| 617 Register value) { | 625 Register value) { |
| 618 // Adjust this code if not the case. | 626 // Adjust this code if not the case. |
| 619 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 627 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 628 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 629 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize); |
| 630 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 631 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize); |
| 632 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 620 | 633 |
| 621 // eax must hold the exception. | 634 // eax must hold the exception. |
| 622 if (!value.is(eax)) { | 635 if (!value.is(eax)) { |
| 623 mov(eax, value); | 636 mov(eax, value); |
| 624 } | 637 } |
| 625 | 638 |
| 626 // Drop sp to the top stack handler. | 639 // Drop sp to the top stack handler. |
| 627 ExternalReference handler_address(Isolate::k_handler_address, | 640 ExternalReference handler_address(Isolate::k_handler_address, |
| 628 isolate()); | 641 isolate()); |
| 629 mov(esp, Operand::StaticVariable(handler_address)); | 642 mov(esp, Operand::StaticVariable(handler_address)); |
| 630 | 643 |
| 631 // Unwind the handlers until the ENTRY handler is found. | 644 // Unwind the handlers until the ENTRY handler is found. |
| 632 Label loop, done; | 645 Label loop, done; |
| 633 bind(&loop); | 646 bind(&loop); |
| 634 // Load the type of the current stack handler. | 647 // Load the type of the current stack handler. |
| 635 const int kStateOffset = StackHandlerConstants::kStateOffset; | 648 const int kStateOffset = StackHandlerConstants::kStateOffset; |
| 636 cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); | 649 cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); |
| 637 j(equal, &done, Label::kNear); | 650 j(equal, &done, Label::kNear); |
| 638 // Fetch the next handler in the list. | 651 // Fetch the next handler in the list. |
| 639 const int kNextOffset = StackHandlerConstants::kNextOffset; | 652 const int kNextOffset = StackHandlerConstants::kNextOffset; |
| 640 mov(esp, Operand(esp, kNextOffset)); | 653 mov(esp, Operand(esp, kNextOffset)); |
| 641 jmp(&loop); | 654 jmp(&loop); |
| 642 bind(&done); | 655 bind(&done); |
| 643 | 656 |
| 644 // Set the top handler address to next handler past the current ENTRY handler. | 657 // Set the top handler address to next handler past the current ENTRY handler. |
| 645 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
| 646 pop(Operand::StaticVariable(handler_address)); | 658 pop(Operand::StaticVariable(handler_address)); |
| 647 | 659 |
| 648 if (type == OUT_OF_MEMORY) { | 660 if (type == OUT_OF_MEMORY) { |
| 649 // Set external caught exception to false. | 661 // Set external caught exception to false. |
| 650 ExternalReference external_caught( | 662 ExternalReference external_caught( |
| 651 Isolate::k_external_caught_exception_address, | 663 Isolate::k_external_caught_exception_address, |
| 652 isolate()); | 664 isolate()); |
| 653 mov(eax, false); | 665 mov(eax, false); |
| 654 mov(Operand::StaticVariable(external_caught), eax); | 666 mov(Operand::StaticVariable(external_caught), eax); |
| 655 | 667 |
| 656 // Set pending exception and eax to out of memory exception. | 668 // Set pending exception and eax to out of memory exception. |
| 657 ExternalReference pending_exception(Isolate::k_pending_exception_address, | 669 ExternalReference pending_exception(Isolate::k_pending_exception_address, |
| 658 isolate()); | 670 isolate()); |
| 659 mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | 671 mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |
| 660 mov(Operand::StaticVariable(pending_exception), eax); | 672 mov(Operand::StaticVariable(pending_exception), eax); |
| 661 } | 673 } |
| 662 | 674 |
| 663 // Clear the context pointer. | 675 // Discard the context saved in the handler and clear the context pointer. |
| 676 pop(edx); |
| 664 Set(esi, Immediate(0)); | 677 Set(esi, Immediate(0)); |
| 665 | 678 |
| 666 // Restore fp from handler and discard handler state. | 679 // Restore fp from handler and discard handler state. |
| 667 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | |
| 668 pop(ebp); | 680 pop(ebp); |
| 669 pop(edx); // State. | 681 pop(edx); // State. |
| 670 | 682 |
| 671 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
| 672 ret(0); | 683 ret(0); |
| 673 } | 684 } |
| 674 | 685 |
| 675 | 686 |
| 676 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 687 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
| 677 Register scratch, | 688 Register scratch, |
| 678 Label* miss) { | 689 Label* miss) { |
| 679 Label same_contexts; | 690 Label same_contexts; |
| 680 | 691 |
| 681 ASSERT(!holder_reg.is(scratch)); | 692 ASSERT(!holder_reg.is(scratch)); |
| (...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2237 | 2248 |
| 2238 // Check that the code was patched as expected. | 2249 // Check that the code was patched as expected. |
| 2239 ASSERT(masm_.pc_ == address_ + size_); | 2250 ASSERT(masm_.pc_ == address_ + size_); |
| 2240 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2251 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 2241 } | 2252 } |
| 2242 | 2253 |
| 2243 | 2254 |
| 2244 } } // namespace v8::internal | 2255 } } // namespace v8::internal |
| 2245 | 2256 |
| 2246 #endif // V8_TARGET_ARCH_IA32 | 2257 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |