OLD | NEW |
---|---|
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
59 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); | 59 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); |
60 Iterate(v, thread); | 60 Iterate(v, thread); |
61 return thread_storage + sizeof(ThreadLocalTop); | 61 return thread_storage + sizeof(ThreadLocalTop); |
62 } | 62 } |
63 | 63 |
64 | 64 |
65 #define VISIT(field) v->VisitPointer(reinterpret_cast<Object**>(&(field))); | 65 #define VISIT(field) v->VisitPointer(reinterpret_cast<Object**>(&(field))); |
66 | 66 |
67 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { | 67 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { |
68 v->VisitPointer(&(thread->pending_exception_)); | 68 v->VisitPointer(&(thread->pending_exception_)); |
69 v->VisitPointer(&(thread->pending_message_obj_)); | |
70 v->VisitPointer(bit_cast<Object**, Script**>(&(thread->pending_message_script_ ))); | |
69 v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_))); | 71 v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_))); |
70 v->VisitPointer(&(thread->scheduled_exception_)); | 72 v->VisitPointer(&(thread->scheduled_exception_)); |
71 | 73 |
72 for (v8::TryCatch* block = thread->try_catch_handler_; | 74 for (v8::TryCatch* block = thread->try_catch_handler_; |
73 block != NULL; | 75 block != NULL; |
74 block = block->next_) { | 76 block = block->next_) { |
75 v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_))); | 77 v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_))); |
76 v->VisitPointer(bit_cast<Object**, void**>(&(block->message_))); | 78 v->VisitPointer(bit_cast<Object**, void**>(&(block->message_))); |
77 } | 79 } |
78 | 80 |
(...skipping 13 matching lines...) Expand all Loading... | |
92 | 94 |
93 void Top::InitializeThreadLocal() { | 95 void Top::InitializeThreadLocal() { |
94 thread_local_.c_entry_fp_ = 0; | 96 thread_local_.c_entry_fp_ = 0; |
95 thread_local_.handler_ = 0; | 97 thread_local_.handler_ = 0; |
96 thread_local_.stack_is_cooked_ = false; | 98 thread_local_.stack_is_cooked_ = false; |
97 thread_local_.try_catch_handler_ = NULL; | 99 thread_local_.try_catch_handler_ = NULL; |
98 thread_local_.context_ = NULL; | 100 thread_local_.context_ = NULL; |
99 thread_local_.external_caught_exception_ = false; | 101 thread_local_.external_caught_exception_ = false; |
100 thread_local_.failed_access_check_callback_ = NULL; | 102 thread_local_.failed_access_check_callback_ = NULL; |
101 clear_pending_exception(); | 103 clear_pending_exception(); |
104 clear_pending_message(); | |
102 clear_scheduled_exception(); | 105 clear_scheduled_exception(); |
103 thread_local_.save_context_ = NULL; | 106 thread_local_.save_context_ = NULL; |
104 thread_local_.catcher_ = NULL; | 107 thread_local_.catcher_ = NULL; |
105 } | 108 } |
106 | 109 |
107 | 110 |
108 // Create a dummy thread that will wait forever on a semaphore. The only | 111 // Create a dummy thread that will wait forever on a semaphore. The only |
109 // purpose for this thread is to have some stack area to save essential data | 112 // purpose for this thread is to have some stack area to save essential data |
110 // into for use by a stacks only core dump (aka minidump). | 113 // into for use by a stacks only core dump (aka minidump). |
111 class PreallocatedMemoryThread: public Thread { | 114 class PreallocatedMemoryThread: public Thread { |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
729 MessageHandler::MakeMessageObject("uncaught_exception", | 732 MessageHandler::MakeMessageObject("uncaught_exception", |
730 location, | 733 location, |
731 HandleVector<Object>(&exception, 1), | 734 HandleVector<Object>(&exception, 1), |
732 stack_trace); | 735 stack_trace); |
733 | 736 |
734 // Report the uncaught exception. | 737 // Report the uncaught exception. |
735 MessageHandler::ReportMessage(location, message); | 738 MessageHandler::ReportMessage(location, message); |
736 } | 739 } |
737 | 740 |
738 | 741 |
739 bool Top::ShouldReportException(bool* is_caught_externally) { | 742 bool Top::IsUncaughtException(bool* is_caught_externally) { |
Søren Thygesen Gjesse
2008/12/04 07:53:53
This function does not only check whether the exce
olehougaard
2008/12/04 08:44:35
Reverting to the original name.
| |
740 StackHandler* handler = | 743 StackHandler* handler = |
741 StackHandler::FromAddress(Top::handler(Top::GetCurrentThread())); | 744 StackHandler::FromAddress(Top::handler(Top::GetCurrentThread())); |
742 | 745 |
743 // Determine if we have an external exception handler and get the | 746 // Determine if we have an external exception handler and get the |
744 // address of the external handler so we can compare the address to | 747 // address of the external handler so we can compare the address to |
745 // determine which one is closer to the top of the stack. | 748 // determine which one is closer to the top of the stack. |
746 bool has_external_handler = (thread_local_.try_catch_handler_ != NULL); | 749 bool has_external_handler = (thread_local_.try_catch_handler_ != NULL); |
747 v8::TryCatch* try_catch = thread_local_.try_catch_handler_; | 750 v8::TryCatch* try_catch = thread_local_.try_catch_handler_; |
748 | 751 |
749 // NOTE: The stack is assumed to grown towards lower addresses. If | 752 // NOTE: The stack is assumed to grown towards lower addresses. If |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
784 void Top::DoThrow(Object* exception, | 787 void Top::DoThrow(Object* exception, |
785 MessageLocation* location, | 788 MessageLocation* location, |
786 const char* message) { | 789 const char* message) { |
787 ASSERT(!has_pending_exception()); | 790 ASSERT(!has_pending_exception()); |
788 | 791 |
789 HandleScope scope; | 792 HandleScope scope; |
790 Handle<Object> exception_handle(exception); | 793 Handle<Object> exception_handle(exception); |
791 | 794 |
792 // Determine reporting and whether the exception is caught externally. | 795 // Determine reporting and whether the exception is caught externally. |
793 bool is_caught_externally = false; | 796 bool is_caught_externally = false; |
794 bool report_exception = (exception != Failure::OutOfMemoryException()) && | 797 bool is_out_of_memory = exception == Failure::OutOfMemoryException(); |
795 ShouldReportException(&is_caught_externally); | 798 bool is_uncaught_exception = IsUncaughtException(&is_caught_externally); |
799 bool report_exception = !is_out_of_memory && is_uncaught_exception; | |
800 | |
801 | |
802 // Notify debugger of exception. | |
803 Debugger::OnException(exception_handle, report_exception); | |
796 | 804 |
797 // Generate the message. | 805 // Generate the message. |
798 Handle<Object> message_obj; | 806 Handle<Object> message_obj; |
799 MessageLocation potential_computed_location; | 807 MessageLocation potential_computed_location; |
800 bool try_catch_needs_message = | 808 bool try_catch_needs_message = |
801 is_caught_externally && | 809 is_caught_externally && |
802 thread_local_.try_catch_handler_->capture_message_; | 810 thread_local_.try_catch_handler_->capture_message_; |
803 if (report_exception || try_catch_needs_message) { | 811 if (report_exception || try_catch_needs_message) { |
804 if (location == NULL) { | 812 if (location == NULL) { |
805 // If no location was specified we use a computed one instead | 813 // If no location was specified we use a computed one instead |
806 ComputeLocation(&potential_computed_location); | 814 ComputeLocation(&potential_computed_location); |
807 location = &potential_computed_location; | 815 location = &potential_computed_location; |
808 } | 816 } |
809 Handle<String> stack_trace; | 817 Handle<String> stack_trace; |
810 if (FLAG_trace_exception) stack_trace = StackTrace(); | 818 if (FLAG_trace_exception) stack_trace = StackTrace(); |
811 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", | 819 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", |
812 location, HandleVector<Object>(&exception_handle, 1), stack_trace); | 820 location, HandleVector<Object>(&exception_handle, 1), stack_trace); |
813 } | 821 } |
814 | 822 |
815 // If the exception is caught externally, we store it in the | 823 // Save the message for reporting if the the exception remains uncaught. |
816 // try/catch handler. The C code can find it later and process it if | 824 thread_local_.pending_message_ = message; |
817 // necessary. | 825 if (!message_obj.is_null()) { |
818 thread_local_.catcher_ = NULL; | 826 thread_local_.pending_message_obj_ = *message_obj; |
819 if (is_caught_externally) { | 827 if (location != NULL) { |
820 thread_local_.catcher_ = thread_local_.try_catch_handler_; | 828 thread_local_.pending_message_script_ = *location->script(); |
821 thread_local_.try_catch_handler_->exception_ = | 829 thread_local_.pending_message_start_pos_ = location->start_pos(); |
822 reinterpret_cast<void*>(*exception_handle); | 830 thread_local_.pending_message_end_pos_ = location->end_pos(); |
823 if (!message_obj.is_null()) { | |
824 thread_local_.try_catch_handler_->message_ = | |
825 reinterpret_cast<void*>(*message_obj); | |
826 } | 831 } |
827 } | 832 } |
828 | 833 |
829 // Notify debugger of exception. | 834 if (is_caught_externally) { |
830 Debugger::OnException(exception_handle, report_exception); | 835 thread_local_.catcher_ = thread_local_.try_catch_handler_; |
831 | |
832 if (report_exception) { | |
833 if (message != NULL) { | |
834 MessageHandler::ReportMessage(message); | |
835 } else if (!message_obj.is_null()) { | |
836 MessageHandler::ReportMessage(location, message_obj); | |
837 } | |
838 } | 836 } |
839 | 837 |
840 // NOTE: Notifying the debugger or reporting the exception may have caused | 838 // NOTE: Notifying the debugger may have caused new exceptions. |
Søren Thygesen Gjesse
2008/12/04 07:53:53
Generating the message without reporting it can al
olehougaard
2008/12/04 08:44:35
Updated the comment.
| |
841 // new exceptions. For now, we just ignore that and set the pending exception | 839 // For now, we just ignore that and set the pending exception |
842 // to the original one. | 840 // to the original one. |
843 set_pending_exception(*exception_handle); | 841 set_pending_exception(*exception_handle); |
844 } | 842 } |
845 | 843 |
846 | 844 |
845 void Top::ReportPendingMessages() { | |
846 ASSERT(has_pending_exception()); | |
847 setup_external_caught(); | |
848 // If the pending exception is OutOfMemoryException set out_of_memory in | |
849 // the global context. Note: We have to mark the global context here | |
850 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to | |
851 // set it. | |
852 HandleScope scope; | |
853 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { | |
854 context()->mark_out_of_memory(); | |
855 } else { | |
856 Handle<Object> exception(pending_exception()); | |
857 if (thread_local_.external_caught_exception_) { | |
858 thread_local_.try_catch_handler_->exception_ | |
859 = thread_local_.pending_exception_; | |
Mads Ager (chromium)
2008/12/03 15:44:48
We normally have the '=' on the previous line.
olehougaard
2008/12/04 08:44:35
Fixed.
| |
860 if (!thread_local_.pending_message_obj_->IsTheHole()) { | |
861 try_catch_handler()->message_ = thread_local_.pending_message_obj_; | |
862 } | |
863 } else if (thread_local_.pending_message_ != NULL) { | |
864 MessageHandler::ReportMessage(thread_local_.pending_message_); | |
865 } else if (!thread_local_.pending_message_obj_->IsTheHole()) { | |
866 Handle<Object> message_obj(thread_local_.pending_message_obj_); | |
867 if (thread_local_.pending_message_script_ != NULL) { | |
868 Handle<Script> script(thread_local_.pending_message_script_); | |
869 int start_pos = thread_local_.pending_message_start_pos_; | |
870 int end_pos = thread_local_.pending_message_end_pos_; | |
871 MessageLocation location(script, start_pos, end_pos); | |
872 MessageHandler::ReportMessage(&location, message_obj); | |
873 } else { | |
874 MessageHandler::ReportMessage(NULL, message_obj); | |
875 } | |
876 } | |
877 set_pending_exception(*exception); | |
878 } | |
879 clear_pending_message(); | |
880 } | |
881 | |
882 | |
847 void Top::TraceException(bool flag) { | 883 void Top::TraceException(bool flag) { |
848 FLAG_trace_exception = flag; | 884 FLAG_trace_exception = flag; |
849 } | 885 } |
850 | 886 |
851 | 887 |
852 bool Top::optional_reschedule_exception(bool is_bottom_call) { | 888 bool Top::optional_reschedule_exception(bool is_bottom_call) { |
853 if (!is_out_of_memory() && | 889 if (!is_out_of_memory() && |
854 (thread_local_.external_caught_exception_ || is_bottom_call)) { | 890 (thread_local_.external_caught_exception_ || is_bottom_call)) { |
855 thread_local_.external_caught_exception_ = false; | 891 thread_local_.external_caught_exception_ = false; |
856 clear_pending_exception(); | 892 clear_pending_exception(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
919 Top::break_access_->Lock(); | 955 Top::break_access_->Lock(); |
920 } | 956 } |
921 | 957 |
922 | 958 |
923 ExecutionAccess::~ExecutionAccess() { | 959 ExecutionAccess::~ExecutionAccess() { |
924 Top::break_access_->Unlock(); | 960 Top::break_access_->Unlock(); |
925 } | 961 } |
926 | 962 |
927 | 963 |
928 } } // namespace v8::internal | 964 } } // namespace v8::internal |
OLD | NEW |