LCOV - code coverage report
Current view: top level - src - execution.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 178 221 80.5 %
Date: 2017-10-20 Functions: 24 29 82.8 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/execution.h"
       6             : 
       7             : #include "src/api.h"
       8             : #include "src/bootstrapper.h"
       9             : #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
      10             : #include "src/debug/debug.h"
      11             : #include "src/isolate-inl.h"
      12             : #include "src/messages.h"
      13             : #include "src/runtime-profiler.h"
      14             : #include "src/vm-state-inl.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19      109998 : StackGuard::StackGuard() : isolate_(nullptr) {}
      20             : 
      21       72440 : void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
      22             :   DCHECK_NOT_NULL(isolate_);
      23             :   thread_local_.set_jslimit(kInterruptLimit);
      24             :   thread_local_.set_climit(kInterruptLimit);
      25       72440 :   isolate_->heap()->SetStackLimits();
      26       72440 : }
      27             : 
      28             : 
      29     4068803 : void StackGuard::reset_limits(const ExecutionAccess& lock) {
      30             :   DCHECK_NOT_NULL(isolate_);
      31     4068803 :   thread_local_.set_jslimit(thread_local_.real_jslimit_);
      32     4068803 :   thread_local_.set_climit(thread_local_.real_climit_);
      33     4068803 :   isolate_->heap()->SetStackLimits();
      34     4068801 : }
      35             : 
      36             : 
      37           0 : static void PrintDeserializedCodeInfo(Handle<JSFunction> function) {
      38           0 :   if (function->code() == function->shared()->code() &&
      39             :       function->shared()->deserialized()) {
      40           0 :     PrintF("[Running deserialized script");
      41             :     Object* script = function->shared()->script();
      42           0 :     if (script->IsScript()) {
      43             :       Object* name = Script::cast(script)->name();
      44           0 :       if (name->IsString()) {
      45           0 :         PrintF(": %s", String::cast(name)->ToCString().get());
      46             :       }
      47             :     }
      48           0 :     PrintF("]\n");
      49             :   }
      50           0 : }
      51             : 
      52             : 
      53             : namespace {
      54             : 
      55    23052416 : MUST_USE_RESULT MaybeHandle<Object> Invoke(
      56             :     Isolate* isolate, bool is_construct, Handle<Object> target,
      57             :     Handle<Object> receiver, int argc, Handle<Object> args[],
      58             :     Handle<Object> new_target, Execution::MessageHandling message_handling) {
      59             :   DCHECK(!receiver->IsJSGlobalObject());
      60             : 
      61             : #ifdef USE_SIMULATOR
      62             :   // Simulators use separate stacks for C++ and JS. JS stack overflow checks
      63             :   // are performed whenever a JS function is called. However, it can be the case
      64             :   // that the C++ stack grows faster than the JS stack, resulting in an overflow
      65             :   // there. Add a check here to make that less likely.
      66             :   StackLimitCheck check(isolate);
      67             :   if (check.HasOverflowed()) {
      68             :     isolate->StackOverflow();
      69             :     if (message_handling == Execution::MessageHandling::kReport) {
      70             :       isolate->ReportPendingMessages();
      71             :     }
      72             :     return MaybeHandle<Object>();
      73             :   }
      74             : #endif
      75             : 
      76             :   // api callbacks can be called directly.
      77    23052415 :   if (target->IsJSFunction()) {
      78             :     Handle<JSFunction> function = Handle<JSFunction>::cast(target);
      79    46027877 :     if ((!is_construct || function->IsConstructor()) &&
      80    23007714 :         function->shared()->IsApiFunction()) {
      81       12126 :       SaveContext save(isolate);
      82             :       isolate->set_context(function->context());
      83             :       DCHECK(function->context()->global_object()->IsJSGlobalObject());
      84       12126 :       if (is_construct) receiver = isolate->factory()->the_hole_value();
      85             :       auto value = Builtins::InvokeApiFunction(
      86             :           isolate, is_construct, function, receiver, argc, args,
      87       12126 :           Handle<HeapObject>::cast(new_target));
      88             :       bool has_exception = value.is_null();
      89             :       DCHECK(has_exception == isolate->has_pending_exception());
      90       12126 :       if (has_exception) {
      91         134 :         if (message_handling == Execution::MessageHandling::kReport) {
      92         134 :           isolate->ReportPendingMessages();
      93             :         }
      94         134 :         return MaybeHandle<Object>();
      95             :       } else {
      96             :         isolate->clear_pending_message();
      97             :       }
      98       11992 :       return value;
      99             :     }
     100             :   }
     101             : 
     102             :   // Entering JavaScript.
     103             :   VMState<JS> state(isolate);
     104    23040288 :   CHECK(AllowJavascriptExecution::IsAllowed(isolate));
     105    23040303 :   if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
     106           5 :     isolate->ThrowIllegalOperation();
     107           5 :     if (message_handling == Execution::MessageHandling::kReport) {
     108           5 :       isolate->ReportPendingMessages();
     109             :     }
     110           5 :     return MaybeHandle<Object>();
     111             :   }
     112             : 
     113             :   // Placeholder for return value.
     114             :   Object* value = nullptr;
     115             : 
     116             :   typedef Object* (*JSEntryFunction)(Object* new_target, Object* target,
     117             :                                      Object* receiver, int argc,
     118             :                                      Object*** args);
     119             : 
     120             :   Handle<Code> code = is_construct
     121             :       ? isolate->factory()->js_construct_entry_code()
     122    23040298 :       : isolate->factory()->js_entry_code();
     123             : 
     124             :   {
     125             :     // Save and restore context around invocation and block the
     126             :     // allocation of handles without explicit handle scopes.
     127    23040298 :     SaveContext save(isolate);
     128             :     SealHandleScope shs(isolate);
     129    23040310 :     JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
     130             : 
     131    23040310 :     if (FLAG_clear_exceptions_on_js_entry) isolate->clear_pending_exception();
     132             : 
     133             :     // Call the function through the right JS entry stub.
     134             :     Object* orig_func = *new_target;
     135             :     Object* func = *target;
     136             :     Object* recv = *receiver;
     137             :     Object*** argv = reinterpret_cast<Object***>(args);
     138    23040310 :     if (FLAG_profile_deserialization && target->IsJSFunction()) {
     139           0 :       PrintDeserializedCodeInfo(Handle<JSFunction>::cast(target));
     140             :     }
     141    23040310 :     RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::JS_Execution);
     142             :     value = CALL_GENERATED_CODE(isolate, stub_entry, orig_func, func, recv,
     143    46080635 :                                 argc, argv);
     144             :   }
     145             : 
     146             : #ifdef VERIFY_HEAP
     147             :   if (FLAG_verify_heap) {
     148             :     value->ObjectVerify();
     149             :   }
     150             : #endif
     151             : 
     152             :   // Update the pending exception flag and return the value.
     153             :   bool has_exception = value->IsException(isolate);
     154             :   DCHECK(has_exception == isolate->has_pending_exception());
     155    23040324 :   if (has_exception) {
     156       61393 :     if (message_handling == Execution::MessageHandling::kReport) {
     157       61388 :       isolate->ReportPendingMessages();
     158             :     }
     159       61393 :     return MaybeHandle<Object>();
     160             :   } else {
     161             :     isolate->clear_pending_message();
     162             :   }
     163             : 
     164    22978933 :   return Handle<Object>(value, isolate);
     165             : }
     166             : 
     167    23039906 : MaybeHandle<Object> CallInternal(Isolate* isolate, Handle<Object> callable,
     168             :                                  Handle<Object> receiver, int argc,
     169             :                                  Handle<Object> argv[],
     170             :                                  Execution::MessageHandling message_handling) {
     171             :   // Convert calls on global objects to be calls on the global
     172             :   // receiver instead to avoid having a 'this' pointer which refers
     173             :   // directly to a global object.
     174    23039917 :   if (receiver->IsJSGlobalObject()) {
     175             :     receiver =
     176             :         handle(Handle<JSGlobalObject>::cast(receiver)->global_proxy(), isolate);
     177             :   }
     178             :   return Invoke(isolate, false, callable, receiver, argc, argv,
     179    23039917 :                 isolate->factory()->undefined_value(), message_handling);
     180             : }
     181             : 
     182             : }  // namespace
     183             : 
     184             : // static
     185    22691197 : MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
     186             :                                     Handle<Object> receiver, int argc,
     187             :                                     Handle<Object> argv[]) {
     188             :   return CallInternal(isolate, callable, receiver, argc, argv,
     189    22691197 :                       MessageHandling::kReport);
     190             : }
     191             : 
     192             : 
     193             : // static
     194       11332 : MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
     195             :                                    int argc, Handle<Object> argv[]) {
     196       11332 :   return New(isolate, constructor, constructor, argc, argv);
     197             : }
     198             : 
     199             : 
     200             : // static
     201        1167 : MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
     202             :                                    Handle<Object> new_target, int argc,
     203             :                                    Handle<Object> argv[]) {
     204             :   return Invoke(isolate, true, constructor,
     205             :                 isolate->factory()->undefined_value(), argc, argv, new_target,
     206       12499 :                 MessageHandling::kReport);
     207             : }
     208             : 
     209      348837 : MaybeHandle<Object> Execution::TryCall(Isolate* isolate,
     210             :                                        Handle<Object> callable,
     211             :                                        Handle<Object> receiver, int argc,
     212             :                                        Handle<Object> args[],
     213             :                                        MessageHandling message_handling,
     214             :                                        MaybeHandle<Object>* exception_out) {
     215             :   bool is_termination = false;
     216             :   MaybeHandle<Object> maybe_result;
     217      348713 :   if (exception_out != nullptr) *exception_out = MaybeHandle<Object>();
     218             :   DCHECK_IMPLIES(message_handling == MessageHandling::kKeepPending,
     219             :                  exception_out == nullptr);
     220             :   // Enter a try-block while executing the JavaScript code. To avoid
     221             :   // duplicate error printing it must be non-verbose.  Also, to avoid
     222             :   // creating message objects during stack overflow we shouldn't
     223             :   // capture messages.
     224             :   {
     225      348713 :     v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
     226      348713 :     catcher.SetVerbose(false);
     227      348713 :     catcher.SetCaptureMessage(false);
     228             : 
     229             :     maybe_result =
     230      348713 :         CallInternal(isolate, callable, receiver, argc, args, message_handling);
     231             : 
     232      348716 :     if (maybe_result.is_null()) {
     233             :       DCHECK(isolate->has_pending_exception());
     234         124 :       if (isolate->pending_exception() ==
     235         124 :           isolate->heap()->termination_exception()) {
     236             :         is_termination = true;
     237             :       } else {
     238         112 :         if (exception_out != nullptr) {
     239             :           DCHECK(catcher.HasCaught());
     240             :           DCHECK(isolate->external_caught_exception());
     241         214 :           *exception_out = v8::Utils::OpenHandle(*catcher.Exception());
     242             :         }
     243             :       }
     244         124 :       if (message_handling == MessageHandling::kReport) {
     245         119 :         isolate->OptionalRescheduleException(true);
     246             :       }
     247      348716 :     }
     248             :   }
     249             : 
     250             :   // Re-request terminate execution interrupt to trigger later.
     251      348716 :   if (is_termination) isolate->stack_guard()->RequestTerminateExecution();
     252             : 
     253      348716 :   return maybe_result;
     254             : }
     255             : 
     256             : 
     257        1636 : void StackGuard::SetStackLimit(uintptr_t limit) {
     258        1636 :   ExecutionAccess access(isolate_);
     259             :   // If the current limits are special (e.g. due to a pending interrupt) then
     260             :   // leave them alone.
     261             :   uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
     262        1636 :   if (thread_local_.jslimit() == thread_local_.real_jslimit_) {
     263             :     thread_local_.set_jslimit(jslimit);
     264             :   }
     265        1636 :   if (thread_local_.climit() == thread_local_.real_climit_) {
     266             :     thread_local_.set_climit(limit);
     267             :   }
     268        1636 :   thread_local_.real_climit_ = limit;
     269        1636 :   thread_local_.real_jslimit_ = jslimit;
     270        1636 : }
     271             : 
     272             : 
     273           0 : void StackGuard::AdjustStackLimitForSimulator() {
     274           0 :   ExecutionAccess access(isolate_);
     275           0 :   uintptr_t climit = thread_local_.real_climit_;
     276             :   // If the current limits are special (e.g. due to a pending interrupt) then
     277             :   // leave them alone.
     278             :   uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, climit);
     279           0 :   if (thread_local_.jslimit() == thread_local_.real_jslimit_) {
     280             :     thread_local_.set_jslimit(jslimit);
     281           0 :     isolate_->heap()->SetStackLimits();
     282             :   }
     283           0 : }
     284             : 
     285             : 
     286           0 : void StackGuard::EnableInterrupts() {
     287           0 :   ExecutionAccess access(isolate_);
     288           0 :   if (has_pending_interrupts(access)) {
     289           0 :     set_interrupt_limits(access);
     290             :   }
     291           0 : }
     292             : 
     293             : 
     294           0 : void StackGuard::DisableInterrupts() {
     295           0 :   ExecutionAccess access(isolate_);
     296           0 :   reset_limits(access);
     297           0 : }
     298             : 
     299             : 
     300     3178442 : void StackGuard::PushPostponeInterruptsScope(PostponeInterruptsScope* scope) {
     301     3178442 :   ExecutionAccess access(isolate_);
     302             :   // Intercept already requested interrupts.
     303     3178444 :   int intercepted = thread_local_.interrupt_flags_ & scope->intercept_mask_;
     304     3178444 :   scope->intercepted_flags_ = intercepted;
     305     3178444 :   thread_local_.interrupt_flags_ &= ~intercepted;
     306     3178444 :   if (!has_pending_interrupts(access)) reset_limits(access);
     307             :   // Add scope to the chain.
     308     3178442 :   scope->prev_ = thread_local_.postpone_interrupts_;
     309     3178442 :   thread_local_.postpone_interrupts_ = scope;
     310     3178444 : }
     311             : 
     312             : 
     313     3178441 : void StackGuard::PopPostponeInterruptsScope() {
     314     3178441 :   ExecutionAccess access(isolate_);
     315     3178444 :   PostponeInterruptsScope* top = thread_local_.postpone_interrupts_;
     316             :   // Make intercepted interrupts active.
     317             :   DCHECK_EQ(thread_local_.interrupt_flags_ & top->intercept_mask_, 0);
     318     3178444 :   thread_local_.interrupt_flags_ |= top->intercepted_flags_;
     319     3178444 :   if (has_pending_interrupts(access)) set_interrupt_limits(access);
     320             :   // Remove scope from chain.
     321     3178444 :   thread_local_.postpone_interrupts_ = top->prev_;
     322     3178444 : }
     323             : 
     324             : 
     325         594 : bool StackGuard::CheckInterrupt(InterruptFlag flag) {
     326         594 :   ExecutionAccess access(isolate_);
     327      291215 :   return thread_local_.interrupt_flags_ & flag;
     328             : }
     329             : 
     330             : 
     331       42823 : void StackGuard::RequestInterrupt(InterruptFlag flag) {
     332       42823 :   ExecutionAccess access(isolate_);
     333             :   // Check the chain of PostponeInterruptsScopes for interception.
     334       62737 :   if (thread_local_.postpone_interrupts_ &&
     335       19914 :       thread_local_.postpone_interrupts_->Intercept(flag)) {
     336       42823 :     return;
     337             :   }
     338             : 
     339             :   // Not intercepted.  Set as active interrupt flag.
     340       22916 :   thread_local_.interrupt_flags_ |= flag;
     341       22916 :   set_interrupt_limits(access);
     342             : 
     343             :   // If this isolate is waiting in a futex, notify it to wake up.
     344       22916 :   isolate_->futex_wait_list_node()->NotifyWake();
     345             : }
     346             : 
     347             : 
     348       43456 : void StackGuard::ClearInterrupt(InterruptFlag flag) {
     349       43456 :   ExecutionAccess access(isolate_);
     350             :   // Clear the interrupt flag from the chain of PostponeInterruptsScopes.
     351       60164 :   for (PostponeInterruptsScope* current = thread_local_.postpone_interrupts_;
     352             :        current != nullptr; current = current->prev_) {
     353       16708 :     current->intercepted_flags_ &= ~flag;
     354             :   }
     355             : 
     356             :   // Clear the interrupt flag from the active interrupt flags.
     357       43456 :   thread_local_.interrupt_flags_ &= ~flag;
     358       43456 :   if (!has_pending_interrupts(access)) reset_limits(access);
     359       43456 : }
     360             : 
     361             : 
     362     1446829 : bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag) {
     363     1446829 :   ExecutionAccess access(isolate_);
     364     1446829 :   bool result = (thread_local_.interrupt_flags_ & flag);
     365     1446829 :   thread_local_.interrupt_flags_ &= ~flag;
     366     1446829 :   if (!has_pending_interrupts(access)) reset_limits(access);
     367     1446829 :   return result;
     368             : }
     369             : 
     370             : 
     371       24163 : char* StackGuard::ArchiveStackGuard(char* to) {
     372       24163 :   ExecutionAccess access(isolate_);
     373       24163 :   MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
     374             :   ThreadLocal blank;
     375             : 
     376             :   // Set the stack limits using the old thread_local_.
     377             :   // TODO(isolates): This was the old semantics of constructing a ThreadLocal
     378             :   //                 (as the ctor called SetStackLimits, which looked at the
     379             :   //                 current thread_local_ from StackGuard)-- but is this
     380             :   //                 really what was intended?
     381       24163 :   isolate_->heap()->SetStackLimits();
     382       24163 :   thread_local_ = blank;
     383             : 
     384       48326 :   return to + sizeof(ThreadLocal);
     385             : }
     386             : 
     387             : 
     388       24163 : char* StackGuard::RestoreStackGuard(char* from) {
     389       24163 :   ExecutionAccess access(isolate_);
     390       24163 :   MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
     391       24163 :   isolate_->heap()->SetStackLimits();
     392       48326 :   return from + sizeof(ThreadLocal);
     393             : }
     394             : 
     395             : 
     396        5856 : void StackGuard::FreeThreadResources() {
     397             :   Isolate::PerIsolateThreadData* per_thread =
     398        5856 :       isolate_->FindOrAllocatePerThreadDataForThisThread();
     399        5856 :   per_thread->set_stack_limit(thread_local_.real_climit_);
     400        5856 : }
     401             : 
     402             : 
     403       85018 : void StackGuard::ThreadLocal::Clear() {
     404       85018 :   real_jslimit_ = kIllegalLimit;
     405             :   set_jslimit(kIllegalLimit);
     406       85018 :   real_climit_ = kIllegalLimit;
     407             :   set_climit(kIllegalLimit);
     408       85018 :   postpone_interrupts_ = nullptr;
     409       85018 :   interrupt_flags_ = 0;
     410       85018 : }
     411             : 
     412             : 
     413       66710 : bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
     414             :   bool should_set_stack_limits = false;
     415       66710 :   if (real_climit_ == kIllegalLimit) {
     416       62076 :     const uintptr_t kLimitSize = FLAG_stack_size * KB;
     417             :     DCHECK_GT(GetCurrentStackPosition(), kLimitSize);
     418       62076 :     uintptr_t limit = GetCurrentStackPosition() - kLimitSize;
     419       62076 :     real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
     420             :     set_jslimit(SimulatorStack::JsLimitFromCLimit(isolate, limit));
     421       62076 :     real_climit_ = limit;
     422             :     set_climit(limit);
     423             :     should_set_stack_limits = true;
     424             :   }
     425       66710 :   postpone_interrupts_ = nullptr;
     426       66710 :   interrupt_flags_ = 0;
     427       66710 :   return should_set_stack_limits;
     428             : }
     429             : 
     430             : 
     431        5856 : void StackGuard::ClearThread(const ExecutionAccess& lock) {
     432        5856 :   thread_local_.Clear();
     433        5856 :   isolate_->heap()->SetStackLimits();
     434        5856 : }
     435             : 
     436             : 
     437       66710 : void StackGuard::InitThread(const ExecutionAccess& lock) {
     438       66710 :   if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
     439       66711 :   Isolate::PerIsolateThreadData* per_thread =
     440       66711 :       isolate_->FindOrAllocatePerThreadDataForThisThread();
     441             :   uintptr_t stored_limit = per_thread->stack_limit();
     442             :   // You should hold the ExecutionAccess lock when you call this.
     443       66711 :   if (stored_limit != 0) {
     444         150 :     SetStackLimit(stored_limit);
     445             :   }
     446       66711 : }
     447             : 
     448             : 
     449             : // --- C a l l s   t o   n a t i v e s ---
     450             : 
     451             : 
     452           0 : void StackGuard::HandleGCInterrupt() {
     453           0 :   if (CheckAndClearInterrupt(GC_REQUEST)) {
     454           0 :     isolate_->heap()->HandleGCRequest();
     455             :   }
     456           0 : }
     457             : 
     458             : 
     459      580054 : Object* StackGuard::HandleInterrupts() {
     460             :   if (FLAG_verify_predictable) {
     461             :     // Advance synthetic time by making a time request.
     462      415678 :     isolate_->heap()->MonotonicallyIncreasingTimeInMs();
     463             :   }
     464             : 
     465             :   bool any_interrupt_handled = false;
     466      290027 :   if (FLAG_trace_interrupts) {
     467           0 :     PrintF("[Handling interrupts: ");
     468             :   }
     469             : 
     470      290027 :   if (CheckAndClearInterrupt(GC_REQUEST)) {
     471        1860 :     if (FLAG_trace_interrupts) {
     472           0 :       PrintF("GC_REQUEST");
     473             :       any_interrupt_handled = true;
     474             :     }
     475        1860 :     isolate_->heap()->HandleGCRequest();
     476             :   }
     477             : 
     478      290027 :   if (CheckDebugBreak()) {
     479      119627 :     if (FLAG_trace_interrupts) {
     480           0 :       if (any_interrupt_handled) PrintF(", ");
     481           0 :       PrintF("DEBUG_BREAK");
     482             :       any_interrupt_handled = true;
     483             :     }
     484      239254 :     isolate_->debug()->HandleDebugBreak(kIgnoreIfTopFrameBlackboxed);
     485             :   }
     486             : 
     487      290027 :   if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
     488        1102 :     if (FLAG_trace_interrupts) {
     489           0 :       if (any_interrupt_handled) PrintF(", ");
     490           0 :       PrintF("TERMINATE_EXECUTION");
     491             :       any_interrupt_handled = true;
     492             :     }
     493        1102 :     return isolate_->TerminateExecution();
     494             :   }
     495             : 
     496      288925 :   if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES)) {
     497          32 :     if (FLAG_trace_interrupts) {
     498           0 :       if (any_interrupt_handled) PrintF(", ");
     499           0 :       PrintF("DEOPT_MARKED_ALLOCATION_SITES");
     500             :       any_interrupt_handled = true;
     501             :     }
     502          32 :     isolate_->heap()->DeoptMarkedAllocationSites();
     503             :   }
     504             : 
     505      288925 :   if (CheckAndClearInterrupt(INSTALL_CODE)) {
     506        7126 :     if (FLAG_trace_interrupts) {
     507           0 :       if (any_interrupt_handled) PrintF(", ");
     508           0 :       PrintF("INSTALL_CODE");
     509             :       any_interrupt_handled = true;
     510             :     }
     511             :     DCHECK(isolate_->concurrent_recompilation_enabled());
     512       14252 :     isolate_->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
     513             :   }
     514             : 
     515      288925 :   if (CheckAndClearInterrupt(API_INTERRUPT)) {
     516          78 :     if (FLAG_trace_interrupts) {
     517           0 :       if (any_interrupt_handled) PrintF(", ");
     518           0 :       PrintF("API_INTERRUPT");
     519             :       any_interrupt_handled = true;
     520             :     }
     521             :     // Callbacks must be invoked outside of ExecusionAccess lock.
     522          78 :     isolate_->InvokeApiInterruptCallbacks();
     523             :   }
     524             : 
     525      288925 :   if (FLAG_trace_interrupts) {
     526           0 :     if (!any_interrupt_handled) {
     527           0 :       PrintF("No interrupt flags set");
     528             :     }
     529           0 :     PrintF("]\n");
     530             :   }
     531             : 
     532      577850 :   isolate_->counters()->stack_interrupts()->Increment();
     533      577850 :   isolate_->counters()->runtime_profiler_ticks()->Increment();
     534      577850 :   isolate_->runtime_profiler()->MarkCandidatesForOptimization();
     535             : 
     536      288925 :   return isolate_->heap()->undefined_value();
     537             : }
     538             : 
     539             : }  // namespace internal
     540             : }  // namespace v8

Generated by: LCOV version 1.10