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

Side by Side Diff: src/top.cc

Issue 174056: Add support for forceful termination of JavaScript execution. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 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/top.h ('k') | src/v8threads.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 91
92 void Top::InitializeThreadLocal() { 92 void Top::InitializeThreadLocal() {
93 thread_local_.c_entry_fp_ = 0; 93 thread_local_.c_entry_fp_ = 0;
94 thread_local_.handler_ = 0; 94 thread_local_.handler_ = 0;
95 #ifdef ENABLE_LOGGING_AND_PROFILING 95 #ifdef ENABLE_LOGGING_AND_PROFILING
96 thread_local_.js_entry_sp_ = 0; 96 thread_local_.js_entry_sp_ = 0;
97 #endif 97 #endif
98 thread_local_.stack_is_cooked_ = false; 98 thread_local_.stack_is_cooked_ = false;
99 thread_local_.try_catch_handler_ = NULL; 99 thread_local_.try_catch_handler_ = NULL;
100 thread_local_.context_ = NULL; 100 thread_local_.context_ = NULL;
101 thread_local_.thread_id_ = ThreadManager::kInvalidId;
101 thread_local_.external_caught_exception_ = false; 102 thread_local_.external_caught_exception_ = false;
102 thread_local_.failed_access_check_callback_ = NULL; 103 thread_local_.failed_access_check_callback_ = NULL;
103 clear_pending_exception(); 104 clear_pending_exception();
104 clear_pending_message(); 105 clear_pending_message();
105 clear_scheduled_exception(); 106 clear_scheduled_exception();
106 thread_local_.save_context_ = NULL; 107 thread_local_.save_context_ = NULL;
107 thread_local_.catcher_ = NULL; 108 thread_local_.catcher_ = NULL;
108 } 109 }
109 110
110 111
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 // double fault with another stack overflow exception, we use a 592 // double fault with another stack overflow exception, we use a
592 // precomputed message. This is somewhat problematic in that it 593 // precomputed message. This is somewhat problematic in that it
593 // doesn't use ReportUncaughtException to determine the location 594 // doesn't use ReportUncaughtException to determine the location
594 // from where the exception occurred. It should probably be 595 // from where the exception occurred. It should probably be
595 // reworked. 596 // reworked.
596 DoThrow(*exception, NULL, kStackOverflowMessage); 597 DoThrow(*exception, NULL, kStackOverflowMessage);
597 return Failure::Exception(); 598 return Failure::Exception();
598 } 599 }
599 600
600 601
602 Failure* Top::TerminateExecution() {
603 DoThrow(Heap::termination_exception(), NULL, NULL);
604 return Failure::Exception();
605 }
606
607
601 Failure* Top::Throw(Object* exception, MessageLocation* location) { 608 Failure* Top::Throw(Object* exception, MessageLocation* location) {
602 DoThrow(exception, location, NULL); 609 DoThrow(exception, location, NULL);
603 return Failure::Exception(); 610 return Failure::Exception();
604 } 611 }
605 612
606 613
607 Failure* Top::ReThrow(Object* exception, MessageLocation* location) { 614 Failure* Top::ReThrow(Object* exception, MessageLocation* location) {
608 // Set the exception being re-thrown. 615 // Set the exception being re-thrown.
609 set_pending_exception(exception); 616 set_pending_exception(exception);
610 return Failure::Exception(); 617 return Failure::Exception();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 MessageHandler::MakeMessageObject("uncaught_exception", 694 MessageHandler::MakeMessageObject("uncaught_exception",
688 location, 695 location,
689 HandleVector<Object>(&exception, 1), 696 HandleVector<Object>(&exception, 1),
690 stack_trace); 697 stack_trace);
691 698
692 // Report the uncaught exception. 699 // Report the uncaught exception.
693 MessageHandler::ReportMessage(location, message); 700 MessageHandler::ReportMessage(location, message);
694 } 701 }
695 702
696 703
697 bool Top::ShouldReportException(bool* is_caught_externally) { 704 bool Top::ShouldReturnException(bool* is_caught_externally,
705 bool catchable_by_javascript) {
698 // Find the top-most try-catch handler. 706 // Find the top-most try-catch handler.
699 StackHandler* handler = 707 StackHandler* handler =
700 StackHandler::FromAddress(Top::handler(Top::GetCurrentThread())); 708 StackHandler::FromAddress(Top::handler(Top::GetCurrentThread()));
701 while (handler != NULL && !handler->is_try_catch()) { 709 while (handler != NULL && !handler->is_try_catch()) {
702 handler = handler->next(); 710 handler = handler->next();
703 } 711 }
704 712
705 // Get the address of the external handler so we can compare the address to 713 // Get the address of the external handler so we can compare the address to
706 // determine which one is closer to the top of the stack. 714 // determine which one is closer to the top of the stack.
707 v8::TryCatch* try_catch = thread_local_.try_catch_handler_; 715 v8::TryCatch* try_catch = thread_local_.try_catch_handler_;
708 716
709 // The exception has been externally caught if and only if there is 717 // The exception has been externally caught if and only if there is
710 // an external handler which is on top of the top-most try-catch 718 // an external handler which is on top of the top-most try-catch
711 // handler. 719 // handler.
712 // 720 //
713 // See comments in RegisterTryCatchHandler for details. 721 // See comments in RegisterTryCatchHandler for details.
714 *is_caught_externally = try_catch != NULL && 722 *is_caught_externally = try_catch != NULL &&
715 (handler == NULL || handler == try_catch->js_handler_); 723 (handler == NULL || handler == try_catch->js_handler_ ||
724 !catchable_by_javascript);
716 725
717 if (*is_caught_externally) { 726 if (*is_caught_externally) {
718 // Only report the exception if the external handler is verbose. 727 // Only report the exception if the external handler is verbose.
719 return thread_local_.try_catch_handler_->is_verbose_; 728 return thread_local_.try_catch_handler_->is_verbose_;
720 } else { 729 } else {
721 // Report the exception if it isn't caught by JavaScript code. 730 // Report the exception if it isn't caught by JavaScript code.
722 return handler == NULL; 731 return handler == NULL;
723 } 732 }
724 } 733 }
725 734
726 735
727 void Top::DoThrow(Object* exception, 736 void Top::DoThrow(Object* exception,
728 MessageLocation* location, 737 MessageLocation* location,
729 const char* message) { 738 const char* message) {
730 ASSERT(!has_pending_exception()); 739 ASSERT(!has_pending_exception());
731 740
732 HandleScope scope; 741 HandleScope scope;
733 Handle<Object> exception_handle(exception); 742 Handle<Object> exception_handle(exception);
734 743
735 // Determine reporting and whether the exception is caught externally. 744 // Determine reporting and whether the exception is caught externally.
736 bool is_caught_externally = false; 745 bool is_caught_externally = false;
737 bool is_out_of_memory = exception == Failure::OutOfMemoryException(); 746 bool is_out_of_memory = exception == Failure::OutOfMemoryException();
738 bool should_return_exception = ShouldReportException(&is_caught_externally); 747 bool is_termination_exception = exception == Heap::termination_exception();
739 bool report_exception = !is_out_of_memory && should_return_exception; 748 bool catchable_by_javascript = !is_termination_exception && !is_out_of_memory;
749 bool should_return_exception =
750 ShouldReturnException(&is_caught_externally, catchable_by_javascript);
751 bool report_exception = catchable_by_javascript && should_return_exception;
740 752
741 #ifdef ENABLE_DEBUGGER_SUPPORT 753 #ifdef ENABLE_DEBUGGER_SUPPORT
742 // Notify debugger of exception. 754 // Notify debugger of exception.
743 Debugger::OnException(exception_handle, report_exception); 755 if (catchable_by_javascript) {
756 Debugger::OnException(exception_handle, report_exception);
757 }
744 #endif 758 #endif
745 759
746 // Generate the message. 760 // Generate the message.
747 Handle<Object> message_obj; 761 Handle<Object> message_obj;
748 MessageLocation potential_computed_location; 762 MessageLocation potential_computed_location;
749 bool try_catch_needs_message = 763 bool try_catch_needs_message =
750 is_caught_externally && 764 is_caught_externally &&
751 thread_local_.try_catch_handler_->capture_message_; 765 thread_local_.try_catch_handler_->capture_message_;
752 if (report_exception || try_catch_needs_message) { 766 if (report_exception || try_catch_needs_message) {
753 if (location == NULL) { 767 if (location == NULL) {
(...skipping 30 matching lines...) Expand all
784 } 798 }
785 799
786 800
787 void Top::ReportPendingMessages() { 801 void Top::ReportPendingMessages() {
788 ASSERT(has_pending_exception()); 802 ASSERT(has_pending_exception());
789 setup_external_caught(); 803 setup_external_caught();
790 // If the pending exception is OutOfMemoryException set out_of_memory in 804 // If the pending exception is OutOfMemoryException set out_of_memory in
791 // the global context. Note: We have to mark the global context here 805 // the global context. Note: We have to mark the global context here
792 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to 806 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
793 // set it. 807 // set it.
808 bool external_caught = thread_local_.external_caught_exception_;
794 HandleScope scope; 809 HandleScope scope;
795 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { 810 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) {
796 context()->mark_out_of_memory(); 811 context()->mark_out_of_memory();
812 } else if (thread_local_.pending_exception_ ==
813 Heap::termination_exception()) {
814 if (external_caught) {
815 thread_local_.try_catch_handler_->can_continue_ = false;
816 thread_local_.try_catch_handler_->exception_ = Heap::null_value();
817 }
797 } else { 818 } else {
798 Handle<Object> exception(pending_exception()); 819 Handle<Object> exception(pending_exception());
799 bool external_caught = thread_local_.external_caught_exception_;
800 thread_local_.external_caught_exception_ = false; 820 thread_local_.external_caught_exception_ = false;
801 if (external_caught) { 821 if (external_caught) {
822 thread_local_.try_catch_handler_->can_continue_ = true;
802 thread_local_.try_catch_handler_->exception_ = 823 thread_local_.try_catch_handler_->exception_ =
803 thread_local_.pending_exception_; 824 thread_local_.pending_exception_;
804 if (!thread_local_.pending_message_obj_->IsTheHole()) { 825 if (!thread_local_.pending_message_obj_->IsTheHole()) {
805 try_catch_handler()->message_ = thread_local_.pending_message_obj_; 826 try_catch_handler()->message_ = thread_local_.pending_message_obj_;
806 } 827 }
807 } 828 }
808 if (thread_local_.has_pending_message_) { 829 if (thread_local_.has_pending_message_) {
809 thread_local_.has_pending_message_ = false; 830 thread_local_.has_pending_message_ = false;
810 if (thread_local_.pending_message_ != NULL) { 831 if (thread_local_.pending_message_ != NULL) {
811 MessageHandler::ReportMessage(thread_local_.pending_message_); 832 MessageHandler::ReportMessage(thread_local_.pending_message_);
(...skipping 15 matching lines...) Expand all
827 } 848 }
828 clear_pending_message(); 849 clear_pending_message();
829 } 850 }
830 851
831 852
832 void Top::TraceException(bool flag) { 853 void Top::TraceException(bool flag) {
833 FLAG_trace_exception = flag; 854 FLAG_trace_exception = flag;
834 } 855 }
835 856
836 857
837 bool Top::optional_reschedule_exception(bool is_bottom_call) { 858 bool Top::OptionalRescheduleException(bool is_bottom_call,
859 bool force_clear_catchable) {
838 // Allways reschedule out of memory exceptions. 860 // Allways reschedule out of memory exceptions.
839 if (!is_out_of_memory()) { 861 if (!is_out_of_memory()) {
840 // Never reschedule the exception if this is the bottom call. 862 bool is_termination_exception =
841 bool clear_exception = is_bottom_call; 863 pending_exception() == Heap::termination_exception();
842 864
843 // If the exception is externally caught, clear it if there are no 865 // Do not reschedule the exception if this is the bottom call or
844 // JavaScript frames on the way to the C++ frame that has the 866 // if we are asked to clear catchable exceptions. Termination
845 // external handler. 867 // exceptions are not catchable and are only cleared if this is
846 if (thread_local_.external_caught_exception_) { 868 // the bottom call.
869 bool clear_exception = is_bottom_call ||
870 (force_clear_catchable && !is_termination_exception);
871
872 if (is_termination_exception) {
873 thread_local_.external_caught_exception_ = false;
874 if (is_bottom_call) {
875 clear_pending_exception();
876 return false;
877 }
878 } else if (thread_local_.external_caught_exception_) {
879 // If the exception is externally caught, clear it if there are no
880 // JavaScript frames on the way to the C++ frame that has the
881 // external handler.
847 ASSERT(thread_local_.try_catch_handler_ != NULL); 882 ASSERT(thread_local_.try_catch_handler_ != NULL);
848 Address external_handler_address = 883 Address external_handler_address =
849 reinterpret_cast<Address>(thread_local_.try_catch_handler_); 884 reinterpret_cast<Address>(thread_local_.try_catch_handler_);
850 JavaScriptFrameIterator it; 885 JavaScriptFrameIterator it;
851 if (it.done() || (it.frame()->sp() > external_handler_address)) { 886 if (it.done() || (it.frame()->sp() > external_handler_address)) {
852 clear_exception = true; 887 clear_exception = true;
853 } 888 }
854 } 889 }
855 890
856 // Clear the exception if needed. 891 // Clear the exception if needed.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 Top::break_access_->Lock(); 968 Top::break_access_->Lock();
934 } 969 }
935 970
936 971
937 ExecutionAccess::~ExecutionAccess() { 972 ExecutionAccess::~ExecutionAccess() {
938 Top::break_access_->Unlock(); 973 Top::break_access_->Unlock();
939 } 974 }
940 975
941 976
942 } } // namespace v8::internal 977 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/top.h ('k') | src/v8threads.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698