| 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( | |
| 71 bit_cast<Object**, Script**>(&(thread->pending_message_script_))); | |
| 72 v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_))); | 69 v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_))); |
| 73 v->VisitPointer(&(thread->scheduled_exception_)); | 70 v->VisitPointer(&(thread->scheduled_exception_)); |
| 74 | 71 |
| 75 for (v8::TryCatch* block = thread->try_catch_handler_; | 72 for (v8::TryCatch* block = thread->try_catch_handler_; |
| 76 block != NULL; | 73 block != NULL; |
| 77 block = block->next_) { | 74 block = block->next_) { |
| 78 v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_))); | 75 v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_))); |
| 79 v->VisitPointer(bit_cast<Object**, void**>(&(block->message_))); | 76 v->VisitPointer(bit_cast<Object**, void**>(&(block->message_))); |
| 80 } | 77 } |
| 81 | 78 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 95 | 92 |
| 96 void Top::InitializeThreadLocal() { | 93 void Top::InitializeThreadLocal() { |
| 97 thread_local_.c_entry_fp_ = 0; | 94 thread_local_.c_entry_fp_ = 0; |
| 98 thread_local_.handler_ = 0; | 95 thread_local_.handler_ = 0; |
| 99 thread_local_.stack_is_cooked_ = false; | 96 thread_local_.stack_is_cooked_ = false; |
| 100 thread_local_.try_catch_handler_ = NULL; | 97 thread_local_.try_catch_handler_ = NULL; |
| 101 thread_local_.context_ = NULL; | 98 thread_local_.context_ = NULL; |
| 102 thread_local_.external_caught_exception_ = false; | 99 thread_local_.external_caught_exception_ = false; |
| 103 thread_local_.failed_access_check_callback_ = NULL; | 100 thread_local_.failed_access_check_callback_ = NULL; |
| 104 clear_pending_exception(); | 101 clear_pending_exception(); |
| 105 clear_pending_message(); | |
| 106 clear_scheduled_exception(); | 102 clear_scheduled_exception(); |
| 107 thread_local_.save_context_ = NULL; | 103 thread_local_.save_context_ = NULL; |
| 108 thread_local_.catcher_ = NULL; | 104 thread_local_.catcher_ = NULL; |
| 109 } | 105 } |
| 110 | 106 |
| 111 | 107 |
| 112 // Create a dummy thread that will wait forever on a semaphore. The only | 108 // Create a dummy thread that will wait forever on a semaphore. The only |
| 113 // purpose for this thread is to have some stack area to save essential data | 109 // purpose for this thread is to have some stack area to save essential data |
| 114 // into for use by a stacks only core dump (aka minidump). | 110 // into for use by a stacks only core dump (aka minidump). |
| 115 class PreallocatedMemoryThread: public Thread { | 111 class PreallocatedMemoryThread: public Thread { |
| (...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 void Top::DoThrow(Object* exception, | 784 void Top::DoThrow(Object* exception, |
| 789 MessageLocation* location, | 785 MessageLocation* location, |
| 790 const char* message) { | 786 const char* message) { |
| 791 ASSERT(!has_pending_exception()); | 787 ASSERT(!has_pending_exception()); |
| 792 | 788 |
| 793 HandleScope scope; | 789 HandleScope scope; |
| 794 Handle<Object> exception_handle(exception); | 790 Handle<Object> exception_handle(exception); |
| 795 | 791 |
| 796 // Determine reporting and whether the exception is caught externally. | 792 // Determine reporting and whether the exception is caught externally. |
| 797 bool is_caught_externally = false; | 793 bool is_caught_externally = false; |
| 798 bool is_out_of_memory = exception == Failure::OutOfMemoryException(); | 794 bool report_exception = (exception != Failure::OutOfMemoryException()) && |
| 799 bool should_return_exception = ShouldReportException(&is_caught_externally); | 795 ShouldReportException(&is_caught_externally); |
| 800 bool report_exception = !is_out_of_memory && should_return_exception; | |
| 801 | |
| 802 | |
| 803 // Notify debugger of exception. | |
| 804 Debugger::OnException(exception_handle, report_exception); | |
| 805 | 796 |
| 806 // Generate the message. | 797 // Generate the message. |
| 807 Handle<Object> message_obj; | 798 Handle<Object> message_obj; |
| 808 MessageLocation potential_computed_location; | 799 MessageLocation potential_computed_location; |
| 809 bool try_catch_needs_message = | 800 bool try_catch_needs_message = |
| 810 is_caught_externally && | 801 is_caught_externally && |
| 811 thread_local_.try_catch_handler_->capture_message_; | 802 thread_local_.try_catch_handler_->capture_message_; |
| 812 if (report_exception || try_catch_needs_message) { | 803 if (report_exception || try_catch_needs_message) { |
| 813 if (location == NULL) { | 804 if (location == NULL) { |
| 814 // If no location was specified we use a computed one instead | 805 // If no location was specified we use a computed one instead |
| 815 ComputeLocation(&potential_computed_location); | 806 ComputeLocation(&potential_computed_location); |
| 816 location = &potential_computed_location; | 807 location = &potential_computed_location; |
| 817 } | 808 } |
| 818 Handle<String> stack_trace; | 809 Handle<String> stack_trace; |
| 819 if (FLAG_trace_exception) stack_trace = StackTrace(); | 810 if (FLAG_trace_exception) stack_trace = StackTrace(); |
| 820 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", | 811 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", |
| 821 location, HandleVector<Object>(&exception_handle, 1), stack_trace); | 812 location, HandleVector<Object>(&exception_handle, 1), stack_trace); |
| 822 } | 813 } |
| 823 | 814 |
| 824 // Save the message for reporting if the the exception remains uncaught. | 815 // If the exception is caught externally, we store it in the |
| 825 thread_local_.pending_message_ = message; | 816 // try/catch handler. The C code can find it later and process it if |
| 826 if (!message_obj.is_null()) { | 817 // necessary. |
| 827 thread_local_.pending_message_obj_ = *message_obj; | 818 thread_local_.catcher_ = NULL; |
| 828 if (location != NULL) { | 819 if (is_caught_externally) { |
| 829 thread_local_.pending_message_script_ = *location->script(); | 820 thread_local_.catcher_ = thread_local_.try_catch_handler_; |
| 830 thread_local_.pending_message_start_pos_ = location->start_pos(); | 821 thread_local_.try_catch_handler_->exception_ = |
| 831 thread_local_.pending_message_end_pos_ = location->end_pos(); | 822 reinterpret_cast<void*>(*exception_handle); |
| 823 if (!message_obj.is_null()) { |
| 824 thread_local_.try_catch_handler_->message_ = |
| 825 reinterpret_cast<void*>(*message_obj); |
| 832 } | 826 } |
| 833 } | 827 } |
| 834 | 828 |
| 835 if (is_caught_externally) { | 829 // Notify debugger of exception. |
| 836 thread_local_.catcher_ = thread_local_.try_catch_handler_; | 830 Debugger::OnException(exception_handle, report_exception); |
| 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 } |
| 837 } | 838 } |
| 838 | 839 |
| 839 // NOTE: Notifying the debugger or generating the message | 840 // NOTE: Notifying the debugger or reporting the exception may have caused |
| 840 // may have caused new exceptions. For now, we just ignore | 841 // new exceptions. For now, we just ignore that and set the pending exception |
| 841 // that and set the pending exception to the original one. | 842 // to the original one. |
| 842 set_pending_exception(*exception_handle); | 843 set_pending_exception(*exception_handle); |
| 843 } | 844 } |
| 844 | 845 |
| 845 | 846 |
| 846 void Top::ReportPendingMessages() { | |
| 847 ASSERT(has_pending_exception()); | |
| 848 setup_external_caught(); | |
| 849 // If the pending exception is OutOfMemoryException set out_of_memory in | |
| 850 // the global context. Note: We have to mark the global context here | |
| 851 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to | |
| 852 // set it. | |
| 853 HandleScope scope; | |
| 854 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { | |
| 855 context()->mark_out_of_memory(); | |
| 856 } else { | |
| 857 Handle<Object> exception(pending_exception()); | |
| 858 if (thread_local_.external_caught_exception_) { | |
| 859 thread_local_.try_catch_handler_->exception_ = | |
| 860 thread_local_.pending_exception_; | |
| 861 if (!thread_local_.pending_message_obj_->IsTheHole()) { | |
| 862 try_catch_handler()->message_ = thread_local_.pending_message_obj_; | |
| 863 } | |
| 864 } else if (thread_local_.pending_message_ != NULL) { | |
| 865 MessageHandler::ReportMessage(thread_local_.pending_message_); | |
| 866 } else if (!thread_local_.pending_message_obj_->IsTheHole()) { | |
| 867 Handle<Object> message_obj(thread_local_.pending_message_obj_); | |
| 868 if (thread_local_.pending_message_script_ != NULL) { | |
| 869 Handle<Script> script(thread_local_.pending_message_script_); | |
| 870 int start_pos = thread_local_.pending_message_start_pos_; | |
| 871 int end_pos = thread_local_.pending_message_end_pos_; | |
| 872 MessageLocation location(script, start_pos, end_pos); | |
| 873 MessageHandler::ReportMessage(&location, message_obj); | |
| 874 } else { | |
| 875 MessageHandler::ReportMessage(NULL, message_obj); | |
| 876 } | |
| 877 } | |
| 878 set_pending_exception(*exception); | |
| 879 } | |
| 880 clear_pending_message(); | |
| 881 } | |
| 882 | |
| 883 | |
| 884 void Top::TraceException(bool flag) { | 847 void Top::TraceException(bool flag) { |
| 885 FLAG_trace_exception = flag; | 848 FLAG_trace_exception = flag; |
| 886 } | 849 } |
| 887 | 850 |
| 888 | 851 |
| 889 bool Top::optional_reschedule_exception(bool is_bottom_call) { | 852 bool Top::optional_reschedule_exception(bool is_bottom_call) { |
| 890 if (!is_out_of_memory() && | 853 if (!is_out_of_memory() && |
| 891 (thread_local_.external_caught_exception_ || is_bottom_call)) { | 854 (thread_local_.external_caught_exception_ || is_bottom_call)) { |
| 892 thread_local_.external_caught_exception_ = false; | 855 thread_local_.external_caught_exception_ = false; |
| 893 clear_pending_exception(); | 856 clear_pending_exception(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 Top::break_access_->Lock(); | 919 Top::break_access_->Lock(); |
| 957 } | 920 } |
| 958 | 921 |
| 959 | 922 |
| 960 ExecutionAccess::~ExecutionAccess() { | 923 ExecutionAccess::~ExecutionAccess() { |
| 961 Top::break_access_->Unlock(); | 924 Top::break_access_->Unlock(); |
| 962 } | 925 } |
| 963 | 926 |
| 964 | 927 |
| 965 } } // namespace v8::internal | 928 } } // namespace v8::internal |
| OLD | NEW |