Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index 288f6bdac49ace5409b1b909d7f239f794a46070..9b9132acf2b699473fe60eeee61e45571c5ed7ae 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -29,10 +29,12 @@ |
#include "v8.h" |
+#include "allocation-inl.h" |
#include "ast.h" |
#include "bootstrapper.h" |
#include "codegen.h" |
#include "compilation-cache.h" |
+#include "cpu-profiler.h" |
#include "debug.h" |
#include "deoptimizer.h" |
#include "heap-profiler.h" |
@@ -45,6 +47,7 @@ |
#include "platform.h" |
#include "regexp-stack.h" |
#include "runtime-profiler.h" |
+#include "sampler.h" |
#include "scopeinfo.h" |
#include "serialize.h" |
#include "simulator.h" |
@@ -107,6 +110,7 @@ void ThreadLocalTop::InitializeInternal() { |
// is complete. |
pending_exception_ = NULL; |
has_pending_message_ = false; |
+ rethrowing_message_ = false; |
pending_message_obj_ = NULL; |
pending_message_script_ = NULL; |
scheduled_exception_ = NULL; |
@@ -116,7 +120,7 @@ void ThreadLocalTop::InitializeInternal() { |
void ThreadLocalTop::Initialize() { |
InitializeInternal(); |
#ifdef USE_SIMULATOR |
-#ifdef V8_TARGET_ARCH_A64 |
+#if V8_TARGET_ARCH_A64 |
simulator_ = Simulator::current(isolate_); |
#elif V8_TARGET_ARCH_ARM |
simulator_ = Simulator::current(isolate_); |
@@ -488,7 +492,8 @@ void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { |
block != NULL; |
block = TRY_CATCH_FROM_ADDRESS(block->next_)) { |
v->VisitPointer(BitCast<Object**>(&(block->exception_))); |
- v->VisitPointer(BitCast<Object**>(&(block->message_))); |
+ v->VisitPointer(BitCast<Object**>(&(block->message_obj_))); |
+ v->VisitPointer(BitCast<Object**>(&(block->message_script_))); |
} |
// Iterate over pointers on native execution stack. |
@@ -506,6 +511,7 @@ void Isolate::Iterate(ObjectVisitor* v) { |
Iterate(v, current_t); |
} |
+ |
void Isolate::IterateDeferredHandles(ObjectVisitor* visitor) { |
for (DeferredHandles* deferred = deferred_handles_head_; |
deferred != NULL; |
@@ -1164,6 +1170,22 @@ void Isolate::ScheduleThrow(Object* exception) { |
} |
+void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) { |
+ ASSERT(handler == try_catch_handler()); |
+ ASSERT(handler->HasCaught()); |
+ ASSERT(handler->rethrow_); |
+ ASSERT(handler->capture_message_); |
+ Object* message = reinterpret_cast<Object*>(handler->message_obj_); |
+ Object* script = reinterpret_cast<Object*>(handler->message_script_); |
+ ASSERT(message->IsJSMessageObject() || message->IsTheHole()); |
+ ASSERT(script->IsScript() || script->IsTheHole()); |
+ thread_local_top()->pending_message_obj_ = message; |
+ thread_local_top()->pending_message_script_ = script; |
+ thread_local_top()->pending_message_start_pos_ = handler->message_start_pos_; |
+ thread_local_top()->pending_message_end_pos_ = handler->message_end_pos_; |
+} |
+ |
+ |
Failure* Isolate::PromoteScheduledException() { |
MaybeObject* thrown = scheduled_exception(); |
clear_scheduled_exception(); |
@@ -1282,9 +1304,12 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) { |
ShouldReportException(&can_be_caught_externally, catchable_by_javascript); |
bool report_exception = catchable_by_javascript && should_report_exception; |
bool try_catch_needs_message = |
- can_be_caught_externally && try_catch_handler()->capture_message_; |
+ can_be_caught_externally && try_catch_handler()->capture_message_ && |
+ !thread_local_top()->rethrowing_message_; |
bool bootstrapping = bootstrapper()->IsActive(); |
+ thread_local_top()->rethrowing_message_ = false; |
+ |
#ifdef ENABLE_DEBUGGER_SUPPORT |
// Notify debugger of exception. |
if (catchable_by_javascript) { |
@@ -1466,8 +1491,9 @@ void Isolate::ReportPendingMessages() { |
HandleScope scope(this); |
Handle<Object> message_obj(thread_local_top_.pending_message_obj_, |
this); |
- if (thread_local_top_.pending_message_script_ != NULL) { |
- Handle<Script> script(thread_local_top_.pending_message_script_); |
+ if (!thread_local_top_.pending_message_script_->IsTheHole()) { |
+ Handle<Script> script( |
+ Script::cast(thread_local_top_.pending_message_script_)); |
int start_pos = thread_local_top_.pending_message_start_pos_; |
int end_pos = thread_local_top_.pending_message_end_pos_; |
MessageLocation location(script, start_pos, end_pos); |
@@ -1489,8 +1515,9 @@ MessageLocation Isolate::GetMessageLocation() { |
thread_local_top_.pending_exception_ != heap()->termination_exception() && |
thread_local_top_.has_pending_message_ && |
!thread_local_top_.pending_message_obj_->IsTheHole() && |
- thread_local_top_.pending_message_script_ != NULL) { |
- Handle<Script> script(thread_local_top_.pending_message_script_); |
+ !thread_local_top_.pending_message_obj_->IsTheHole()) { |
+ Handle<Script> script( |
+ Script::cast(thread_local_top_.pending_message_script_)); |
int start_pos = thread_local_top_.pending_message_start_pos_; |
int end_pos = thread_local_top_.pending_message_end_pos_; |
return MessageLocation(script, start_pos, end_pos); |
@@ -1627,7 +1654,7 @@ char* Isolate::RestoreThread(char* from) { |
// This might be just paranoia, but it seems to be needed in case a |
// thread_local_top_ is restored on a separate OS thread. |
#ifdef USE_SIMULATOR |
-#ifdef V8_TARGET_ARCH_A64 |
+#if V8_TARGET_ARCH_A64 |
thread_local_top()->simulator_ = Simulator::current(this); |
#elif V8_TARGET_ARCH_ARM |
thread_local_top()->simulator_ = Simulator::current(this); |
@@ -1742,6 +1769,7 @@ Isolate::Isolate() |
descriptor_lookup_cache_(NULL), |
handle_scope_implementer_(NULL), |
unicode_cache_(NULL), |
+ runtime_zone_(this), |
in_use_list_(0), |
free_list_(0), |
preallocated_storage_preallocated_(false), |
@@ -1757,8 +1785,10 @@ Isolate::Isolate() |
date_cache_(NULL), |
code_stub_interface_descriptors_(NULL), |
context_exit_happened_(false), |
+ initialized_from_snapshot_(false), |
cpu_profiler_(NULL), |
heap_profiler_(NULL), |
+ function_entry_hook_(NULL), |
deferred_handles_head_(NULL), |
optimizing_compiler_thread_(this), |
marking_thread_(NULL), |
@@ -1778,9 +1808,9 @@ Isolate::Isolate() |
thread_manager_ = new ThreadManager(); |
thread_manager_->isolate_ = this; |
-#if defined(V8_TARGET_ARCH_A64) && !defined(__arm__) || \ |
- defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \ |
- defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__) |
+#if V8_TARGET_ARCH_ARM && !defined(__arm__) || \ |
+ V8_TARGET_ARCH_A64 && !defined(__arm__) || \ |
+ V8_TARGET_ARCH_MIPS && !defined(__mips__) |
simulator_initialized_ = false; |
simulator_i_cache_ = NULL; |
simulator_redirection_ = NULL; |
@@ -1852,6 +1882,10 @@ void Isolate::Deinit() { |
if (state_ == INITIALIZED) { |
TRACE_ISOLATE(deinit); |
+#ifdef ENABLE_DEBUGGER_SUPPORT |
+ debugger()->UnloadDebugger(); |
+#endif |
+ |
if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Stop(); |
if (FLAG_sweeper_threads > 0) { |
@@ -1939,6 +1973,18 @@ void Isolate::SetIsolateThreadLocals(Isolate* isolate, |
Isolate::~Isolate() { |
TRACE_ISOLATE(destructor); |
+ // Has to be called while counters_ are still alive |
+ runtime_zone_.DeleteKeptSegment(); |
+ |
+ // The entry stack must be empty when we get here, |
+ // except for the default isolate, where it can |
+ // still contain up to one entry stack item |
+ ASSERT(entry_stack_ == NULL || this == default_isolate_); |
+ ASSERT(entry_stack_ == NULL || entry_stack_->previous_item == NULL); |
+ |
+ delete entry_stack_; |
+ entry_stack_ = NULL; |
+ |
delete[] assembler_spare_buffer_; |
assembler_spare_buffer_ = NULL; |
@@ -2005,6 +2051,9 @@ Isolate::~Isolate() { |
delete global_handles_; |
global_handles_ = NULL; |
+ delete string_stream_debug_object_cache_; |
+ string_stream_debug_object_cache_ = NULL; |
+ |
delete external_reference_table_; |
external_reference_table_ = NULL; |
@@ -2042,15 +2091,24 @@ void Isolate::PropagatePendingExceptionToExternalTryCatch() { |
try_catch_handler()->has_terminated_ = true; |
try_catch_handler()->exception_ = heap()->null_value(); |
} else { |
+ v8::TryCatch* handler = try_catch_handler(); |
// At this point all non-object (failure) exceptions have |
// been dealt with so this shouldn't fail. |
ASSERT(!pending_exception()->IsFailure()); |
- try_catch_handler()->can_continue_ = true; |
- try_catch_handler()->has_terminated_ = false; |
- try_catch_handler()->exception_ = pending_exception(); |
- if (!thread_local_top_.pending_message_obj_->IsTheHole()) { |
- try_catch_handler()->message_ = thread_local_top_.pending_message_obj_; |
- } |
+ ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
+ thread_local_top_.pending_message_obj_->IsTheHole()); |
+ ASSERT(thread_local_top_.pending_message_script_->IsScript() || |
+ thread_local_top_.pending_message_script_->IsTheHole()); |
+ handler->can_continue_ = true; |
+ handler->has_terminated_ = false; |
+ handler->exception_ = pending_exception(); |
+ // Propagate to the external try-catch only if we got an actual message. |
+ if (thread_local_top_.pending_message_obj_->IsTheHole()) return; |
+ |
+ handler->message_obj_ = thread_local_top_.pending_message_obj_; |
+ handler->message_script_ = thread_local_top_.pending_message_script_; |
+ handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_; |
+ handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_; |
} |
} |
@@ -2082,6 +2140,14 @@ bool Isolate::Init(Deserializer* des) { |
ASSERT(Isolate::Current() == this); |
TRACE_ISOLATE(init); |
+ if (function_entry_hook() != NULL) { |
+ // When function entry hooking is in effect, we have to create the code |
+ // stubs from scratch to get entry hooks, rather than loading the previously |
+ // generated stubs from disk. |
+ // If this assert fires, the initialization path has regressed. |
+ ASSERT(des == NULL); |
+ } |
+ |
// The initialization process does not handle memory exhaustion. |
DisallowAllocationFailure disallow_allocation_failure; |
@@ -2129,8 +2195,7 @@ bool Isolate::Init(Deserializer* des) { |
// Initialize other runtime facilities |
#if defined(USE_SIMULATOR) |
-#if defined(V8_TARGET_ARCH_A64) || defined(V8_TARGET_ARCH_ARM) || \ |
- defined(V8_TARGET_ARCH_MIPS) |
+#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_A64 || V8_TARGET_ARCH_MIPS |
Simulator::Initialize(this); |
#endif |
#endif |
@@ -2274,6 +2339,9 @@ bool Isolate::Init(Deserializer* des) { |
sweeper_thread_[i]->Start(); |
} |
} |
+ |
+ initialized_from_snapshot_ = (des != NULL); |
+ |
return true; |
} |