Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(459)

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 7618007: Simplify handling of exits from with and catch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporate review comments Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/frames-ia32.h ('k') | src/parser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/frames-ia32.h ('k') | src/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698