LCOV - code coverage report
Current view: top level - src/runtime - runtime-test.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 353 427 82.7 %
Date: 2019-04-19 Functions: 87 184 47.3 %

          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/runtime/runtime-utils.h"
       6             : 
       7             : #include <memory>
       8             : #include <sstream>
       9             : 
      10             : #include "src/api-inl.h"
      11             : #include "src/arguments-inl.h"
      12             : #include "src/assembler-inl.h"
      13             : #include "src/base/platform/mutex.h"
      14             : #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
      15             : #include "src/compiler.h"
      16             : #include "src/counters.h"
      17             : #include "src/deoptimizer.h"
      18             : #include "src/frames-inl.h"
      19             : #include "src/heap/heap-inl.h"  // For ToBoolean. TODO(jkummerow): Drop.
      20             : #include "src/heap/heap-write-barrier-inl.h"
      21             : #include "src/ic/stub-cache.h"
      22             : #include "src/isolate-inl.h"
      23             : #include "src/objects/heap-object-inl.h"
      24             : #include "src/objects/smi.h"
      25             : #include "src/ostreams.h"
      26             : #include "src/runtime-profiler.h"
      27             : #include "src/snapshot/natives.h"
      28             : #include "src/trap-handler/trap-handler.h"
      29             : #include "src/wasm/memory-tracing.h"
      30             : #include "src/wasm/module-compiler.h"
      31             : #include "src/wasm/wasm-engine.h"
      32             : #include "src/wasm/wasm-module.h"
      33             : #include "src/wasm/wasm-objects-inl.h"
      34             : #include "src/wasm/wasm-serialization.h"
      35             : 
      36             : namespace v8 {
      37             : namespace internal {
      38             : 
      39             : namespace {
      40           8 : struct WasmCompileControls {
      41             :   uint32_t MaxWasmBufferSize = std::numeric_limits<uint32_t>::max();
      42             :   bool AllowAnySizeForAsync = true;
      43             : };
      44             : using WasmCompileControlsMap = std::map<v8::Isolate*, WasmCompileControls>;
      45             : 
      46             : // We need per-isolate controls, because we sometimes run tests in multiple
      47             : // isolates concurrently. Methods need to hold the accompanying mutex on access.
      48             : // To avoid upsetting the static initializer count, we lazy initialize this.
      49         100 : DEFINE_LAZY_LEAKY_OBJECT_GETTER(WasmCompileControlsMap,
      50             :                                 GetPerIsolateWasmControls)
      51             : base::LazyMutex g_PerIsolateWasmControlsMutex = LAZY_MUTEX_INITIALIZER;
      52             : 
      53          24 : bool IsWasmCompileAllowed(v8::Isolate* isolate, v8::Local<v8::Value> value,
      54             :                           bool is_async) {
      55             :   base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer());
      56             :   DCHECK_GT(GetPerIsolateWasmControls()->count(isolate), 0);
      57          24 :   const WasmCompileControls& ctrls = GetPerIsolateWasmControls()->at(isolate);
      58          24 :   return (is_async && ctrls.AllowAnySizeForAsync) ||
      59          24 :          (value->IsArrayBuffer() &&
      60           0 :           v8::Local<v8::ArrayBuffer>::Cast(value)->ByteLength() <=
      61          48 :               ctrls.MaxWasmBufferSize) ||
      62          48 :          (value->IsArrayBufferView() &&
      63          48 :           v8::Local<v8::ArrayBufferView>::Cast(value)->ByteLength() <=
      64          48 :               ctrls.MaxWasmBufferSize);
      65             : }
      66             : 
      67             : // Use the compile controls for instantiation, too
      68          20 : bool IsWasmInstantiateAllowed(v8::Isolate* isolate,
      69             :                               v8::Local<v8::Value> module_or_bytes,
      70             :                               bool is_async) {
      71             :   base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer());
      72             :   DCHECK_GT(GetPerIsolateWasmControls()->count(isolate), 0);
      73          20 :   const WasmCompileControls& ctrls = GetPerIsolateWasmControls()->at(isolate);
      74          20 :   if (is_async && ctrls.AllowAnySizeForAsync) return true;
      75          20 :   if (!module_or_bytes->IsWebAssemblyCompiledModule()) {
      76           0 :     return IsWasmCompileAllowed(isolate, module_or_bytes, is_async);
      77             :   }
      78             :   v8::Local<v8::WasmModuleObject> module =
      79             :       v8::Local<v8::WasmModuleObject>::Cast(module_or_bytes);
      80             :   return static_cast<uint32_t>(
      81          60 :              module->GetCompiledModule().GetWireBytesRef().size()) <=
      82          20 :          ctrls.MaxWasmBufferSize;
      83             : }
      84             : 
      85          16 : v8::Local<v8::Value> NewRangeException(v8::Isolate* isolate,
      86             :                                        const char* message) {
      87             :   return v8::Exception::RangeError(
      88          16 :       v8::String::NewFromOneByte(isolate,
      89             :                                  reinterpret_cast<const uint8_t*>(message),
      90             :                                  v8::NewStringType::kNormal)
      91          16 :           .ToLocalChecked());
      92             : }
      93             : 
      94          16 : void ThrowRangeException(v8::Isolate* isolate, const char* message) {
      95          16 :   isolate->ThrowException(NewRangeException(isolate, message));
      96          16 : }
      97             : 
      98          24 : bool WasmModuleOverride(const v8::FunctionCallbackInfo<v8::Value>& args) {
      99          24 :   if (IsWasmCompileAllowed(args.GetIsolate(), args[0], false)) return false;
     100           8 :   ThrowRangeException(args.GetIsolate(), "Sync compile not allowed");
     101           8 :   return true;
     102             : }
     103             : 
     104          20 : bool WasmInstanceOverride(const v8::FunctionCallbackInfo<v8::Value>& args) {
     105          20 :   if (IsWasmInstantiateAllowed(args.GetIsolate(), args[0], false)) return false;
     106           8 :   ThrowRangeException(args.GetIsolate(), "Sync instantiate not allowed");
     107           8 :   return true;
     108             : }
     109             : 
     110             : }  // namespace
     111             : 
     112           0 : RUNTIME_FUNCTION(Runtime_ClearMegamorphicStubCache) {
     113             :   HandleScope scope(isolate);
     114             :   DCHECK_EQ(0, args.length());
     115           0 :   isolate->load_stub_cache()->Clear();
     116           0 :   isolate->store_stub_cache()->Clear();
     117             :   return ReadOnlyRoots(isolate).undefined_value();
     118             : }
     119             : 
     120         936 : RUNTIME_FUNCTION(Runtime_ConstructDouble) {
     121             :   HandleScope scope(isolate);
     122             :   DCHECK_EQ(2, args.length());
     123         936 :   CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
     124         936 :   CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
     125         468 :   uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
     126         936 :   return *isolate->factory()->NewNumber(uint64_to_double(result));
     127             : }
     128             : 
     129          18 : RUNTIME_FUNCTION(Runtime_ConstructConsString) {
     130             :   HandleScope scope(isolate);
     131             :   DCHECK_EQ(2, args.length());
     132           9 :   CONVERT_ARG_HANDLE_CHECKED(String, left, 0);
     133           9 :   CONVERT_ARG_HANDLE_CHECKED(String, right, 1);
     134             : 
     135           9 :   CHECK(left->IsOneByteRepresentation());
     136           9 :   CHECK(right->IsOneByteRepresentation());
     137             : 
     138             :   const bool kIsOneByte = true;
     139           9 :   const int length = left->length() + right->length();
     140          18 :   return *isolate->factory()->NewConsString(left, right, length, kIsOneByte);
     141             : }
     142             : 
     143          18 : RUNTIME_FUNCTION(Runtime_ConstructSlicedString) {
     144             :   HandleScope scope(isolate);
     145             :   DCHECK_EQ(2, args.length());
     146           9 :   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
     147           9 :   CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
     148             : 
     149           9 :   CHECK(string->IsOneByteRepresentation());
     150           9 :   CHECK_LT(index->value(), string->length());
     151             : 
     152             :   Handle<String> sliced_string = isolate->factory()->NewSubString(
     153           9 :       string, index->value(), string->length());
     154           9 :   CHECK(sliced_string->IsSlicedString());
     155             :   return *sliced_string;
     156             : }
     157             : 
     158      116554 : RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
     159             :   HandleScope scope(isolate);
     160             :   DCHECK_EQ(1, args.length());
     161             : 
     162             :   // This function is used by fuzzers to get coverage in compiler.
     163             :   // Ignore calls on non-function objects to avoid runtime errors.
     164             :   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
     165       58277 :   if (!function_object->IsJSFunction()) {
     166             :     return ReadOnlyRoots(isolate).undefined_value();
     167             :   }
     168       58277 :   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
     169             : 
     170             :   // If the function is not optimized, just return.
     171       58277 :   if (!function->IsOptimized()) return ReadOnlyRoots(isolate).undefined_value();
     172             : 
     173       14881 :   Deoptimizer::DeoptimizeFunction(*function);
     174             : 
     175             :   return ReadOnlyRoots(isolate).undefined_value();
     176             : }
     177             : 
     178        8330 : RUNTIME_FUNCTION(Runtime_DeoptimizeNow) {
     179             :   HandleScope scope(isolate);
     180             :   DCHECK_EQ(0, args.length());
     181             : 
     182             :   Handle<JSFunction> function;
     183             : 
     184             :   // Find the JavaScript function on the top of the stack.
     185        4165 :   JavaScriptFrameIterator it(isolate);
     186        4165 :   if (!it.done()) function = handle(it.frame()->function(), isolate);
     187        4165 :   if (function.is_null()) return ReadOnlyRoots(isolate).undefined_value();
     188             : 
     189             :   // If the function is not optimized, just return.
     190        4165 :   if (!function->IsOptimized()) return ReadOnlyRoots(isolate).undefined_value();
     191             : 
     192         639 :   Deoptimizer::DeoptimizeFunction(*function);
     193             : 
     194             :   return ReadOnlyRoots(isolate).undefined_value();
     195             : }
     196             : 
     197          18 : RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
     198             :   SealHandleScope shs(isolate);
     199             :   DCHECK_EQ(0, args.length());
     200             : #if defined(USE_SIMULATOR)
     201             :   return ReadOnlyRoots(isolate).true_value();
     202             : #else
     203             :   return ReadOnlyRoots(isolate).false_value();
     204             : #endif
     205             : }
     206             : 
     207          70 : RUNTIME_FUNCTION(Runtime_ICsAreEnabled) {
     208             :   SealHandleScope shs(isolate);
     209             :   DCHECK_EQ(0, args.length());
     210          35 :   return isolate->heap()->ToBoolean(FLAG_use_ic);
     211             : }
     212             : 
     213          94 : RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
     214             :   SealHandleScope shs(isolate);
     215             :   DCHECK_EQ(0, args.length());
     216             :   return isolate->heap()->ToBoolean(
     217             :       isolate->concurrent_recompilation_enabled());
     218             : }
     219             : 
     220      566922 : RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
     221             :   HandleScope scope(isolate);
     222             : 
     223             :   // This function is used by fuzzers, ignore calls with bogus arguments count.
     224      283461 :   if (args.length() != 1 && args.length() != 2) {
     225             :     return ReadOnlyRoots(isolate).undefined_value();
     226             :   }
     227             : 
     228             :   // This function is used by fuzzers to get coverage for optimizations
     229             :   // in compiler. Ignore calls on non-function objects to avoid runtime errors.
     230             :   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
     231      283461 :   if (!function_object->IsJSFunction()) {
     232             :     return ReadOnlyRoots(isolate).undefined_value();
     233             :   }
     234      283461 :   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
     235             : 
     236             :   // Check we called PrepareFunctionForOptimization and hold the bytecode
     237             :   // array to prevent it from getting flushed.
     238             :   // TODO(mythria): Enable this check once we add PrepareForOptimization in all
     239             :   // tests before calling OptimizeFunctionOnNextCall.
     240             :   // CHECK(!ObjectHashTable::cast(
     241             :   //          isolate->heap()->pending_optimize_for_test_bytecode())
     242             :   //          ->Lookup(handle(function->shared(), isolate))
     243             :   //          ->IsTheHole());
     244             : 
     245             :   // The following conditions were lifted (in part) from the DCHECK inside
     246             :   // JSFunction::MarkForOptimization().
     247             : 
     248      566922 :   if (!function->shared()->allows_lazy_compilation()) {
     249             :     return ReadOnlyRoots(isolate).undefined_value();
     250             :   }
     251             : 
     252             :   // If function isn't compiled, compile it now.
     253      283409 :   IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
     254      284265 :   if (!is_compiled_scope.is_compiled() &&
     255         856 :       !Compiler::Compile(function, Compiler::CLEAR_EXCEPTION,
     256             :                          &is_compiled_scope)) {
     257             :     return ReadOnlyRoots(isolate).undefined_value();
     258             :   }
     259             : 
     260      857218 :   if (function->shared()->optimization_disabled() &&
     261      290810 :       function->shared()->disable_optimization_reason() ==
     262             :           BailoutReason::kNeverOptimize) {
     263             :     return ReadOnlyRoots(isolate).undefined_value();
     264             :   }
     265             : 
     266             :   // If the function is already optimized, just return.
     267      528543 :   if (function->IsOptimized() || function->shared()->HasAsmWasmData()) {
     268             :     return ReadOnlyRoots(isolate).undefined_value();
     269             :   }
     270             : 
     271             :   // If the function has optimized code, ensure that we check for it and return.
     272      245339 :   if (function->HasOptimizedCode()) {
     273             :     DCHECK(function->ChecksOptimizationMarker());
     274             :     return ReadOnlyRoots(isolate).undefined_value();
     275             :   }
     276             : 
     277             :   ConcurrencyMode concurrency_mode = ConcurrencyMode::kNotConcurrent;
     278      245315 :   if (args.length() == 2) {
     279             :     // Ignore invalid inputs produced by fuzzers.
     280             :     CONVERT_ARG_HANDLE_CHECKED(Object, type, 1);
     281         105 :     if (!type->IsString()) {
     282             :       return ReadOnlyRoots(isolate).undefined_value();
     283             :     }
     284         315 :     if (Handle<String>::cast(type)->IsOneByteEqualTo(
     285         105 :             StaticCharVector("concurrent")) &&
     286             :         isolate->concurrent_recompilation_enabled()) {
     287             :       concurrency_mode = ConcurrencyMode::kConcurrent;
     288             :     }
     289             :   }
     290      245315 :   if (FLAG_trace_opt) {
     291         672 :     PrintF("[manually marking ");
     292        1344 :     function->ShortPrint();
     293         672 :     PrintF(" for %s optimization]\n",
     294             :            concurrency_mode == ConcurrencyMode::kConcurrent ? "concurrent"
     295         672 :                                                             : "non-concurrent");
     296             :   }
     297             : 
     298             :   // This function may not have been lazily compiled yet, even though its shared
     299             :   // function has.
     300      245315 :   if (!function->is_compiled()) {
     301             :     DCHECK(function->shared()->IsInterpreted());
     302      140734 :     function->set_code(*BUILTIN_CODE(isolate, InterpreterEntryTrampoline));
     303             :   }
     304             : 
     305      245315 :   JSFunction::EnsureFeedbackVector(function);
     306      245315 :   function->MarkForOptimization(concurrency_mode);
     307             : 
     308             :   return ReadOnlyRoots(isolate).undefined_value();
     309             : }
     310             : 
     311             : namespace {
     312             : 
     313       50114 : bool EnsureFeedbackVector(Handle<JSFunction> function) {
     314             :   // Check function allows lazy compilation.
     315       50114 :   if (!function->shared()->allows_lazy_compilation()) {
     316             :     return false;
     317             :   }
     318             : 
     319             :   // If function isn't compiled, compile it now.
     320       50114 :   IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
     321       59365 :   if (!is_compiled_scope.is_compiled() &&
     322        9251 :       !Compiler::Compile(function, Compiler::CLEAR_EXCEPTION,
     323             :                          &is_compiled_scope)) {
     324             :     return false;
     325             :   }
     326             : 
     327             :   // Ensure function has a feedback vector to hold type feedback for
     328             :   // optimization.
     329       50114 :   JSFunction::EnsureFeedbackVector(function);
     330       50114 :   return true;
     331             : }
     332             : 
     333             : }  // namespace
     334             : 
     335         412 : RUNTIME_FUNCTION(Runtime_EnsureFeedbackVectorForFunction) {
     336             :   HandleScope scope(isolate);
     337             :   DCHECK_EQ(1, args.length());
     338         206 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     339             : 
     340         206 :   EnsureFeedbackVector(function);
     341             :   return ReadOnlyRoots(isolate).undefined_value();
     342             : }
     343             : 
     344       99816 : RUNTIME_FUNCTION(Runtime_PrepareFunctionForOptimization) {
     345             :   HandleScope scope(isolate);
     346             :   DCHECK_EQ(1, args.length());
     347       49908 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     348             : 
     349       49908 :   if (!EnsureFeedbackVector(function)) {
     350             :     return ReadOnlyRoots(isolate).undefined_value();
     351             :   }
     352             : 
     353             :   // If optimization is disabled for the function, return without making it
     354             :   // pending optimize for test.
     355       51706 :   if (function->shared()->optimization_disabled() &&
     356             :       function->shared()->disable_optimization_reason() ==
     357             :           BailoutReason::kNeverOptimize) {
     358             :     return ReadOnlyRoots(isolate).undefined_value();
     359             :   }
     360             : 
     361             :   // If the function is already optimized, return without making it pending
     362             :   // optimize for test.
     363       87565 :   if (function->IsOptimized() || function->shared()->HasAsmWasmData()) {
     364             :     return ReadOnlyRoots(isolate).undefined_value();
     365             :   }
     366             : 
     367             :   // If the function has optimized code, ensure that we check for it and then
     368             :   // return without making it pending optimize for test.
     369       37657 :   if (function->HasOptimizedCode()) {
     370             :     DCHECK(function->ChecksOptimizationMarker());
     371             :     return ReadOnlyRoots(isolate).undefined_value();
     372             :   }
     373             : 
     374             :   // Hold onto the bytecode array between marking and optimization to ensure
     375             :   // it's not flushed.
     376             :   Handle<ObjectHashTable> table =
     377             :       isolate->heap()->pending_optimize_for_test_bytecode()->IsUndefined()
     378             :           ? ObjectHashTable::New(isolate, 1)
     379             :           : handle(ObjectHashTable::cast(
     380             :                        isolate->heap()->pending_optimize_for_test_bytecode()),
     381       37193 :                    isolate);
     382             :   table = ObjectHashTable::Put(
     383             :       table, handle(function->shared(), isolate),
     384       74386 :       handle(function->shared()->GetBytecodeArray(), isolate));
     385             :   isolate->heap()->SetPendingOptimizeForTestBytecode(*table);
     386             : 
     387             :   return ReadOnlyRoots(isolate).undefined_value();
     388             : }
     389             : 
     390       46946 : RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
     391             :   HandleScope scope(isolate);
     392             :   DCHECK(args.length() == 0 || args.length() == 1);
     393             : 
     394             :   Handle<JSFunction> function;
     395             : 
     396             :   // The optional parameter determines the frame being targeted.
     397       23473 :   int stack_depth = args.length() == 1 ? args.smi_at(0) : 0;
     398             : 
     399             :   // Find the JavaScript function on the top of the stack.
     400       23473 :   JavaScriptFrameIterator it(isolate);
     401       23662 :   while (!it.done() && stack_depth--) it.Advance();
     402       23473 :   if (!it.done()) function = handle(it.frame()->function(), isolate);
     403       23473 :   if (function.is_null()) return ReadOnlyRoots(isolate).undefined_value();
     404             : 
     405             :   // If the function is already optimized, just return.
     406       23473 :   if (function->IsOptimized()) return ReadOnlyRoots(isolate).undefined_value();
     407             : 
     408       44284 :   if (function->shared()->optimization_disabled() &&
     409       17750 :       function->shared()->disable_optimization_reason() ==
     410             :           BailoutReason::kNeverOptimize) {
     411             :     return ReadOnlyRoots(isolate).undefined_value();
     412             :   }
     413             : 
     414             :   // Ensure that the function is marked for non-concurrent optimization, so that
     415             :   // subsequent runs don't also optimize.
     416       13267 :   if (!function->HasOptimizedCode()) {
     417       13267 :     if (FLAG_trace_osr) {
     418           0 :       PrintF("[OSR - OptimizeOsr marking ");
     419           0 :       function->ShortPrint();
     420           0 :       PrintF(" for non-concurrent optimization]\n");
     421             :     }
     422       13267 :     function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
     423             :   }
     424             : 
     425             :   // Make the profiler arm all back edges in unoptimized code.
     426       13267 :   if (it.frame()->type() == StackFrame::INTERPRETED) {
     427             :     isolate->runtime_profiler()->AttemptOnStackReplacement(
     428             :         InterpretedFrame::cast(it.frame()),
     429        6605 :         AbstractCode::kMaxLoopNestingMarker);
     430             :   }
     431             : 
     432             :   return ReadOnlyRoots(isolate).undefined_value();
     433             : }
     434             : 
     435             : 
     436        3674 : RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
     437             :   HandleScope scope(isolate);
     438             :   DCHECK_EQ(1, args.length());
     439             :   // This function is used by fuzzers to get coverage for optimizations
     440             :   // in compiler. Ignore calls on non-function objects to avoid runtime errors.
     441             :   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
     442        1837 :   if (!function_object->IsJSFunction()) {
     443             :     return ReadOnlyRoots(isolate).undefined_value();
     444             :   }
     445        1801 :   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
     446        1801 :   function->shared()->DisableOptimization(BailoutReason::kNeverOptimize);
     447             :   return ReadOnlyRoots(isolate).undefined_value();
     448             : }
     449             : 
     450       12016 : RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
     451             :   HandleScope scope(isolate);
     452             :   DCHECK(args.length() == 1 || args.length() == 2);
     453             :   int status = 0;
     454        6008 :   if (FLAG_lite_mode || FLAG_jitless) {
     455             :     // Both jitless and lite modes cannot optimize. Unit tests should handle
     456             :     // these the same way. In the future, the two flags may become synonyms.
     457             :     status |= static_cast<int>(OptimizationStatus::kLiteMode);
     458             :   }
     459        6008 :   if (!isolate->use_optimizer()) {
     460          43 :     status |= static_cast<int>(OptimizationStatus::kNeverOptimize);
     461             :   }
     462        6008 :   if (FLAG_always_opt || FLAG_prepare_always_opt) {
     463        1655 :     status |= static_cast<int>(OptimizationStatus::kAlwaysOptimize);
     464             :   }
     465        6008 :   if (FLAG_deopt_every_n_times) {
     466          24 :     status |= static_cast<int>(OptimizationStatus::kMaybeDeopted);
     467             :   }
     468             : 
     469             :   // This function is used by fuzzers to get coverage for optimizations
     470             :   // in compiler. Ignore calls on non-function objects to avoid runtime errors.
     471             :   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
     472        6008 :   if (!function_object->IsJSFunction()) {
     473             :     return Smi::FromInt(status);
     474             :   }
     475        5979 :   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
     476        5979 :   status |= static_cast<int>(OptimizationStatus::kIsFunction);
     477             : 
     478             :   bool sync_with_compiler_thread = true;
     479        5979 :   if (args.length() == 2) {
     480             :     CONVERT_ARG_HANDLE_CHECKED(Object, sync_object, 1);
     481        5938 :     if (!sync_object->IsString())
     482             :       return ReadOnlyRoots(isolate).undefined_value();
     483        5938 :     Handle<String> sync = Handle<String>::cast(sync_object);
     484       11876 :     if (sync->IsOneByteEqualTo(StaticCharVector("no sync"))) {
     485             :       sync_with_compiler_thread = false;
     486             :     }
     487             :   }
     488             : 
     489        5979 :   if (isolate->concurrent_recompilation_enabled() &&
     490             :       sync_with_compiler_thread) {
     491        6020 :     while (function->IsInOptimizationQueue()) {
     492          86 :       isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
     493          86 :       base::OS::Sleep(base::TimeDelta::FromMilliseconds(50));
     494             :     }
     495             :   }
     496             : 
     497        5979 :   if (function->IsMarkedForOptimization()) {
     498           8 :     status |= static_cast<int>(OptimizationStatus::kMarkedForOptimization);
     499        5971 :   } else if (function->IsInOptimizationQueue()) {
     500             :     status |=
     501          32 :         static_cast<int>(OptimizationStatus::kMarkedForConcurrentOptimization);
     502        5939 :   } else if (function->IsInOptimizationQueue()) {
     503           0 :     status |= static_cast<int>(OptimizationStatus::kOptimizingConcurrently);
     504             :   }
     505             : 
     506        5979 :   if (function->IsOptimized()) {
     507        4873 :     status |= static_cast<int>(OptimizationStatus::kOptimized);
     508        9746 :     if (function->code()->is_turbofanned()) {
     509        4873 :       status |= static_cast<int>(OptimizationStatus::kTurboFanned);
     510             :     }
     511             :   }
     512        5979 :   if (function->IsInterpreted()) {
     513        1098 :     status |= static_cast<int>(OptimizationStatus::kInterpreted);
     514             :   }
     515             : 
     516             :   // Additionally, detect activations of this frame on the stack, and report the
     517             :   // status of the topmost frame.
     518             :   JavaScriptFrame* frame = nullptr;
     519        5979 :   JavaScriptFrameIterator it(isolate);
     520       36541 :   while (!it.done()) {
     521       61152 :     if (it.frame()->function() == *function) {
     522             :       frame = it.frame();
     523             :       break;
     524             :     }
     525       30562 :     it.Advance();
     526             :   }
     527        5979 :   if (frame != nullptr) {
     528          14 :     status |= static_cast<int>(OptimizationStatus::kIsExecuting);
     529          28 :     if (frame->is_optimized()) {
     530             :       status |=
     531          10 :           static_cast<int>(OptimizationStatus::kTopmostFrameIsTurboFanned);
     532             :     }
     533             :   }
     534             : 
     535             :   return Smi::FromInt(status);
     536             : }
     537             : 
     538         148 : RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
     539             :   DCHECK_EQ(0, args.length());
     540          74 :   if (FLAG_block_concurrent_recompilation &&
     541             :       isolate->concurrent_recompilation_enabled()) {
     542          74 :     isolate->optimizing_compile_dispatcher()->Unblock();
     543             :   }
     544             :   return ReadOnlyRoots(isolate).undefined_value();
     545             : }
     546             : 
     547         130 : RUNTIME_FUNCTION(Runtime_GetDeoptCount) {
     548             :   HandleScope scope(isolate);
     549             :   DCHECK_EQ(1, args.length());
     550          65 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     551             :   // Functions without a feedback vector have never deoptimized.
     552          65 :   if (!function->has_feedback_vector()) return Smi::kZero;
     553             :   return Smi::FromInt(function->feedback_vector()->deopt_count());
     554             : }
     555             : 
     556          45 : static void ReturnThis(const v8::FunctionCallbackInfo<v8::Value>& args) {
     557             :   args.GetReturnValue().Set(args.This());
     558          45 : }
     559             : 
     560         238 : RUNTIME_FUNCTION(Runtime_GetUndetectable) {
     561             :   HandleScope scope(isolate);
     562             :   DCHECK_EQ(0, args.length());
     563             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     564             : 
     565         119 :   Local<v8::ObjectTemplate> desc = v8::ObjectTemplate::New(v8_isolate);
     566         119 :   desc->MarkAsUndetectable();
     567         119 :   desc->SetCallAsFunctionHandler(ReturnThis);
     568             :   Local<v8::Object> obj;
     569         238 :   if (!desc->NewInstance(v8_isolate->GetCurrentContext()).ToLocal(&obj)) {
     570             :     return Object();
     571             :   }
     572             :   return *Utils::OpenHandle(*obj);
     573             : }
     574             : 
     575          80 : static void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& args) {
     576             :   double v1 = args[0]
     577         240 :                   ->NumberValue(v8::Isolate::GetCurrent()->GetCurrentContext())
     578             :                   .ToChecked();
     579             :   double v2 = args[1]
     580         240 :                   ->NumberValue(v8::Isolate::GetCurrent()->GetCurrentContext())
     581             :                   .ToChecked();
     582          80 :   args.GetReturnValue().Set(
     583             :       v8::Number::New(v8::Isolate::GetCurrent(), v1 - v2));
     584          80 : }
     585             : 
     586             : // Returns a callable object. The object returns the difference of its two
     587             : // parameters when it is called.
     588          16 : RUNTIME_FUNCTION(Runtime_GetCallable) {
     589             :   HandleScope scope(isolate);
     590             :   DCHECK_EQ(0, args.length());
     591             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     592           8 :   Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(v8_isolate);
     593           8 :   Local<ObjectTemplate> instance_template = t->InstanceTemplate();
     594           8 :   instance_template->SetCallAsFunctionHandler(call_as_function);
     595           8 :   v8_isolate->GetCurrentContext();
     596             :   Local<v8::Object> instance =
     597           8 :       t->GetFunction(v8_isolate->GetCurrentContext())
     598             :           .ToLocalChecked()
     599           8 :           ->NewInstance(v8_isolate->GetCurrentContext())
     600             :           .ToLocalChecked();
     601             :   return *Utils::OpenHandle(*instance);
     602             : }
     603             : 
     604      104796 : RUNTIME_FUNCTION(Runtime_ClearFunctionFeedback) {
     605             :   HandleScope scope(isolate);
     606             :   DCHECK_EQ(1, args.length());
     607       52398 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     608       52398 :   function->ClearTypeFeedbackInfo();
     609             :   return ReadOnlyRoots(isolate).undefined_value();
     610             : }
     611             : 
     612          96 : RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) {
     613             :   HandleScope scope(isolate);
     614          48 :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     615          48 :   CHECK_EQ(args.length(), 2);
     616          48 :   CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0);
     617          48 :   CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1);
     618          48 :   base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer());
     619          48 :   WasmCompileControls& ctrl = (*GetPerIsolateWasmControls())[v8_isolate];
     620          48 :   ctrl.AllowAnySizeForAsync = allow_async;
     621          48 :   ctrl.MaxWasmBufferSize = static_cast<uint32_t>(block_size->value());
     622          48 :   v8_isolate->SetWasmModuleCallback(WasmModuleOverride);
     623             :   return ReadOnlyRoots(isolate).undefined_value();
     624             : }
     625             : 
     626          16 : RUNTIME_FUNCTION(Runtime_SetWasmInstantiateControls) {
     627             :   HandleScope scope(isolate);
     628             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     629           8 :   CHECK_EQ(args.length(), 0);
     630           8 :   v8_isolate->SetWasmInstanceCallback(WasmInstanceOverride);
     631             :   return ReadOnlyRoots(isolate).undefined_value();
     632             : }
     633             : 
     634         108 : RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
     635             :   HandleScope scope(isolate);
     636             :   DCHECK_EQ(0, args.length());
     637          54 :   isolate->heap()->NotifyContextDisposed(true);
     638             :   return ReadOnlyRoots(isolate).undefined_value();
     639             : }
     640             : 
     641             : 
     642         604 : RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
     643             :   SealHandleScope shs(isolate);
     644             :   DCHECK(args.length() == 2 || args.length() == 3);
     645             : #ifdef V8_ENABLE_ALLOCATION_TIMEOUT
     646             :   CONVERT_INT32_ARG_CHECKED(timeout, 1);
     647             :   isolate->heap()->set_allocation_timeout(timeout);
     648             : #endif
     649             : #ifdef DEBUG
     650             :   CONVERT_INT32_ARG_CHECKED(interval, 0);
     651             :   FLAG_gc_interval = interval;
     652             :   if (args.length() == 3) {
     653             :     // Enable/disable inline allocation if requested.
     654             :     CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
     655             :     if (inline_allocation) {
     656             :       isolate->heap()->EnableInlineAllocation();
     657             :     } else {
     658             :       isolate->heap()->DisableInlineAllocation();
     659             :     }
     660             :   }
     661             : #endif
     662             :   return ReadOnlyRoots(isolate).undefined_value();
     663             : }
     664             : 
     665             : 
     666        1556 : RUNTIME_FUNCTION(Runtime_DebugPrint) {
     667             :   SealHandleScope shs(isolate);
     668             :   DCHECK_EQ(1, args.length());
     669             : 
     670         778 :   MaybeObject maybe_object(*args.address_of_arg_at(0));
     671             : 
     672        1556 :   StdoutStream os;
     673         778 :   if (maybe_object->IsCleared()) {
     674           0 :     os << "[weak cleared]";
     675             :   } else {
     676             :     Object object = maybe_object.GetHeapObjectOrSmi();
     677             :     bool weak = maybe_object.IsWeak();
     678             : 
     679             : #ifdef DEBUG
     680             :     if (object->IsString() && !isolate->context().is_null()) {
     681             :       DCHECK(!weak);
     682             :       // If we have a string, assume it's a code "marker"
     683             :       // and print some interesting cpu debugging info.
     684             :       object->Print(os);
     685             :       JavaScriptFrameIterator it(isolate);
     686             :       JavaScriptFrame* frame = it.frame();
     687             :       os << "fp = " << reinterpret_cast<void*>(frame->fp())
     688             :          << ", sp = " << reinterpret_cast<void*>(frame->sp())
     689             :          << ", caller_sp = " << reinterpret_cast<void*>(frame->caller_sp())
     690             :          << ": ";
     691             :     } else {
     692             :       os << "DebugPrint: ";
     693             :       if (weak) {
     694             :         os << "[weak] ";
     695             :       }
     696             :       object->Print(os);
     697             :     }
     698             :     if (object->IsHeapObject()) {
     699             :       HeapObject::cast(object)->map()->Print(os);
     700             :     }
     701             : #else
     702         778 :     if (weak) {
     703           0 :       os << "[weak] ";
     704             :     }
     705             :     // ShortPrint is available in release mode. Print is not.
     706         778 :     os << Brief(object);
     707             : #endif
     708             :   }
     709             :   os << std::endl;
     710             : 
     711             :   return args[0];  // return TOS
     712             : }
     713             : 
     714           0 : RUNTIME_FUNCTION(Runtime_PrintWithNameForAssert) {
     715             :   SealHandleScope shs(isolate);
     716             :   DCHECK_EQ(2, args.length());
     717             : 
     718           0 :   CONVERT_ARG_CHECKED(String, name, 0);
     719             : 
     720           0 :   PrintF(" * ");
     721           0 :   StringCharacterStream stream(name);
     722           0 :   while (stream.HasMore()) {
     723           0 :     uint16_t character = stream.GetNext();
     724           0 :     PrintF("%c", character);
     725             :   }
     726           0 :   PrintF(": ");
     727           0 :   args[1]->ShortPrint();
     728           0 :   PrintF("\n");
     729             : 
     730             :   return ReadOnlyRoots(isolate).undefined_value();
     731             : }
     732             : 
     733          16 : RUNTIME_FUNCTION(Runtime_DebugTrace) {
     734             :   SealHandleScope shs(isolate);
     735             :   DCHECK_EQ(0, args.length());
     736           8 :   isolate->PrintStack(stdout);
     737             :   return ReadOnlyRoots(isolate).undefined_value();
     738             : }
     739             : 
     740           0 : RUNTIME_FUNCTION(Runtime_DebugTrackRetainingPath) {
     741             :   HandleScope scope(isolate);
     742             :   DCHECK_LE(1, args.length());
     743             :   DCHECK_GE(2, args.length());
     744           0 :   if (!FLAG_track_retaining_path) {
     745           0 :     PrintF("DebugTrackRetainingPath requires --track-retaining-path flag.\n");
     746             :   } else {
     747           0 :     CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
     748             :     RetainingPathOption option = RetainingPathOption::kDefault;
     749           0 :     if (args.length() == 2) {
     750           0 :       CONVERT_ARG_HANDLE_CHECKED(String, str, 1);
     751           0 :       const char track_ephemeron_path[] = "track-ephemeron-path";
     752           0 :       if (str->IsOneByteEqualTo(StaticCharVector(track_ephemeron_path))) {
     753             :         option = RetainingPathOption::kTrackEphemeronPath;
     754           0 :       } else if (str->length() != 0) {
     755           0 :         PrintF("Unexpected second argument of DebugTrackRetainingPath.\n");
     756             :         PrintF("Expected an empty string or '%s', got '%s'.\n",
     757           0 :                track_ephemeron_path, str->ToCString().get());
     758             :       }
     759             :     }
     760           0 :     isolate->heap()->AddRetainingPathTarget(object, option);
     761             :   }
     762             :   return ReadOnlyRoots(isolate).undefined_value();
     763             : }
     764             : 
     765             : // This will not allocate (flatten the string), but it may run
     766             : // very slowly for very deeply nested ConsStrings.  For debugging use only.
     767           0 : RUNTIME_FUNCTION(Runtime_GlobalPrint) {
     768             :   SealHandleScope shs(isolate);
     769             :   DCHECK_EQ(1, args.length());
     770             : 
     771           0 :   CONVERT_ARG_CHECKED(String, string, 0);
     772           0 :   StringCharacterStream stream(string);
     773           0 :   while (stream.HasMore()) {
     774           0 :     uint16_t character = stream.GetNext();
     775           0 :     PrintF("%c", character);
     776             :   }
     777             :   return string;
     778             : }
     779             : 
     780             : 
     781           0 : RUNTIME_FUNCTION(Runtime_SystemBreak) {
     782             :   // The code below doesn't create handles, but when breaking here in GDB
     783             :   // having a handle scope might be useful.
     784             :   HandleScope scope(isolate);
     785             :   DCHECK_EQ(0, args.length());
     786           0 :   base::OS::DebugBreak();
     787             :   return ReadOnlyRoots(isolate).undefined_value();
     788             : }
     789             : 
     790             : 
     791          84 : RUNTIME_FUNCTION(Runtime_SetForceSlowPath) {
     792             :   SealHandleScope shs(isolate);
     793             :   DCHECK_EQ(1, args.length());
     794             :   CONVERT_ARG_CHECKED(Object, arg, 0);
     795          42 :   if (arg->IsTrue(isolate)) {
     796             :     isolate->set_force_slow_path(true);
     797             :   } else {
     798             :     DCHECK(arg->IsFalse(isolate));
     799             :     isolate->set_force_slow_path(false);
     800             :   }
     801             :   return ReadOnlyRoots(isolate).undefined_value();
     802             : }
     803             : 
     804           0 : RUNTIME_FUNCTION(Runtime_Abort) {
     805             :   SealHandleScope shs(isolate);
     806             :   DCHECK_EQ(1, args.length());
     807           0 :   CONVERT_SMI_ARG_CHECKED(message_id, 0);
     808           0 :   const char* message = GetAbortReason(static_cast<AbortReason>(message_id));
     809           0 :   base::OS::PrintError("abort: %s\n", message);
     810           0 :   isolate->PrintStack(stderr);
     811           0 :   base::OS::Abort();
     812             :   UNREACHABLE();
     813             : }
     814             : 
     815             : 
     816           0 : RUNTIME_FUNCTION(Runtime_AbortJS) {
     817             :   HandleScope scope(isolate);
     818             :   DCHECK_EQ(1, args.length());
     819           0 :   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
     820           0 :   if (FLAG_disable_abortjs) {
     821           0 :     base::OS::PrintError("[disabled] abort: %s\n", message->ToCString().get());
     822             :     return Object();
     823             :   }
     824           0 :   base::OS::PrintError("abort: %s\n", message->ToCString().get());
     825           0 :   isolate->PrintStack(stderr);
     826           0 :   base::OS::Abort();
     827             :   UNREACHABLE();
     828             : }
     829             : 
     830             : 
     831          36 : RUNTIME_FUNCTION(Runtime_DisassembleFunction) {
     832             :   HandleScope scope(isolate);
     833             : #ifdef DEBUG
     834             :   DCHECK_EQ(1, args.length());
     835             :   // Get the function and make sure it is compiled.
     836             :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
     837             :   IsCompiledScope is_compiled_scope;
     838             :   if (!func->is_compiled() &&
     839             :       !Compiler::Compile(func, Compiler::KEEP_EXCEPTION, &is_compiled_scope)) {
     840             :     return ReadOnlyRoots(isolate).exception();
     841             :   }
     842             :   StdoutStream os;
     843             :   func->code()->Print(os);
     844             :   os << std::endl;
     845             : #endif  // DEBUG
     846             :   return ReadOnlyRoots(isolate).undefined_value();
     847             : }
     848             : 
     849             : namespace {
     850             : 
     851           0 : int StackSize(Isolate* isolate) {
     852             :   int n = 0;
     853           0 :   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
     854           0 :   return n;
     855             : }
     856             : 
     857           0 : void PrintIndentation(Isolate* isolate) {
     858             :   const int nmax = 80;
     859           0 :   int n = StackSize(isolate);
     860           0 :   if (n <= nmax) {
     861           0 :     PrintF("%4d:%*s", n, n, "");
     862             :   } else {
     863           0 :     PrintF("%4d:%*s", n, nmax, "...");
     864             :   }
     865           0 : }
     866             : 
     867             : }  // namespace
     868             : 
     869           0 : RUNTIME_FUNCTION(Runtime_TraceEnter) {
     870             :   SealHandleScope shs(isolate);
     871             :   DCHECK_EQ(0, args.length());
     872           0 :   PrintIndentation(isolate);
     873           0 :   JavaScriptFrame::PrintTop(isolate, stdout, true, false);
     874           0 :   PrintF(" {\n");
     875             :   return ReadOnlyRoots(isolate).undefined_value();
     876             : }
     877             : 
     878             : 
     879           0 : RUNTIME_FUNCTION(Runtime_TraceExit) {
     880             :   SealHandleScope shs(isolate);
     881             :   DCHECK_EQ(1, args.length());
     882           0 :   CONVERT_ARG_CHECKED(Object, obj, 0);
     883           0 :   PrintIndentation(isolate);
     884           0 :   PrintF("} -> ");
     885           0 :   obj->ShortPrint();
     886           0 :   PrintF("\n");
     887           0 :   return obj;  // return TOS
     888             : }
     889             : 
     890        3574 : RUNTIME_FUNCTION(Runtime_HaveSameMap) {
     891             :   SealHandleScope shs(isolate);
     892             :   DCHECK_EQ(2, args.length());
     893        3574 :   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
     894        3574 :   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
     895        3574 :   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
     896             : }
     897             : 
     898             : 
     899         152 : RUNTIME_FUNCTION(Runtime_InNewSpace) {
     900             :   SealHandleScope shs(isolate);
     901             :   DCHECK_EQ(1, args.length());
     902             :   CONVERT_ARG_CHECKED(Object, obj, 0);
     903             :   return isolate->heap()->ToBoolean(ObjectInYoungGeneration(obj));
     904             : }
     905             : 
     906        8444 : RUNTIME_FUNCTION(Runtime_IsAsmWasmCode) {
     907             :   SealHandleScope shs(isolate);
     908             :   DCHECK_EQ(1, args.length());
     909        8444 :   CONVERT_ARG_CHECKED(JSFunction, function, 0);
     910        4222 :   if (!function->shared()->HasAsmWasmData()) {
     911             :     // Doesn't have wasm data.
     912             :     return ReadOnlyRoots(isolate).false_value();
     913             :   }
     914        6060 :   if (function->shared()->HasBuiltinId() &&
     915        3030 :       function->shared()->builtin_id() == Builtins::kInstantiateAsmJs) {
     916             :     // Hasn't been compiled yet.
     917             :     return ReadOnlyRoots(isolate).false_value();
     918             :   }
     919             :   return ReadOnlyRoots(isolate).true_value();
     920             : }
     921             : 
     922             : namespace {
     923          72 : bool DisallowCodegenFromStringsCallback(v8::Local<v8::Context> context,
     924             :                                         v8::Local<v8::String> source) {
     925          72 :   return false;
     926             : }
     927             : }
     928             : 
     929         288 : RUNTIME_FUNCTION(Runtime_DisallowCodegenFromStrings) {
     930             :   SealHandleScope shs(isolate);
     931             :   DCHECK_EQ(1, args.length());
     932         144 :   CONVERT_BOOLEAN_ARG_CHECKED(flag, 0);
     933             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     934         144 :   v8_isolate->SetAllowCodeGenerationFromStringsCallback(
     935         144 :       flag ? DisallowCodegenFromStringsCallback : nullptr);
     936             :   return ReadOnlyRoots(isolate).undefined_value();
     937             : }
     938             : 
     939         272 : RUNTIME_FUNCTION(Runtime_DisallowWasmCodegen) {
     940             :   SealHandleScope shs(isolate);
     941             :   DCHECK_EQ(1, args.length());
     942         136 :   CONVERT_BOOLEAN_ARG_CHECKED(flag, 0);
     943             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     944         136 :   v8_isolate->SetAllowWasmCodeGenerationCallback(
     945         136 :       flag ? DisallowCodegenFromStringsCallback : nullptr);
     946             :   return ReadOnlyRoots(isolate).undefined_value();
     947             : }
     948             : 
     949          80 : RUNTIME_FUNCTION(Runtime_IsWasmCode) {
     950             :   SealHandleScope shs(isolate);
     951             :   DCHECK_EQ(1, args.length());
     952          80 :   CONVERT_ARG_CHECKED(JSFunction, function, 0);
     953          80 :   bool is_js_to_wasm = function->code()->kind() == Code::JS_TO_WASM_FUNCTION;
     954             :   return isolate->heap()->ToBoolean(is_js_to_wasm);
     955             : }
     956             : 
     957       16064 : RUNTIME_FUNCTION(Runtime_IsWasmTrapHandlerEnabled) {
     958             :   DisallowHeapAllocation no_gc;
     959             :   DCHECK_EQ(0, args.length());
     960             :   return isolate->heap()->ToBoolean(trap_handler::IsTrapHandlerEnabled());
     961             : }
     962             : 
     963        1616 : RUNTIME_FUNCTION(Runtime_IsThreadInWasm) {
     964             :   DisallowHeapAllocation no_gc;
     965             :   DCHECK_EQ(0, args.length());
     966             :   return isolate->heap()->ToBoolean(trap_handler::IsThreadInWasm());
     967             : }
     968             : 
     969       32064 : RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) {
     970             :   HandleScope scope(isolate);
     971             :   DCHECK_EQ(0, args.length());
     972       16032 :   size_t trap_count = trap_handler::GetRecoveredTrapCount();
     973       32064 :   return *isolate->factory()->NewNumberFromSize(trap_count);
     974             : }
     975             : 
     976         832 : RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) {
     977             :   HandleScope scope(isolate);
     978             :   DCHECK_EQ(2, args.length());
     979         416 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0);
     980         416 :   CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 1);
     981             :   Handle<Object> tag =
     982         416 :       WasmExceptionPackage::GetExceptionTag(isolate, exception);
     983         416 :   if (tag->IsWasmExceptionTag()) {
     984             :     Handle<FixedArray> exceptions_table(instance->exceptions_table(), isolate);
     985         576 :     for (int index = 0; index < exceptions_table->length(); ++index) {
     986         496 :       if (exceptions_table->get(index) == *tag) return Smi::FromInt(index);
     987             :     }
     988             :   }
     989             :   return ReadOnlyRoots(isolate).undefined_value();
     990             : }
     991             : 
     992         800 : RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) {
     993             :   HandleScope scope(isolate);
     994             :   DCHECK_EQ(1, args.length());
     995         400 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0);
     996             :   Handle<Object> values_obj =
     997         400 :       WasmExceptionPackage::GetExceptionValues(isolate, exception);
     998         400 :   CHECK(values_obj->IsFixedArray());  // Only called with correct input.
     999         400 :   Handle<FixedArray> values = Handle<FixedArray>::cast(values_obj);
    1000             :   return *isolate->factory()->NewJSArrayWithElements(values);
    1001             : }
    1002             : 
    1003             : namespace {
    1004          16 : bool EnableWasmThreads(v8::Local<v8::Context> context) { return true; }
    1005             : 
    1006          16 : bool DisableWasmThreads(v8::Local<v8::Context> context) { return false; }
    1007             : }  // namespace
    1008             : 
    1009             : // This runtime function enables WebAssembly threads through an embedder
    1010             : // callback and thereby bypasses the value in FLAG_experimental_wasm_threads.
    1011          48 : RUNTIME_FUNCTION(Runtime_SetWasmThreadsEnabled) {
    1012             :   DCHECK_EQ(1, args.length());
    1013          24 :   CONVERT_BOOLEAN_ARG_CHECKED(flag, 0);
    1014             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
    1015          24 :   v8_isolate->SetWasmThreadsEnabledCallback(flag ? EnableWasmThreads
    1016          24 :                                                  : DisableWasmThreads);
    1017             :   return ReadOnlyRoots(isolate).undefined_value();
    1018             : }
    1019             : 
    1020             : #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)       \
    1021             :   RUNTIME_FUNCTION(Runtime_Has##Name) {                  \
    1022             :     CONVERT_ARG_CHECKED(JSObject, obj, 0);               \
    1023             :     return isolate->heap()->ToBoolean(obj->Has##Name()); \
    1024             :   }
    1025             : 
    1026         252 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
    1027     3608776 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SmiElements)
    1028     5409056 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ObjectElements)
    1029     5400000 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SmiOrObjectElements)
    1030     5412188 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DoubleElements)
    1031    19806760 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HoleyElements)
    1032        2452 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
    1033         420 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(PackedElements)
    1034         252 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
    1035             : // Properties test sitting with elements tests - not fooling anyone.
    1036       34556 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
    1037             : 
    1038             : #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
    1039             : 
    1040             : #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype) \
    1041             :   RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                     \
    1042             :     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                 \
    1043             :     return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());    \
    1044             :   }
    1045             : 
    1046        1800 : TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
    1047             : 
    1048             : #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
    1049             : 
    1050         344 : RUNTIME_FUNCTION(Runtime_ArraySpeciesProtector) {
    1051             :   SealHandleScope shs(isolate);
    1052             :   DCHECK_EQ(0, args.length());
    1053             :   return isolate->heap()->ToBoolean(isolate->IsArraySpeciesLookupChainIntact());
    1054             : }
    1055             : 
    1056         400 : RUNTIME_FUNCTION(Runtime_MapIteratorProtector) {
    1057             :   SealHandleScope shs(isolate);
    1058             :   DCHECK_EQ(0, args.length());
    1059             :   return isolate->heap()->ToBoolean(isolate->IsMapIteratorLookupChainIntact());
    1060             : }
    1061             : 
    1062         400 : RUNTIME_FUNCTION(Runtime_SetIteratorProtector) {
    1063             :   SealHandleScope shs(isolate);
    1064             :   DCHECK_EQ(0, args.length());
    1065             :   return isolate->heap()->ToBoolean(isolate->IsSetIteratorLookupChainIntact());
    1066             : }
    1067             : 
    1068         208 : RUNTIME_FUNCTION(Runtime_StringIteratorProtector) {
    1069             :   SealHandleScope shs(isolate);
    1070             :   DCHECK_EQ(0, args.length());
    1071             :   return isolate->heap()->ToBoolean(
    1072             :       isolate->IsStringIteratorLookupChainIntact());
    1073             : }
    1074             : 
    1075             : // Take a compiled wasm module and serialize it into an array buffer, which is
    1076             : // then returned.
    1077         336 : RUNTIME_FUNCTION(Runtime_SerializeWasmModule) {
    1078             :   HandleScope scope(isolate);
    1079             :   DCHECK_EQ(1, args.length());
    1080         168 :   CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
    1081             : 
    1082         168 :   wasm::NativeModule* native_module = module_obj->native_module();
    1083         336 :   wasm::WasmSerializer wasm_serializer(native_module);
    1084         168 :   size_t compiled_size = wasm_serializer.GetSerializedNativeModuleSize();
    1085         168 :   void* array_data = isolate->array_buffer_allocator()->Allocate(compiled_size);
    1086             :   Handle<JSArrayBuffer> array_buffer =
    1087         168 :       isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared);
    1088         168 :   JSArrayBuffer::Setup(array_buffer, isolate, false, array_data, compiled_size);
    1089         336 :   if (!array_data ||
    1090         168 :       !wasm_serializer.SerializeNativeModule(
    1091             :           {reinterpret_cast<uint8_t*>(array_data), compiled_size})) {
    1092             :     return ReadOnlyRoots(isolate).undefined_value();
    1093             :   }
    1094             :   return *array_buffer;
    1095             : }
    1096             : 
    1097             : // Take an array buffer and attempt to reconstruct a compiled wasm module.
    1098             : // Return undefined if unsuccessful.
    1099         352 : RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
    1100             :   HandleScope scope(isolate);
    1101             :   DCHECK_EQ(2, args.length());
    1102         176 :   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0);
    1103         176 :   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, wire_bytes, 1);
    1104         176 :   CHECK(!buffer->was_detached());
    1105         176 :   CHECK(!wire_bytes->WasDetached());
    1106             : 
    1107         176 :   Handle<JSArrayBuffer> wire_bytes_buffer = wire_bytes->GetBuffer();
    1108             :   Vector<const uint8_t> wire_bytes_vec{
    1109             :       reinterpret_cast<const uint8_t*>(wire_bytes_buffer->backing_store()) +
    1110             :           wire_bytes->byte_offset(),
    1111         176 :       wire_bytes->byte_length()};
    1112             :   Vector<uint8_t> buffer_vec{
    1113             :       reinterpret_cast<uint8_t*>(buffer->backing_store()),
    1114             :       buffer->byte_length()};
    1115             : 
    1116             :   // Note that {wasm::DeserializeNativeModule} will allocate. We assume the
    1117             :   // JSArrayBuffer backing store doesn't get relocated.
    1118             :   MaybeHandle<WasmModuleObject> maybe_module_object =
    1119         176 :       wasm::DeserializeNativeModule(isolate, buffer_vec, wire_bytes_vec);
    1120             :   Handle<WasmModuleObject> module_object;
    1121         176 :   if (!maybe_module_object.ToHandle(&module_object)) {
    1122             :     return ReadOnlyRoots(isolate).undefined_value();
    1123             :   }
    1124             :   return *module_object;
    1125             : }
    1126             : 
    1127       17658 : RUNTIME_FUNCTION(Runtime_HeapObjectVerify) {
    1128             :   HandleScope shs(isolate);
    1129             :   DCHECK_EQ(1, args.length());
    1130             :   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    1131             : #ifdef VERIFY_HEAP
    1132             :   object->ObjectVerify(isolate);
    1133             : #else
    1134             :   CHECK(object->IsObject());
    1135        8829 :   if (object->IsHeapObject()) {
    1136       17604 :     CHECK(HeapObject::cast(*object)->map()->IsMap());
    1137             :   } else {
    1138          27 :     CHECK(object->IsSmi());
    1139             :   }
    1140             : #endif
    1141             :   return isolate->heap()->ToBoolean(true);
    1142             : }
    1143             : 
    1144         112 : RUNTIME_FUNCTION(Runtime_WasmGetNumberOfInstances) {
    1145             :   SealHandleScope shs(isolate);
    1146             :   DCHECK_EQ(1, args.length());
    1147          56 :   CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
    1148             :   int instance_count = 0;
    1149          56 :   WeakArrayList weak_instance_list = module_obj->weak_instance_list();
    1150         296 :   for (int i = 0; i < weak_instance_list->length(); ++i) {
    1151         240 :     if (weak_instance_list->Get(i)->IsWeak()) instance_count++;
    1152             :   }
    1153             :   return Smi::FromInt(instance_count);
    1154             : }
    1155             : 
    1156         960 : RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) {
    1157             :   DCHECK_EQ(1, args.length());
    1158             :   HandleScope scope(isolate);
    1159         480 :   CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
    1160         480 :   if (!instance->has_debug_info()) return Object();
    1161         280 :   uint64_t num = instance->debug_info()->NumInterpretedCalls();
    1162         560 :   return *isolate->factory()->NewNumberFromSize(static_cast<size_t>(num));
    1163             : }
    1164             : 
    1165         208 : RUNTIME_FUNCTION(Runtime_RedirectToWasmInterpreter) {
    1166             :   DCHECK_EQ(2, args.length());
    1167             :   HandleScope scope(isolate);
    1168         104 :   CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
    1169         208 :   CONVERT_SMI_ARG_CHECKED(function_index, 1);
    1170             :   Handle<WasmDebugInfo> debug_info =
    1171         104 :       WasmInstanceObject::GetOrCreateDebugInfo(instance);
    1172         208 :   WasmDebugInfo::RedirectToInterpreter(debug_info,
    1173         104 :                                        Vector<int>(&function_index, 1));
    1174             :   return ReadOnlyRoots(isolate).undefined_value();
    1175             : }
    1176             : 
    1177         144 : RUNTIME_FUNCTION(Runtime_WasmTraceMemory) {
    1178             :   HandleScope scope(isolate);
    1179             :   DCHECK_EQ(1, args.length());
    1180          72 :   CONVERT_ARG_CHECKED(Smi, info_addr, 0);
    1181             : 
    1182             :   wasm::MemoryTracingInfo* info =
    1183          72 :       reinterpret_cast<wasm::MemoryTracingInfo*>(info_addr.ptr());
    1184             : 
    1185             :   // Find the caller wasm frame.
    1186         144 :   wasm::WasmCodeRefScope wasm_code_ref_scope;
    1187          72 :   StackTraceFrameIterator it(isolate);
    1188             :   DCHECK(!it.done());
    1189             :   DCHECK(it.is_wasm());
    1190             :   WasmCompiledFrame* frame = WasmCompiledFrame::cast(it.frame());
    1191             : 
    1192             :   uint8_t* mem_start = reinterpret_cast<uint8_t*>(
    1193         144 :       frame->wasm_instance()->memory_object()->array_buffer()->backing_store());
    1194          72 :   int func_index = frame->function_index();
    1195          72 :   int pos = frame->position();
    1196             :   // TODO(titzer): eliminate dependency on WasmModule definition here.
    1197             :   int func_start =
    1198          72 :       frame->wasm_instance()->module()->functions[func_index].code.offset();
    1199          72 :   wasm::ExecutionTier tier = frame->wasm_code()->is_liftoff()
    1200             :                                  ? wasm::ExecutionTier::kLiftoff
    1201          72 :                                  : wasm::ExecutionTier::kTurbofan;
    1202          72 :   wasm::TraceMemoryOperation(tier, info, func_index, pos - func_start,
    1203          72 :                              mem_start);
    1204             :   return ReadOnlyRoots(isolate).undefined_value();
    1205             : }
    1206             : 
    1207          32 : RUNTIME_FUNCTION(Runtime_WasmTierUpFunction) {
    1208             :   HandleScope scope(isolate);
    1209             :   DCHECK_EQ(2, args.length());
    1210          16 :   CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
    1211          16 :   CONVERT_SMI_ARG_CHECKED(function_index, 1);
    1212          16 :   auto* native_module = instance->module_object()->native_module();
    1213          16 :   isolate->wasm_engine()->CompileFunction(
    1214          16 :       isolate, native_module, function_index, wasm::ExecutionTier::kTurbofan);
    1215          16 :   CHECK(!native_module->compilation_state()->failed());
    1216             :   return ReadOnlyRoots(isolate).undefined_value();
    1217             : }
    1218             : 
    1219         224 : RUNTIME_FUNCTION(Runtime_IsLiftoffFunction) {
    1220             :   HandleScope scope(isolate);
    1221             :   DCHECK_EQ(1, args.length());
    1222         112 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
    1223         112 :   CHECK(WasmExportedFunction::IsWasmExportedFunction(*function));
    1224             :   Handle<WasmExportedFunction> exp_fun =
    1225             :       Handle<WasmExportedFunction>::cast(function);
    1226             :   wasm::NativeModule* native_module =
    1227         224 :       exp_fun->instance()->module_object()->native_module();
    1228         112 :   uint32_t func_index = exp_fun->function_index();
    1229         224 :   wasm::WasmCodeRefScope code_ref_scope;
    1230         112 :   wasm::WasmCode* code = native_module->GetCode(func_index);
    1231         112 :   return isolate->heap()->ToBoolean(code && code->is_liftoff());
    1232             : }
    1233             : 
    1234          36 : RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTracking) {
    1235             :   HandleScope scope(isolate);
    1236             :   DCHECK_EQ(1, args.length());
    1237             : 
    1238          18 :   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
    1239          18 :   object->map()->CompleteInobjectSlackTracking(isolate);
    1240             : 
    1241             :   return ReadOnlyRoots(isolate).undefined_value();
    1242             : }
    1243             : 
    1244          96 : RUNTIME_FUNCTION(Runtime_FreezeWasmLazyCompilation) {
    1245             :   DCHECK_EQ(1, args.length());
    1246             :   DisallowHeapAllocation no_gc;
    1247          48 :   CONVERT_ARG_CHECKED(WasmInstanceObject, instance, 0);
    1248             : 
    1249          96 :   instance->module_object()->native_module()->set_lazy_compile_frozen(true);
    1250             :   return ReadOnlyRoots(isolate).undefined_value();
    1251             : }
    1252             : 
    1253             : }  // namespace internal
    1254      122036 : }  // namespace v8

Generated by: LCOV version 1.10