diff options
Diffstat (limited to 'deps/v8/src/isolate.cc')
-rw-r--r-- | deps/v8/src/isolate.cc | 234 |
1 files changed, 147 insertions, 87 deletions
diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc index 8116f14d30..c9f01118c5 100644 --- a/deps/v8/src/isolate.cc +++ b/deps/v8/src/isolate.cc @@ -22,6 +22,7 @@ #include "src/crankshaft/hydrogen.h" #include "src/debug/debug.h" #include "src/deoptimizer.h" +#include "src/external-reference-table.h" #include "src/frames-inl.h" #include "src/ic/stub-cache.h" #include "src/interpreter/interpreter.h" @@ -34,7 +35,7 @@ #include "src/regexp/regexp-stack.h" #include "src/runtime-profiler.h" #include "src/simulator.h" -#include "src/snapshot/serialize.h" +#include "src/snapshot/deserializer.h" #include "src/v8.h" #include "src/version.h" #include "src/vm-state-inl.h" @@ -338,8 +339,23 @@ static bool IsVisibleInStackTrace(JSFunction* fun, return true; } +static Handle<FixedArray> MaybeGrow(Isolate* isolate, + Handle<FixedArray> elements, + int cur_position, int new_size) { + if (new_size > elements->length()) { + int new_capacity = JSObject::NewElementsCapacity(elements->length()); + Handle<FixedArray> new_elements = + isolate->factory()->NewFixedArrayWithHoles(new_capacity); + for (int i = 0; i < cur_position; i++) { + new_elements->set(i, elements->get(i)); + } + elements = new_elements; + } + DCHECK(new_size <= elements->length()); + return elements; +} -Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object, +Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, Handle<Object> caller) { // Get stack trace limit. Handle<JSObject> error = error_function(); @@ -364,51 +380,72 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object, int frames_seen = 0; int sloppy_frames = 0; bool encountered_strict_function = false; - for (JavaScriptFrameIterator iter(this); - !iter.done() && frames_seen < limit; + for (StackFrameIterator iter(this); !iter.done() && frames_seen < limit; iter.Advance()) { - JavaScriptFrame* frame = iter.frame(); - // Set initial size to the maximum inlining level + 1 for the outermost - // function. - List<FrameSummary> frames(FLAG_max_inlining_levels + 1); - frame->Summarize(&frames); - for (int i = frames.length() - 1; i >= 0; i--) { - Handle<JSFunction> fun = frames[i].function(); - Handle<Object> recv = frames[i].receiver(); - // Filter out internal frames that we do not want to show. - if (!IsVisibleInStackTrace(*fun, *caller, *recv, &seen_caller)) continue; - // Filter out frames from other security contexts. - if (!this->context()->HasSameSecurityTokenAs(fun->context())) continue; - if (cursor + 4 > elements->length()) { - int new_capacity = JSObject::NewElementsCapacity(elements->length()); - Handle<FixedArray> new_elements = - factory()->NewFixedArrayWithHoles(new_capacity); - for (int i = 0; i < cursor; i++) { - new_elements->set(i, elements->get(i)); - } - elements = new_elements; - } - DCHECK(cursor + 4 <= elements->length()); - - Handle<AbstractCode> abstract_code = frames[i].abstract_code(); - - Handle<Smi> offset(Smi::FromInt(frames[i].code_offset()), this); - // The stack trace API should not expose receivers and function - // objects on frames deeper than the top-most one with a strict - // mode function. The number of sloppy frames is stored as - // first element in the result array. - if (!encountered_strict_function) { - if (is_strict(fun->shared()->language_mode())) { - encountered_strict_function = true; - } else { - sloppy_frames++; + StackFrame* frame = iter.frame(); + + switch (frame->type()) { + case StackFrame::JAVA_SCRIPT: + case StackFrame::OPTIMIZED: + case StackFrame::INTERPRETED: { + JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); + // Set initial size to the maximum inlining level + 1 for the outermost + // function. + List<FrameSummary> frames(FLAG_max_inlining_levels + 1); + js_frame->Summarize(&frames); + for (int i = frames.length() - 1; i >= 0; i--) { + Handle<JSFunction> fun = frames[i].function(); + Handle<Object> recv = frames[i].receiver(); + // Filter out internal frames that we do not want to show. + if (!IsVisibleInStackTrace(*fun, *caller, *recv, &seen_caller)) { + continue; + } + // Filter out frames from other security contexts. + if (!this->context()->HasSameSecurityTokenAs(fun->context())) { + continue; + } + elements = MaybeGrow(this, elements, cursor, cursor + 4); + + Handle<AbstractCode> abstract_code = frames[i].abstract_code(); + + Handle<Smi> offset(Smi::FromInt(frames[i].code_offset()), this); + // The stack trace API should not expose receivers and function + // objects on frames deeper than the top-most one with a strict mode + // function. The number of sloppy frames is stored as first element in + // the result array. + if (!encountered_strict_function) { + if (is_strict(fun->shared()->language_mode())) { + encountered_strict_function = true; + } else { + sloppy_frames++; + } + } + elements->set(cursor++, *recv); + elements->set(cursor++, *fun); + elements->set(cursor++, *abstract_code); + elements->set(cursor++, *offset); + frames_seen++; } - } - elements->set(cursor++, *recv); - elements->set(cursor++, *fun); - elements->set(cursor++, *abstract_code); - elements->set(cursor++, *offset); - frames_seen++; + } break; + + case StackFrame::WASM: { + WasmFrame* wasm_frame = WasmFrame::cast(frame); + Code* code = wasm_frame->unchecked_code(); + Handle<AbstractCode> abstract_code = + Handle<AbstractCode>(AbstractCode::cast(code)); + Handle<JSFunction> fun = factory()->NewFunction( + factory()->NewStringFromAsciiChecked("<WASM>")); + elements = MaybeGrow(this, elements, cursor, cursor + 4); + // TODO(jfb) Pass module object. + elements->set(cursor++, *factory()->undefined_value()); + elements->set(cursor++, *fun); + elements->set(cursor++, *abstract_code); + elements->set(cursor++, Internals::IntToSmi(0)); + frames_seen++; + } break; + + default: + break; } } elements->set(0, Smi::FromInt(sloppy_frames)); @@ -419,9 +456,8 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object, return result; } - -MaybeHandle<JSObject> Isolate::CaptureAndSetDetailedStackTrace( - Handle<JSObject> error_object) { +MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace( + Handle<JSReceiver> error_object) { if (capture_stack_trace_for_uncaught_exceptions_) { // Capture stack trace for a detailed exception message. Handle<Name> key = factory()->detailed_stack_trace_symbol(); @@ -429,21 +465,20 @@ MaybeHandle<JSObject> Isolate::CaptureAndSetDetailedStackTrace( stack_trace_for_uncaught_exceptions_frame_limit_, stack_trace_for_uncaught_exceptions_options_); RETURN_ON_EXCEPTION( - this, JSObject::SetProperty(error_object, key, stack_trace, STRICT), - JSObject); + this, JSReceiver::SetProperty(error_object, key, stack_trace, STRICT), + JSReceiver); } return error_object; } - -MaybeHandle<JSObject> Isolate::CaptureAndSetSimpleStackTrace( - Handle<JSObject> error_object, Handle<Object> caller) { +MaybeHandle<JSReceiver> Isolate::CaptureAndSetSimpleStackTrace( + Handle<JSReceiver> error_object, Handle<Object> caller) { // Capture stack trace for simple stack trace string formatting. Handle<Name> key = factory()->stack_trace_symbol(); Handle<Object> stack_trace = CaptureSimpleStackTrace(error_object, caller); RETURN_ON_EXCEPTION( - this, JSObject::SetProperty(error_object, key, stack_trace, STRICT), - JSObject); + this, JSReceiver::SetProperty(error_object, key, stack_trace, STRICT), + JSReceiver); return error_object; } @@ -868,7 +903,7 @@ Object* Isolate::StackOverflow() { #ifdef VERIFY_HEAP if (FLAG_verify_heap && FLAG_stress_compaction) { - heap()->CollectAllAvailableGarbage("trigger compaction"); + heap()->CollectAllGarbage(Heap::kNoGCFlags, "trigger compaction"); } #endif // VERIFY_HEAP @@ -1780,6 +1815,8 @@ Isolate::Isolate(bool enable_serializer) descriptor_lookup_cache_(NULL), handle_scope_implementer_(NULL), unicode_cache_(NULL), + runtime_zone_(&allocator_), + interface_descriptor_zone_(&allocator_), inner_pointer_to_code_cache_(NULL), global_handles_(NULL), eternal_handles_(NULL), @@ -1794,6 +1831,7 @@ Isolate::Isolate(bool enable_serializer) serializer_enabled_(enable_serializer), has_fatal_error_(false), initialized_from_snapshot_(false), + is_tail_call_elimination_enabled_(true), cpu_profiler_(NULL), heap_profiler_(NULL), function_entry_hook_(NULL), @@ -2165,7 +2203,7 @@ bool Isolate::Init(Deserializer* des) { // Initialize other runtime facilities #if defined(USE_SIMULATOR) #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \ - V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC + V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 Simulator::Initialize(this); #endif #endif @@ -2196,7 +2234,7 @@ bool Isolate::Init(Deserializer* des) { } if (create_heap_objects) { - // Terminate the cache array with the sentinel so we can iterate. + // Terminate the partial snapshot cache so we can iterate. partial_snapshot_cache_.Add(heap_.undefined_value()); } @@ -2268,9 +2306,8 @@ bool Isolate::Init(Deserializer* des) { // the snapshot. HandleScope scope(this); Deoptimizer::EnsureCodeForDeoptimizationEntry( - this, - Deoptimizer::LAZY, - kDeoptTableSerializeEntryCount - 1); + this, Deoptimizer::LAZY, + ExternalReferenceTable::kDeoptTableSerializeEntryCount - 1); } if (!serializer_enabled()) { @@ -2431,12 +2468,11 @@ CodeTracer* Isolate::GetCodeTracer() { return code_tracer(); } - -Map* Isolate::get_initial_js_array_map(ElementsKind kind, Strength strength) { +Map* Isolate::get_initial_js_array_map(ElementsKind kind) { if (IsFastElementsKind(kind)) { DisallowHeapAllocation no_gc; - Object* const initial_js_array_map = context()->native_context()->get( - Context::ArrayMapIndex(kind, strength)); + Object* const initial_js_array_map = + context()->native_context()->get(Context::ArrayMapIndex(kind)); if (!initial_js_array_map->IsUndefined()) { return Map::cast(initial_js_array_map); } @@ -2511,25 +2547,6 @@ bool Isolate::IsFastArrayConstructorPrototypeChainIntact() { return cell_reports_intact; } -bool Isolate::IsArraySpeciesLookupChainIntact() { - if (!FLAG_harmony_species) return true; - // Note: It would be nice to have debug checks to make sure that the - // species protector is accurate, but this would be hard to do for most of - // what the protector stands for: - // - You'd need to traverse the heap to check that no Array instance has - // a constructor property or a modified __proto__ - // - To check that Array[Symbol.species] == Array, JS code has to execute, - // but JS cannot be invoked in callstack overflow situations - // All that could be checked reliably is that - // Array.prototype.constructor == Array. Given that limitation, no check is - // done here. In place, there are mjsunit tests harmony/array-species* which - // ensure that behavior is correct in various invalid protector cases. - - PropertyCell* species_cell = heap()->species_protector(); - return species_cell->value()->IsSmi() && - Smi::cast(species_cell->value())->value() == kArrayProtectorValid; -} - void Isolate::InvalidateArraySpeciesProtector() { if (!FLAG_harmony_species) return; DCHECK(factory()->species_protector()->value()->IsSmi()); @@ -2682,7 +2699,11 @@ void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) { void Isolate::FireCallCompletedCallback() { bool has_call_completed_callbacks = !call_completed_callbacks_.is_empty(); - bool run_microtasks = autorun_microtasks() && pending_microtask_count(); + bool run_microtasks = + pending_microtask_count() && + !handle_scope_implementer()->HasMicrotasksSuppressions() && + handle_scope_implementer()->microtasks_policy() == + v8::MicrotasksPolicy::kAuto; if (!has_call_completed_callbacks && !run_microtasks) return; if (!handle_scope_implementer()->CallDepthIsZero()) return; @@ -2737,7 +2758,12 @@ void Isolate::RunMicrotasks() { // Increase call depth to prevent recursive callbacks. v8::Isolate::SuppressMicrotaskExecutionScope suppress( reinterpret_cast<v8::Isolate*>(this)); + RunMicrotasksInternal(); + FireMicrotasksCompletedCallback(); +} + +void Isolate::RunMicrotasksInternal() { while (pending_microtask_count() > 0) { HandleScope scope(this); int num_tasks = pending_microtask_count(); @@ -2746,8 +2772,8 @@ void Isolate::RunMicrotasks() { set_pending_microtask_count(0); heap()->set_microtask_queue(heap()->empty_fixed_array()); - for (int i = 0; i < num_tasks; i++) { - HandleScope scope(this); + Isolate* isolate = this; + FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < num_tasks, i++, { Handle<Object> microtask(queue->get(i), this); if (microtask->IsJSFunction()) { Handle<JSFunction> microtask_function = @@ -2774,11 +2800,37 @@ void Isolate::RunMicrotasks() { void* data = v8::ToCData<void*>(callback_info->data()); callback(data); } + }); + } +} + + +void Isolate::AddMicrotasksCompletedCallback( + MicrotasksCompletedCallback callback) { + for (int i = 0; i < microtasks_completed_callbacks_.length(); i++) { + if (callback == microtasks_completed_callbacks_.at(i)) return; + } + microtasks_completed_callbacks_.Add(callback); +} + + +void Isolate::RemoveMicrotasksCompletedCallback( + MicrotasksCompletedCallback callback) { + for (int i = 0; i < microtasks_completed_callbacks_.length(); i++) { + if (callback == microtasks_completed_callbacks_.at(i)) { + microtasks_completed_callbacks_.Remove(i); } } } +void Isolate::FireMicrotasksCompletedCallback() { + for (int i = 0; i < microtasks_completed_callbacks_.length(); i++) { + microtasks_completed_callbacks_.at(i)(reinterpret_cast<v8::Isolate*>(this)); + } +} + + void Isolate::SetUseCounterCallback(v8::Isolate::UseCounterCallback callback) { DCHECK(!use_counter_callback_); use_counter_callback_ = callback; @@ -2817,6 +2869,14 @@ std::string Isolate::GetTurboCfgFileName() { } } +void Isolate::SetTailCallEliminationEnabled(bool enabled) { + if (is_tail_call_elimination_enabled_ == enabled) return; + is_tail_call_elimination_enabled_ = enabled; + // TODO(ishell): Introduce DependencyGroup::kTailCallChangedGroup to + // deoptimize only those functions that are affected by the change of this + // flag. + internal::Deoptimizer::DeoptimizeAll(this); +} // Heap::detached_contexts tracks detached contexts as pairs // (number of GC since the context was detached, the context). |