diff options
Diffstat (limited to 'src/3rdparty/v8/src/isolate.cc')
-rw-r--r-- | src/3rdparty/v8/src/isolate.cc | 180 |
1 files changed, 141 insertions, 39 deletions
diff --git a/src/3rdparty/v8/src/isolate.cc b/src/3rdparty/v8/src/isolate.cc index 63029ab..3a6099b 100644 --- a/src/3rdparty/v8/src/isolate.cc +++ b/src/3rdparty/v8/src/isolate.cc @@ -257,7 +257,7 @@ void Isolate::PreallocatedStorageInit(size_t size) { void* Isolate::PreallocatedStorageNew(size_t size) { if (!preallocated_storage_preallocated_) { - return FreeStoreAllocationPolicy::New(size); + return FreeStoreAllocationPolicy().New(size); } ASSERT(free_list_.next_ != &free_list_); ASSERT(free_list_.previous_ != &free_list_); @@ -478,6 +478,14 @@ void Isolate::Iterate(ObjectVisitor* v) { Iterate(v, current_t); } +void Isolate::IterateDeferredHandles(ObjectVisitor* visitor) { + for (DeferredHandles* deferred = deferred_handles_head_; + deferred != NULL; + deferred = deferred->next_) { + deferred->Iterate(visitor); + } +} + void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) { // The ARM simulator has a separate JS stack. We therefore register @@ -528,6 +536,24 @@ Handle<String> Isolate::StackTraceString() { } +void Isolate::PushStackTraceAndDie(unsigned int magic, + Object* object, + Map* map, + unsigned int magic2) { + const int kMaxStackTraceSize = 8192; + Handle<String> trace = StackTraceString(); + char buffer[kMaxStackTraceSize]; + int length = Min(kMaxStackTraceSize - 1, trace->length()); + String::WriteToFlat(*trace, buffer, 0, length); + buffer[length] = '\0'; + OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n", + magic, magic2, + static_cast<void*>(object), static_cast<void*>(map), + buffer); + OS::Abort(); +} + + void Isolate::CaptureAndSetCurrentStackTraceFor(Handle<JSObject> error_object) { if (capture_stack_trace_for_uncaught_exceptions_) { // Capture stack trace for a detailed exception message. @@ -549,8 +575,6 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace( Handle<String> column_key = factory()->LookupAsciiSymbol("column"); Handle<String> line_key = factory()->LookupAsciiSymbol("lineNumber"); Handle<String> script_key = factory()->LookupAsciiSymbol("scriptName"); - Handle<String> name_or_source_url_key = - factory()->LookupAsciiSymbol("nameOrSourceURL"); Handle<String> script_name_or_source_url_key = factory()->LookupAsciiSymbol("scriptNameOrSourceURL"); Handle<String> function_key = factory()->LookupAsciiSymbol("functionName"); @@ -610,18 +634,7 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace( } if (options & StackTrace::kScriptNameOrSourceURL) { - Handle<Object> script_name(script->name(), this); - Handle<JSValue> script_wrapper = GetScriptWrapper(script); - Handle<Object> property = GetProperty(script_wrapper, - name_or_source_url_key); - ASSERT(property->IsJSFunction()); - Handle<JSFunction> method = Handle<JSFunction>::cast(property); - bool caught_exception; - Handle<Object> result = Execution::TryCall(method, script_wrapper, 0, - NULL, &caught_exception); - if (caught_exception) { - result = factory()->undefined_value(); - } + Handle<Object> result = GetScriptNameOrSourceURL(script); CHECK_NOT_EMPTY_HANDLE(this, JSObject::SetLocalPropertyIgnoreAttributes( stack_frame, script_name_or_source_url_key, @@ -744,7 +757,7 @@ void Isolate::SetFailedAccessCheckCallback( thread_local_top()->failed_access_check_callback_ = callback; } - + void Isolate::SetUserObjectComparisonCallback( v8::UserObjectComparisonCallback callback) { thread_local_top()->user_object_comparison_callback_ = callback; @@ -788,16 +801,17 @@ static MayAccessDecision MayAccessPreCheck(Isolate* isolate, if (isolate->bootstrapper()->IsActive()) return YES; if (receiver->IsJSGlobalProxy()) { - Object* receiver_context = JSGlobalProxy::cast(receiver)->context(); + Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context(); if (!receiver_context->IsContext()) return NO; - // Get the global context of current top context. - // avoid using Isolate::global_context() because it uses Handle. - Context* global_context = isolate->context()->global()->global_context(); - if (receiver_context == global_context) return YES; + // Get the native context of current top context. + // avoid using Isolate::native_context() because it uses Handle. + Context* native_context = + isolate->context()->global_object()->native_context(); + if (receiver_context == native_context) return YES; if (Context::cast(receiver_context)->security_token() == - global_context->security_token()) + native_context->security_token()) return YES; } @@ -928,7 +942,7 @@ Failure* Isolate::Throw(Object* exception, MessageLocation* location) { } -Failure* Isolate::ReThrow(MaybeObject* exception, MessageLocation* location) { +Failure* Isolate::ReThrow(MaybeObject* exception) { bool can_be_caught_externally = false; bool catchable_by_javascript = is_catchable_by_javascript(exception); ShouldReportException(&can_be_caught_externally, catchable_by_javascript); @@ -1118,6 +1132,14 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) { stack_trace_for_uncaught_exceptions_options_); } } + // Stringify custom error objects for the message object. + if (exception_handle->IsJSObject() && !IsErrorObject(exception_handle)) { + bool failed = false; + exception_handle = Execution::ToString(exception_handle, &failed); + if (failed) { + exception_handle = factory()->LookupAsciiSymbol("exception"); + } + } Handle<Object> message_obj = MessageHandler::MakeMessageObject( "uncaught_exception", location, @@ -1138,8 +1160,18 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) { // to the console for easier debugging. int line_number = GetScriptLineNumberSafe(location->script(), location->start_pos()); - OS::PrintError("Extension or internal compilation error at line %d.\n", - line_number); + if (exception->IsString()) { + OS::PrintError( + "Extension or internal compilation error: %s in %s at line %d.\n", + *String::cast(exception)->ToCString(), + *String::cast(location->script()->name())->ToCString(), + line_number + 1); + } else { + OS::PrintError( + "Extension or internal compilation error in %s at line %d.\n", + *String::cast(location->script()->name())->ToCString(), + line_number + 1); + } } } @@ -1202,7 +1234,7 @@ void Isolate::ReportPendingMessages() { PropagatePendingExceptionToExternalTryCatch(); // If the pending exception is OutOfMemoryException set out_of_memory in - // the global context. Note: We have to mark the global context here + // the native context. Note: We have to mark the native context here // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to // set it. HandleScope scope; @@ -1312,20 +1344,26 @@ bool Isolate::is_out_of_memory() { } +Handle<Context> Isolate::native_context() { + GlobalObject* global = thread_local_top()->context_->global_object(); + return Handle<Context>(global->native_context()); +} + + Handle<Context> Isolate::global_context() { - GlobalObject* global = thread_local_top()->context_->global(); + GlobalObject* global = thread_local_top()->context_->global_object(); return Handle<Context>(global->global_context()); } -Handle<Context> Isolate::GetCallingGlobalContext() { +Handle<Context> Isolate::GetCallingNativeContext() { JavaScriptFrameIterator it; #ifdef ENABLE_DEBUGGER_SUPPORT if (debug_->InDebugger()) { while (!it.done()) { JavaScriptFrame* frame = it.frame(); Context* context = Context::cast(frame->context()); - if (context->global_context() == *debug_->debug_context()) { + if (context->native_context() == *debug_->debug_context()) { it.Advance(); } else { break; @@ -1336,7 +1374,7 @@ Handle<Context> Isolate::GetCallingGlobalContext() { if (it.done()) return Handle<Context>::null(); JavaScriptFrame* frame = it.frame(); Context* context = Context::cast(frame->context()); - return Handle<Context>(context->global_context()); + return Handle<Context>(context->native_context()); } @@ -1467,6 +1505,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), @@ -1480,14 +1519,15 @@ Isolate::Isolate() string_tracker_(NULL), regexp_stack_(NULL), date_cache_(NULL), - context_exit_happened_(false) { + context_exit_happened_(false), + deferred_handles_head_(NULL), + optimizing_compiler_thread_(this) { TRACE_ISOLATE(constructor); memset(isolate_addresses_, 0, sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1)); heap_.isolate_ = this; - zone_.isolate_ = this; stack_guard_.isolate_ = this; // ThreadManager is initialized early to support locking an isolate @@ -1544,6 +1584,11 @@ void Isolate::TearDown() { thread_data_table_->RemoveAllThreads(this); } + if (serialize_partial_snapshot_cache_ != NULL) { + delete[] serialize_partial_snapshot_cache_; + serialize_partial_snapshot_cache_ = NULL; + } + if (!IsDefaultIsolate()) { delete this; } @@ -1557,6 +1602,8 @@ void Isolate::Deinit() { if (state_ == INITIALIZED) { TRACE_ISOLATE(deinit); + if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Stop(); + if (FLAG_hydrogen_stats) HStatistics::Instance()->Print(); // We must stop the logger before we tear down other components. @@ -1592,6 +1639,26 @@ void Isolate::Deinit() { } +void Isolate::PushToPartialSnapshotCache(Object* obj) { + int length = serialize_partial_snapshot_cache_length(); + int capacity = serialize_partial_snapshot_cache_capacity(); + + if (length >= capacity) { + int new_capacity = static_cast<int>((capacity + 10) * 1.2); + Object** new_array = new Object*[new_capacity]; + for (int i = 0; i < length; i++) { + new_array[i] = serialize_partial_snapshot_cache()[i]; + } + if (capacity != 0) delete[] serialize_partial_snapshot_cache(); + set_serialize_partial_snapshot_cache(new_array); + set_serialize_partial_snapshot_cache_capacity(new_capacity); + } + + serialize_partial_snapshot_cache()[length] = obj; + set_serialize_partial_snapshot_cache_length(length + 1); +} + + void Isolate::SetIsolateThreadLocals(Isolate* isolate, PerIsolateThreadData* data) { Thread::SetThreadLocal(isolate_key_, isolate); @@ -1603,7 +1670,7 @@ Isolate::~Isolate() { TRACE_ISOLATE(destructor); // Has to be called while counters_ are still alive. - zone_.DeleteKeptSegment(); + runtime_zone_.DeleteKeptSegment(); delete[] assembler_spare_buffer_; assembler_spare_buffer_ = NULL; @@ -1740,10 +1807,8 @@ bool Isolate::Init(Deserializer* des) { ASSERT(Isolate::Current() == this); TRACE_ISOLATE(init); -#ifdef DEBUG // The initialization process does not handle memory exhaustion. DisallowAllocationFailure disallow_allocation_failure; -#endif InitializeLoggingAndCounters(); @@ -1775,7 +1840,7 @@ bool Isolate::Init(Deserializer* des) { global_handles_ = new GlobalHandles(this); bootstrapper_ = new Bootstrapper(); handle_scope_implementer_ = new HandleScopeImplementer(this); - stub_cache_ = new StubCache(this); + stub_cache_ = new StubCache(this, runtime_zone()); regexp_stack_ = new RegExpStack(); regexp_stack_->isolate_ = this; date_cache_ = new DateCache(); @@ -1809,6 +1874,11 @@ bool Isolate::Init(Deserializer* des) { return false; } + if (create_heap_objects) { + // Terminate the cache array with the sentinel so we can iterate. + PushToPartialSnapshotCache(heap_.undefined_value()); + } + InitializeThreadLocal(); bootstrapper_->Initialize(create_heap_objects); @@ -1835,7 +1905,7 @@ bool Isolate::Init(Deserializer* des) { #endif // If we are deserializing, read the state into the now-empty heap. - if (des != NULL) { + if (!create_heap_objects) { des->Deserialize(); } stub_cache_->Initialize(); @@ -1850,7 +1920,7 @@ bool Isolate::Init(Deserializer* des) { heap_.SetStackLimits(); // Quiet the heap NaN if needed on target platform. - if (des != NULL) Assembler::QuietNaN(heap_.nan_value()); + if (!create_heap_objects) Assembler::QuietNaN(heap_.nan_value()); deoptimizer_data_ = new DeoptimizerData; runtime_profiler_ = new RuntimeProfiler(this); @@ -1858,7 +1928,8 @@ bool Isolate::Init(Deserializer* des) { // If we are deserializing, log non-function code objects and compiled // functions found in the snapshot. - if (des != NULL && (FLAG_log_code || FLAG_ll_prof)) { + if (create_heap_objects && + (FLAG_log_code || FLAG_ll_prof || logger_->is_logging_code_events())) { HandleScope scope; LOG(this, LogCodeObjects()); LOG(this, LogCompiledFunctions()); @@ -1873,6 +1944,7 @@ bool Isolate::Init(Deserializer* des) { state_ = INITIALIZED; time_millis_at_init_ = OS::TimeCurrentMillis(); + if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Start(); return true; } @@ -1956,6 +2028,36 @@ void Isolate::Exit() { } +void Isolate::LinkDeferredHandles(DeferredHandles* deferred) { + deferred->next_ = deferred_handles_head_; + if (deferred_handles_head_ != NULL) { + deferred_handles_head_->previous_ = deferred; + } + deferred_handles_head_ = deferred; +} + + +void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) { +#ifdef DEBUG + // In debug mode assert that the linked list is well-formed. + DeferredHandles* deferred_iterator = deferred; + while (deferred_iterator->previous_ != NULL) { + deferred_iterator = deferred_iterator->previous_; + } + ASSERT(deferred_handles_head_ == deferred_iterator); +#endif + if (deferred_handles_head_ == deferred) { + deferred_handles_head_ = deferred_handles_head_->next_; + } + if (deferred->next_ != NULL) { + deferred->next_->previous_ = deferred->previous_; + } + if (deferred->previous_ != NULL) { + deferred->previous_->next_ = deferred->next_; + } +} + + #ifdef DEBUG #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); |