diff options
Diffstat (limited to 'deps/v8/src/execution/isolate.cc')
-rw-r--r-- | deps/v8/src/execution/isolate.cc | 231 |
1 files changed, 143 insertions, 88 deletions
diff --git a/deps/v8/src/execution/isolate.cc b/deps/v8/src/execution/isolate.cc index 8a8db12ca3..2b3551cdfb 100644 --- a/deps/v8/src/execution/isolate.cc +++ b/deps/v8/src/execution/isolate.cc @@ -736,15 +736,19 @@ class FrameArrayBuilder { } // Creates a StackTraceFrame object for each frame in the FrameArray. - Handle<FixedArray> GetElementsAsStackTraceFrameArray() { + Handle<FixedArray> GetElementsAsStackTraceFrameArray( + bool enable_frame_caching) { elements_->ShrinkToFit(isolate_); const int frame_count = elements_->FrameCount(); Handle<FixedArray> stack_trace = isolate_->factory()->NewFixedArray(frame_count); for (int i = 0; i < frame_count; ++i) { - // Caching stack frames only happens for non-Wasm frames. - if (!elements_->IsAnyWasmFrame(i)) { + // Caching stack frames only happens for user JS frames. + const bool cache_frame = + enable_frame_caching && !elements_->IsAnyWasmFrame(i) && + elements_->Function(i).shared().IsUserJavaScript(); + if (cache_frame) { MaybeHandle<StackTraceFrame> maybe_frame = StackFrameCacheHelper::LookupCachedFrame( isolate_, handle(elements_->Code(i), isolate_), @@ -760,7 +764,7 @@ class FrameArrayBuilder { isolate_->factory()->NewStackTraceFrame(elements_, i); stack_trace->set(i, *frame); - if (!elements_->IsAnyWasmFrame(i)) { + if (cache_frame) { StackFrameCacheHelper::CacheFrameAndUpdateCache( isolate_, handle(elements_->Code(i), isolate_), Smi::ToInt(elements_->Offset(i)), frame); @@ -938,6 +942,14 @@ void CaptureAsyncStackTrace(Isolate* isolate, Handle<JSPromise> promise, PromiseCapability::cast(context->get(index)), isolate); if (!capability->promise().IsJSPromise()) return; promise = handle(JSPromise::cast(capability->promise()), isolate); + } else if (IsBuiltinFunction(isolate, reaction->fulfill_handler(), + Builtins::kPromiseCapabilityDefaultResolve)) { + Handle<JSFunction> function(JSFunction::cast(reaction->fulfill_handler()), + isolate); + Handle<Context> context(function->context(), isolate); + promise = + handle(JSPromise::cast(context->get(PromiseBuiltins::kPromiseSlot)), + isolate); } else { // We have some generic promise chain here, so try to // continue with the chained promise on the reaction @@ -973,9 +985,7 @@ struct CaptureStackTraceOptions { bool capture_builtin_exit_frames; bool capture_only_frames_subject_to_debugging; bool async_stack_trace; - - enum CaptureResult { RAW_FRAME_ARRAY, STACK_TRACE_FRAME_ARRAY }; - CaptureResult capture_result; + bool enable_frame_caching; }; Handle<Object> CaptureStackTrace(Isolate* isolate, Handle<Object> caller, @@ -1105,10 +1115,8 @@ Handle<Object> CaptureStackTrace(Isolate* isolate, Handle<Object> caller, } // TODO(yangguo): Queue this structured stack trace for preprocessing on GC. - if (options.capture_result == CaptureStackTraceOptions::RAW_FRAME_ARRAY) { - return builder.GetElements(); - } - return builder.GetElementsAsStackTraceFrameArray(); + return builder.GetElementsAsStackTraceFrameArray( + options.enable_frame_caching); } } // namespace @@ -1126,7 +1134,7 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, options.async_stack_trace = FLAG_async_stack_traces; options.filter_mode = FrameArrayBuilder::CURRENT_SECURITY_CONTEXT; options.capture_only_frames_subject_to_debugging = false; - options.capture_result = CaptureStackTraceOptions::RAW_FRAME_ARRAY; + options.enable_frame_caching = false; return CaptureStackTrace(this, caller, options); } @@ -1222,7 +1230,7 @@ Handle<FixedArray> Isolate::CaptureCurrentStackTrace( ? FrameArrayBuilder::ALL : FrameArrayBuilder::CURRENT_SECURITY_CONTEXT; options.capture_only_frames_subject_to_debugging = true; - options.capture_result = CaptureStackTraceOptions::STACK_TRACE_FRAME_ARRAY; + options.enable_frame_caching = true; return Handle<FixedArray>::cast( CaptureStackTrace(this, factory()->undefined_value(), options)); @@ -1377,7 +1385,8 @@ Object Isolate::StackOverflow() { Handle<Object> exception; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( this, exception, - ErrorUtils::Construct(this, fun, fun, msg, SKIP_NONE, no_caller, true)); + ErrorUtils::Construct(this, fun, fun, msg, SKIP_NONE, no_caller, + ErrorUtils::StackTraceCollection::kSimple)); Throw(*exception, nullptr); @@ -1621,7 +1630,12 @@ Object Isolate::UnwindAndFindHandler() { thread_local_top()->pending_handler_fp_ = handler_fp; thread_local_top()->pending_handler_sp_ = handler_sp; - // Return and clear pending exception. + // Return and clear pending exception. The contract is that: + // (1) the pending exception is stored in one place (no duplication), and + // (2) within generated-code land, that one place is the return register. + // If/when we unwind back into C++ (returning to the JSEntry stub, + // or to Execution::CallWasm), the returned exception will be sent + // back to isolate->set_pending_exception(...). clear_pending_exception(); return exception; }; @@ -1656,6 +1670,19 @@ Object Isolate::UnwindAndFindHandler() { 0); } + case StackFrame::C_WASM_ENTRY: { + StackHandler* handler = frame->top_handler(); + thread_local_top()->handler_ = handler->next_address(); + Code code = frame->LookupCode(); + HandlerTable table(code); + Address instruction_start = code.InstructionStart(); + int return_offset = static_cast<int>(frame->pc() - instruction_start); + int handler_offset = table.LookupReturn(return_offset); + DCHECK_NE(-1, handler_offset); + return FoundHandler(Context(), instruction_start, handler_offset, + code.constant_pool(), frame->sp(), frame->fp()); + } + case StackFrame::WASM_COMPILED: { if (trap_handler::IsThreadInWasm()) { trap_handler::ClearThreadInWasm(); @@ -2014,33 +2041,23 @@ Object Isolate::PromoteScheduledException() { } void Isolate::PrintCurrentStackTrace(FILE* out) { - IncrementalStringBuilder builder(this); - for (StackTraceFrameIterator it(this); !it.done(); it.Advance()) { - if (!it.is_javascript()) continue; + CaptureStackTraceOptions options; + options.limit = 0; + options.skip_mode = SKIP_NONE; + options.capture_builtin_exit_frames = true; + options.async_stack_trace = FLAG_async_stack_traces; + options.filter_mode = FrameArrayBuilder::CURRENT_SECURITY_CONTEXT; + options.capture_only_frames_subject_to_debugging = false; + options.enable_frame_caching = false; - HandleScope scope(this); - JavaScriptFrame* frame = it.javascript_frame(); - - Handle<Object> receiver(frame->receiver(), this); - Handle<JSFunction> function(frame->function(), this); - Handle<AbstractCode> code; - int offset; - if (frame->is_interpreted()) { - InterpretedFrame* interpreted_frame = InterpretedFrame::cast(frame); - code = handle(AbstractCode::cast(interpreted_frame->GetBytecodeArray()), - this); - offset = interpreted_frame->GetBytecodeOffset(); - } else { - code = handle(AbstractCode::cast(frame->LookupCode()), this); - offset = static_cast<int>(frame->pc() - code->InstructionStart()); - } + Handle<FixedArray> frames = Handle<FixedArray>::cast( + CaptureStackTrace(this, this->factory()->undefined_value(), options)); - // To preserve backwards compatiblity, only append a newline when - // the current stringified frame actually has characters. - const int old_length = builder.Length(); - JSStackFrame site(this, receiver, function, code, offset); - site.ToString(builder); - if (old_length != builder.Length()) builder.AppendCharacter('\n'); + IncrementalStringBuilder builder(this); + for (int i = 0; i < frames->length(); ++i) { + Handle<StackTraceFrame> frame(StackTraceFrame::cast(frames->get(i)), this); + + SerializeStackTraceFrame(this, frame, builder); } Handle<String> stack_trace = builder.Finish().ToHandleChecked(); @@ -2113,7 +2130,8 @@ bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target, JSReceiver::GetDataProperty(Handle<JSObject>::cast(exception), key); if (!property->IsFixedArray()) return false; - Handle<FrameArray> elements = Handle<FrameArray>::cast(property); + Handle<FrameArray> elements = + GetFrameArrayFromStackTrace(this, Handle<FixedArray>::cast(property)); const int frame_count = elements->FrameCount(); for (int i = 0; i < frame_count; i++) { @@ -2248,7 +2266,7 @@ bool Isolate::IsExternalHandlerOnTop(Object exception) { } void Isolate::ReportPendingMessagesImpl(bool report_externally) { - Object exception = pending_exception(); + Object exception_obj = pending_exception(); // Clear the pending message object early to avoid endless recursion. Object message_obj = thread_local_top()->pending_message_obj_; @@ -2256,7 +2274,7 @@ void Isolate::ReportPendingMessagesImpl(bool report_externally) { // For uncatchable exceptions we do nothing. If needed, the exception and the // message have already been propagated to v8::TryCatch. - if (!is_catchable_by_javascript(exception)) return; + if (!is_catchable_by_javascript(exception_obj)) return; // Determine whether the message needs to be reported to all message handlers // depending on whether and external v8::TryCatch or an internal JavaScript @@ -2267,19 +2285,20 @@ void Isolate::ReportPendingMessagesImpl(bool report_externally) { should_report_exception = try_catch_handler()->is_verbose_; } else { // Report the exception if it isn't caught by JavaScript code. - should_report_exception = !IsJavaScriptHandlerOnTop(exception); + should_report_exception = !IsJavaScriptHandlerOnTop(exception_obj); } // Actually report the pending message to all message handlers. if (!message_obj.IsTheHole(this) && should_report_exception) { HandleScope scope(this); Handle<JSMessageObject> message(JSMessageObject::cast(message_obj), this); + Handle<Object> exception(exception_obj, this); Handle<Script> script(message->script(), this); // Clear the exception and restore it afterwards, otherwise // CollectSourcePositions will abort. clear_pending_exception(); JSMessageObject::EnsureSourcePositionsAvailable(this, message); - set_pending_exception(exception); + set_pending_exception(*exception); int start_pos = message->GetStartPosition(); int end_pos = message->GetEndPosition(); MessageLocation location(script, start_pos, end_pos); @@ -2853,6 +2872,13 @@ void Isolate::Delete(Isolate* isolate) { SetIsolateThreadLocals(saved_isolate, saved_data); } +void Isolate::SetUpFromReadOnlyHeap(ReadOnlyHeap* ro_heap) { + DCHECK_NOT_NULL(ro_heap); + DCHECK_IMPLIES(read_only_heap_ != nullptr, read_only_heap_ == ro_heap); + read_only_heap_ = ro_heap; + heap_.SetUpFromReadOnlyHeap(ro_heap); +} + v8::PageAllocator* Isolate::page_allocator() { return isolate_allocator_->page_allocator(); } @@ -3282,6 +3308,21 @@ bool Isolate::InitWithSnapshot(ReadOnlyDeserializer* read_only_deserializer, return Init(read_only_deserializer, startup_deserializer); } +static void AddCrashKeysForIsolateAndHeapPointers(Isolate* isolate) { + v8::Platform* platform = V8::GetCurrentPlatform(); + + const int id = isolate->id(); + platform->AddCrashKey(id, "isolate", reinterpret_cast<uintptr_t>(isolate)); + + auto heap = isolate->heap(); + platform->AddCrashKey(id, "ro_space", + reinterpret_cast<uintptr_t>(heap->read_only_space()->first_page())); + platform->AddCrashKey(id, "map_space", + reinterpret_cast<uintptr_t>(heap->map_space()->first_page())); + platform->AddCrashKey(id, "code_space", + reinterpret_cast<uintptr_t>(heap->code_space()->first_page())); +} + bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer, StartupDeserializer* startup_deserializer) { TRACE_ISOLATE(init); @@ -3432,7 +3473,7 @@ bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer, if (create_heap_objects) { heap_.read_only_space()->ClearStringPaddingIfNeeded(); - heap_.read_only_heap()->OnCreateHeapObjectsComplete(this); + read_only_heap_->OnCreateHeapObjectsComplete(this); } else { startup_deserializer->DeserializeInto(this); } @@ -3527,6 +3568,7 @@ bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer, PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms); } + AddCrashKeysForIsolateAndHeapPointers(this); return true; } @@ -3693,9 +3735,9 @@ void Isolate::MaybeInitializeVectorListFromHeap() { std::vector<Handle<FeedbackVector>> vectors; { - HeapIterator heap_iterator(heap()); - for (HeapObject current_obj = heap_iterator.next(); !current_obj.is_null(); - current_obj = heap_iterator.next()) { + HeapObjectIterator heap_iterator(heap()); + for (HeapObject current_obj = heap_iterator.Next(); !current_obj.is_null(); + current_obj = heap_iterator.Next()) { if (!current_obj.IsFeedbackVector()) continue; FeedbackVector vector = FeedbackVector::cast(current_obj); @@ -3907,13 +3949,31 @@ void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) { if (!IsNoElementsProtectorIntact()) return; if (!IsArrayOrObjectOrStringPrototype(*object)) return; PropertyCell::SetValueWithInvalidation( - this, factory()->no_elements_protector(), + this, "no_elements_protector", factory()->no_elements_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); } +void Isolate::TraceProtectorInvalidation(const char* protector_name) { + static constexpr char kInvalidateProtectorTracingCategory[] = + "V8.InvalidateProtector"; + static constexpr char kInvalidateProtectorTracingArg[] = "protector-name"; + + DCHECK(FLAG_trace_protector_invalidation); + + // TODO(jgruber): Remove the PrintF once tracing can output to stdout. + i::PrintF("Invalidating protector cell %s in isolate %p\n", protector_name, + this); + TRACE_EVENT_INSTANT1("v8", kInvalidateProtectorTracingCategory, + TRACE_EVENT_SCOPE_THREAD, kInvalidateProtectorTracingArg, + protector_name); +} + void Isolate::InvalidateIsConcatSpreadableProtector() { DCHECK(factory()->is_concat_spreadable_protector()->value().IsSmi()); DCHECK(IsIsConcatSpreadableLookupChainIntact()); + if (FLAG_trace_protector_invalidation) { + TraceProtectorInvalidation("is_concat_spreadable_protector"); + } factory()->is_concat_spreadable_protector()->set_value( Smi::FromInt(kProtectorInvalid)); DCHECK(!IsIsConcatSpreadableLookupChainIntact()); @@ -3922,6 +3982,9 @@ void Isolate::InvalidateIsConcatSpreadableProtector() { void Isolate::InvalidateArrayConstructorProtector() { DCHECK(factory()->array_constructor_protector()->value().IsSmi()); DCHECK(IsArrayConstructorIntact()); + if (FLAG_trace_protector_invalidation) { + TraceProtectorInvalidation("array_constructor_protector"); + } factory()->array_constructor_protector()->set_value( Smi::FromInt(kProtectorInvalid)); DCHECK(!IsArrayConstructorIntact()); @@ -3931,7 +3994,7 @@ void Isolate::InvalidateArraySpeciesProtector() { DCHECK(factory()->array_species_protector()->value().IsSmi()); DCHECK(IsArraySpeciesLookupChainIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->array_species_protector(), + this, "array_species_protector", factory()->array_species_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsArraySpeciesLookupChainIntact()); } @@ -3940,25 +4003,30 @@ void Isolate::InvalidateTypedArraySpeciesProtector() { DCHECK(factory()->typed_array_species_protector()->value().IsSmi()); DCHECK(IsTypedArraySpeciesLookupChainIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->typed_array_species_protector(), + this, "typed_array_species_protector", + factory()->typed_array_species_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsTypedArraySpeciesLookupChainIntact()); } -void Isolate::InvalidateRegExpSpeciesProtector() { - DCHECK(factory()->regexp_species_protector()->value().IsSmi()); - DCHECK(IsRegExpSpeciesLookupChainIntact()); +void Isolate::InvalidateRegExpSpeciesProtector( + Handle<NativeContext> native_context) { + DCHECK_EQ(*native_context, this->raw_native_context()); + DCHECK(native_context->regexp_species_protector().value().IsSmi()); + DCHECK(IsRegExpSpeciesLookupChainIntact(native_context)); + Handle<PropertyCell> species_cell(native_context->regexp_species_protector(), + this); PropertyCell::SetValueWithInvalidation( - this, factory()->regexp_species_protector(), + this, "regexp_species_protector", species_cell, handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsRegExpSpeciesLookupChainIntact()); + DCHECK(!IsRegExpSpeciesLookupChainIntact(native_context)); } void Isolate::InvalidatePromiseSpeciesProtector() { DCHECK(factory()->promise_species_protector()->value().IsSmi()); DCHECK(IsPromiseSpeciesLookupChainIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->promise_species_protector(), + this, "promise_species_protector", factory()->promise_species_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsPromiseSpeciesLookupChainIntact()); } @@ -3966,6 +4034,9 @@ void Isolate::InvalidatePromiseSpeciesProtector() { void Isolate::InvalidateStringLengthOverflowProtector() { DCHECK(factory()->string_length_protector()->value().IsSmi()); DCHECK(IsStringLengthOverflowIntact()); + if (FLAG_trace_protector_invalidation) { + TraceProtectorInvalidation("string_length_protector"); + } factory()->string_length_protector()->set_value( Smi::FromInt(kProtectorInvalid)); DCHECK(!IsStringLengthOverflowIntact()); @@ -3975,7 +4046,7 @@ void Isolate::InvalidateArrayIteratorProtector() { DCHECK(factory()->array_iterator_protector()->value().IsSmi()); DCHECK(IsArrayIteratorLookupChainIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->array_iterator_protector(), + this, "array_iterator_protector", factory()->array_iterator_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsArrayIteratorLookupChainIntact()); } @@ -3984,7 +4055,7 @@ void Isolate::InvalidateMapIteratorProtector() { DCHECK(factory()->map_iterator_protector()->value().IsSmi()); DCHECK(IsMapIteratorLookupChainIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->map_iterator_protector(), + this, "map_iterator_protector", factory()->map_iterator_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsMapIteratorLookupChainIntact()); } @@ -3993,7 +4064,7 @@ void Isolate::InvalidateSetIteratorProtector() { DCHECK(factory()->set_iterator_protector()->value().IsSmi()); DCHECK(IsSetIteratorLookupChainIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->set_iterator_protector(), + this, "set_iterator_protector", factory()->set_iterator_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsSetIteratorLookupChainIntact()); } @@ -4002,7 +4073,7 @@ void Isolate::InvalidateStringIteratorProtector() { DCHECK(factory()->string_iterator_protector()->value().IsSmi()); DCHECK(IsStringIteratorLookupChainIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->string_iterator_protector(), + this, "string_iterator_protector", factory()->string_iterator_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsStringIteratorLookupChainIntact()); } @@ -4011,7 +4082,8 @@ void Isolate::InvalidateArrayBufferDetachingProtector() { DCHECK(factory()->array_buffer_detaching_protector()->value().IsSmi()); DCHECK(IsArrayBufferDetachingIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->array_buffer_detaching_protector(), + this, "array_buffer_detaching_protector", + factory()->array_buffer_detaching_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsArrayBufferDetachingIntact()); } @@ -4020,7 +4092,7 @@ void Isolate::InvalidatePromiseHookProtector() { DCHECK(factory()->promise_hook_protector()->value().IsSmi()); DCHECK(IsPromiseHookProtectorIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->promise_hook_protector(), + this, "promise_hook_protector", factory()->promise_hook_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsPromiseHookProtectorIntact()); } @@ -4028,6 +4100,9 @@ void Isolate::InvalidatePromiseHookProtector() { void Isolate::InvalidatePromiseResolveProtector() { DCHECK(factory()->promise_resolve_protector()->value().IsSmi()); DCHECK(IsPromiseResolveLookupChainIntact()); + if (FLAG_trace_protector_invalidation) { + TraceProtectorInvalidation("promise_resolve_protector"); + } factory()->promise_resolve_protector()->set_value( Smi::FromInt(kProtectorInvalid)); DCHECK(!IsPromiseResolveLookupChainIntact()); @@ -4037,7 +4112,7 @@ void Isolate::InvalidatePromiseThenProtector() { DCHECK(factory()->promise_then_protector()->value().IsSmi()); DCHECK(IsPromiseThenLookupChainIntact()); PropertyCell::SetValueWithInvalidation( - this, factory()->promise_then_protector(), + this, "promise_then_protector", factory()->promise_then_protector(), handle(Smi::FromInt(kProtectorInvalid), this)); DCHECK(!IsPromiseThenLookupChainIntact()); } @@ -4176,7 +4251,7 @@ void Isolate::FireCallCompletedCallback(MicrotaskQueue* microtask_queue) { // set is still open (whether to clear it after every microtask or once // during a microtask checkpoint). See also // https://github.com/tc39/proposal-weakrefs/issues/39 . - heap()->ClearKeepDuringJobSet(); + heap()->ClearKeptObjects(); } if (call_completed_callbacks_.empty()) return; @@ -4261,7 +4336,7 @@ void Isolate::SetHostImportModuleDynamicallyCallback( } Handle<JSObject> Isolate::RunHostInitializeImportMetaObjectCallback( - Handle<Module> module) { + Handle<SourceTextModule> module) { Handle<Object> host_meta(module->import_meta(), this); if (host_meta->IsTheHole(this)) { host_meta = factory()->NewJSObjectWithNullProto(); @@ -4269,7 +4344,7 @@ Handle<JSObject> Isolate::RunHostInitializeImportMetaObjectCallback( v8::Local<v8::Context> api_context = v8::Utils::ToLocal(Handle<Context>(native_context())); host_initialize_import_meta_object_callback_( - api_context, Utils::ToLocal(module), + api_context, Utils::ToLocal(Handle<Module>::cast(module)), v8::Local<v8::Object>::Cast(v8::Utils::ToLocal(host_meta))); } module->set_import_meta(*host_meta); @@ -4641,26 +4716,6 @@ AssertNoContextChange::AssertNoContextChange(Isolate* isolate) : isolate_(isolate), context_(isolate->context(), isolate) {} #endif // DEBUG -bool InterruptsScope::Intercept(StackGuard::InterruptFlag flag) { - InterruptsScope* last_postpone_scope = nullptr; - for (InterruptsScope* current = this; current; current = current->prev_) { - // We only consider scopes related to passed flag. - if (!(current->intercept_mask_ & flag)) continue; - if (current->mode_ == kRunInterrupts) { - // If innermost scope is kRunInterrupts scope, prevent interrupt from - // being intercepted. - break; - } else { - DCHECK_EQ(current->mode_, kPostponeInterrupts); - last_postpone_scope = current; - } - } - // If there is no postpone scope for passed flag then we should not intercept. - if (!last_postpone_scope) return false; - last_postpone_scope->intercepted_flags_ |= flag; - return true; -} - #undef TRACE_ISOLATE } // namespace internal |