LCOV - code coverage report
Current view: top level - src/runtime - runtime-test.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 412 495 83.2 %
Date: 2019-02-19 Functions: 85 180 47.2 %

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

Generated by: LCOV version 1.10