LCOV - code coverage report
Current view: top level - src/runtime - runtime-test.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 412 490 84.1 %
Date: 2019-01-20 Functions: 85 178 47.8 %

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

Generated by: LCOV version 1.10