LCOV - code coverage report
Current view: top level - src/runtime - runtime-test.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 383 488 78.5 %
Date: 2017-10-20 Functions: 66 151 43.7 %

          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             : 
       9             : #include "src/api.h"
      10             : #include "src/arguments.h"
      11             : #include "src/assembler-inl.h"
      12             : #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
      13             : #include "src/compiler.h"
      14             : #include "src/deoptimizer.h"
      15             : #include "src/frames-inl.h"
      16             : #include "src/isolate-inl.h"
      17             : #include "src/runtime-profiler.h"
      18             : #include "src/snapshot/code-serializer.h"
      19             : #include "src/snapshot/natives.h"
      20             : #include "src/wasm/memory-tracing.h"
      21             : #include "src/wasm/wasm-module.h"
      22             : #include "src/wasm/wasm-objects-inl.h"
      23             : 
      24             : namespace {
      25          12 : struct WasmCompileControls {
      26             :   uint32_t MaxWasmBufferSize = std::numeric_limits<uint32_t>::max();
      27             :   bool AllowAnySizeForAsync = true;
      28             : };
      29             : 
      30             : // We need per-isolate controls, because we sometimes run tests in multiple
      31             : // isolates
      32             : // concurrently.
      33             : // To avoid upsetting the static initializer count, we lazy initialize this.
      34             : v8::base::LazyInstance<std::map<v8::Isolate*, WasmCompileControls>>::type
      35             :     g_PerIsolateWasmControls = LAZY_INSTANCE_INITIALIZER;
      36             : 
      37          30 : bool IsWasmCompileAllowed(v8::Isolate* isolate, v8::Local<v8::Value> value,
      38             :                           bool is_async) {
      39             :   DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0);
      40          30 :   const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate);
      41          60 :   return (is_async && ctrls.AllowAnySizeForAsync) ||
      42          30 :          (v8::Local<v8::ArrayBuffer>::Cast(value)->ByteLength() <=
      43          30 :           ctrls.MaxWasmBufferSize);
      44             : }
      45             : 
      46             : // Use the compile controls for instantiation, too
      47          24 : bool IsWasmInstantiateAllowed(v8::Isolate* isolate,
      48             :                               v8::Local<v8::Value> module_or_bytes,
      49             :                               bool is_async) {
      50             :   DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0);
      51          24 :   const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate);
      52          24 :   if (is_async && ctrls.AllowAnySizeForAsync) return true;
      53          24 :   if (!module_or_bytes->IsWebAssemblyCompiledModule()) {
      54           0 :     return IsWasmCompileAllowed(isolate, module_or_bytes, is_async);
      55             :   }
      56             :   v8::Local<v8::WasmCompiledModule> module =
      57             :       v8::Local<v8::WasmCompiledModule>::Cast(module_or_bytes);
      58          72 :   return static_cast<uint32_t>(module->GetWasmWireBytes()->Length()) <=
      59          24 :          ctrls.MaxWasmBufferSize;
      60             : }
      61             : 
      62          20 : v8::Local<v8::Value> NewRangeException(v8::Isolate* isolate,
      63             :                                        const char* message) {
      64             :   return v8::Exception::RangeError(
      65             :       v8::String::NewFromOneByte(isolate,
      66             :                                  reinterpret_cast<const uint8_t*>(message),
      67             :                                  v8::NewStringType::kNormal)
      68          40 :           .ToLocalChecked());
      69             : }
      70             : 
      71          20 : void ThrowRangeException(v8::Isolate* isolate, const char* message) {
      72          20 :   isolate->ThrowException(NewRangeException(isolate, message));
      73          20 : }
      74             : 
      75          70 : bool WasmModuleOverride(const v8::FunctionCallbackInfo<v8::Value>& args) {
      76          30 :   if (IsWasmCompileAllowed(args.GetIsolate(), args[0], false)) return false;
      77          10 :   ThrowRangeException(args.GetIsolate(), "Sync compile not allowed");
      78          10 :   return true;
      79             : }
      80             : 
      81          58 : bool WasmInstanceOverride(const v8::FunctionCallbackInfo<v8::Value>& args) {
      82          24 :   if (IsWasmInstantiateAllowed(args.GetIsolate(), args[0], false)) return false;
      83          10 :   ThrowRangeException(args.GetIsolate(), "Sync instantiate not allowed");
      84          10 :   return true;
      85             : }
      86             : 
      87             : }  // namespace
      88             : 
      89             : namespace v8 {
      90             : namespace internal {
      91             : 
      92         936 : RUNTIME_FUNCTION(Runtime_ConstructDouble) {
      93         468 :   HandleScope scope(isolate);
      94             :   DCHECK_EQ(2, args.length());
      95         936 :   CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
      96         936 :   CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
      97         468 :   uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
      98         936 :   return *isolate->factory()->NewNumber(uint64_to_double(result));
      99             : }
     100             : 
     101          20 : RUNTIME_FUNCTION(Runtime_ConstructConsString) {
     102          10 :   HandleScope scope(isolate);
     103             :   DCHECK_EQ(2, args.length());
     104          20 :   CONVERT_ARG_HANDLE_CHECKED(String, left, 0);
     105          20 :   CONVERT_ARG_HANDLE_CHECKED(String, right, 1);
     106             : 
     107          10 :   CHECK(left->IsOneByteRepresentation());
     108          10 :   CHECK(right->IsOneByteRepresentation());
     109             : 
     110             :   const bool kIsOneByte = true;
     111          20 :   const int length = left->length() + right->length();
     112          20 :   return *isolate->factory()->NewConsString(left, right, length, kIsOneByte);
     113             : }
     114             : 
     115      121850 : RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
     116       60925 :   HandleScope scope(isolate);
     117             :   DCHECK_EQ(1, args.length());
     118             : 
     119             :   // This function is used by fuzzers to get coverage in compiler.
     120             :   // Ignore calls on non-function objects to avoid runtime errors.
     121       60925 :   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
     122       60925 :   if (!function_object->IsJSFunction()) {
     123           0 :     return isolate->heap()->undefined_value();
     124             :   }
     125       60925 :   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
     126             : 
     127             :   // If the function is not optimized, just return.
     128       60925 :   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
     129             : 
     130             :   // TODO(turbofan): Deoptimization from AstGraphBuilder is not supported.
     131       31900 :   if (function->code()->is_turbofanned() &&
     132       15950 :       !function->shared()->HasBytecodeArray()) {
     133           0 :     return isolate->heap()->undefined_value();
     134             :   }
     135             : 
     136       15950 :   Deoptimizer::DeoptimizeFunction(*function);
     137             : 
     138       15950 :   return isolate->heap()->undefined_value();
     139             : }
     140             : 
     141             : 
     142        8228 : RUNTIME_FUNCTION(Runtime_DeoptimizeNow) {
     143        4114 :   HandleScope scope(isolate);
     144             :   DCHECK_EQ(0, args.length());
     145             : 
     146             :   Handle<JSFunction> function;
     147             : 
     148             :   // Find the JavaScript function on the top of the stack.
     149        8228 :   JavaScriptFrameIterator it(isolate);
     150        4114 :   if (!it.done()) function = Handle<JSFunction>(it.frame()->function());
     151        4114 :   if (function.is_null()) return isolate->heap()->undefined_value();
     152             : 
     153             :   // If the function is not optimized, just return.
     154        4114 :   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
     155             : 
     156             :   // TODO(turbofan): Deoptimization from AstGraphBuilder is not supported.
     157         902 :   if (function->code()->is_turbofanned() &&
     158         451 :       !function->shared()->HasBytecodeArray()) {
     159           0 :     return isolate->heap()->undefined_value();
     160             :   }
     161             : 
     162         451 :   Deoptimizer::DeoptimizeFunction(*function);
     163             : 
     164        4565 :   return isolate->heap()->undefined_value();
     165             : }
     166             : 
     167             : 
     168          18 : RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
     169             :   SealHandleScope shs(isolate);
     170             :   DCHECK_EQ(0, args.length());
     171             : #if defined(USE_SIMULATOR)
     172             :   return isolate->heap()->true_value();
     173             : #else
     174           9 :   return isolate->heap()->false_value();
     175             : #endif
     176             : }
     177             : 
     178             : 
     179         104 : RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
     180             :   SealHandleScope shs(isolate);
     181             :   DCHECK_EQ(0, args.length());
     182             :   return isolate->heap()->ToBoolean(
     183          52 :       isolate->concurrent_recompilation_enabled());
     184             : }
     185             : 
     186           0 : RUNTIME_FUNCTION(Runtime_TypeProfile) {
     187           0 :   HandleScope scope(isolate);
     188             :   DCHECK_EQ(1, args.length());
     189             : 
     190           0 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     191           0 :   if (function->has_feedback_vector()) {
     192           0 :     FeedbackVector* vector = function->feedback_vector();
     193           0 :     if (vector->metadata()->HasTypeProfileSlot()) {
     194           0 :       FeedbackSlot slot = vector->GetTypeProfileSlot();
     195           0 :       CollectTypeProfileNexus nexus(vector, slot);
     196           0 :       return nexus.GetTypeProfile();
     197             :     }
     198             :   }
     199           0 :   return *isolate->factory()->NewJSObject(isolate->object_function());
     200             : }
     201             : 
     202      358921 : RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
     203      179413 :   HandleScope scope(isolate);
     204             : 
     205             :   // This function is used by fuzzers, ignore calls with bogus arguments count.
     206      179413 :   if (args.length() != 1 && args.length() != 2) {
     207           0 :     return isolate->heap()->undefined_value();
     208             :   }
     209             : 
     210             :   // This function is used by fuzzers to get coverage for optimizations
     211             :   // in compiler. Ignore calls on non-function objects to avoid runtime errors.
     212      179413 :   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
     213      179413 :   if (!function_object->IsJSFunction()) {
     214           0 :     return isolate->heap()->undefined_value();
     215             :   }
     216      179413 :   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
     217             : 
     218             :   // The following conditions were lifted (in part) from the DCHECK inside
     219             :   // JSFunction::MarkForOptimization().
     220             : 
     221      179413 :   if (!function->shared()->allows_lazy_compilation()) {
     222          49 :     return isolate->heap()->undefined_value();
     223             :   }
     224             : 
     225             :   // If function isn't compiled, compile it now.
     226      180319 :   if (!function->shared()->is_compiled() &&
     227         955 :       !Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) {
     228           0 :     return isolate->heap()->undefined_value();
     229             :   }
     230             : 
     231             :   // If the function is already optimized, just return.
     232      179364 :   if (function->IsOptimized() || function->shared()->HasAsmWasmData()) {
     233       42374 :     return isolate->heap()->undefined_value();
     234             :   }
     235             : 
     236             :   // If the function has optimized code, ensure that we check for it and return.
     237      136990 :   if (function->HasOptimizedCode()) {
     238          19 :     if (!function->IsInterpreted()) {
     239             :       // For non I+TF path, install a shim which checks the optimization marker.
     240             :       function->set_code(
     241           3 :           isolate->builtins()->builtin(Builtins::kCheckOptimizationMarker));
     242             :     }
     243             :     DCHECK(function->ChecksOptimizationMarker());
     244          19 :     return isolate->heap()->undefined_value();
     245             :   }
     246             : 
     247             :   ConcurrencyMode concurrency_mode = ConcurrencyMode::kNotConcurrent;
     248      136971 :   if (args.length() == 2) {
     249         190 :     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
     250         285 :     if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
     251          95 :         isolate->concurrent_recompilation_enabled()) {
     252             :       concurrency_mode = ConcurrencyMode::kConcurrent;
     253             :     }
     254             :   }
     255      136971 :   if (FLAG_trace_opt) {
     256           0 :     PrintF("[manually marking ");
     257           0 :     function->ShortPrint();
     258             :     PrintF(" for %s optimization]\n",
     259             :            concurrency_mode == ConcurrencyMode::kConcurrent ? "concurrent"
     260           0 :                                                             : "non-concurrent");
     261             :   }
     262             : 
     263             :   // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
     264      136971 :   JSFunction::EnsureLiterals(function);
     265             : 
     266      136971 :   function->MarkForOptimization(concurrency_mode);
     267             : 
     268      136971 :   return isolate->heap()->undefined_value();
     269             : }
     270             : 
     271       55314 : RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
     272       24341 :   HandleScope scope(isolate);
     273             :   DCHECK(args.length() == 0 || args.length() == 1);
     274             : 
     275             :   Handle<JSFunction> function;
     276             : 
     277             :   // The optional parameter determines the frame being targeted.
     278       24341 :   int stack_depth = args.length() == 1 ? args.smi_at(0) : 0;
     279             : 
     280             :   // Find the JavaScript function on the top of the stack.
     281       48682 :   JavaScriptFrameIterator it(isolate);
     282         189 :   while (!it.done() && stack_depth--) it.Advance();
     283       24341 :   if (!it.done()) function = Handle<JSFunction>(it.frame()->function());
     284       24341 :   if (function.is_null()) return isolate->heap()->undefined_value();
     285             : 
     286             :   // If the function is already optimized, just return.
     287       24341 :   if (function->IsOptimized()) return isolate->heap()->undefined_value();
     288             : 
     289             :   // Ensure that the function is marked for non-concurrent optimization, so that
     290             :   // subsequent runs don't also optimize.
     291       13154 :   if (!function->HasOptimizedCode()) {
     292       13154 :     if (FLAG_trace_osr) {
     293           0 :       PrintF("[OSR - OptimizeOsr marking ");
     294           0 :       function->ShortPrint();
     295           0 :       PrintF(" for non-concurrent optimization]\n");
     296             :     }
     297       13154 :     function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
     298             :   }
     299             : 
     300             :   // Make the profiler arm all back edges in unoptimized code.
     301       13154 :   if (it.frame()->type() == StackFrame::INTERPRETED) {
     302             :     isolate->runtime_profiler()->AttemptOnStackReplacement(
     303       13264 :         it.frame(), AbstractCode::kMaxLoopNestingMarker);
     304             :   }
     305             : 
     306       37495 :   return isolate->heap()->undefined_value();
     307             : }
     308             : 
     309             : 
     310        2618 : RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
     311        1309 :   HandleScope scope(isolate);
     312             :   DCHECK_EQ(1, args.length());
     313             :   // This function is used by fuzzers to get coverage for optimizations
     314             :   // in compiler. Ignore calls on non-function objects to avoid runtime errors.
     315        1309 :   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
     316        1309 :   if (!function_object->IsJSFunction()) {
     317          40 :     return isolate->heap()->undefined_value();
     318             :   }
     319        1269 :   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
     320        1269 :   function->shared()->DisableOptimization(kOptimizationDisabledForTest);
     321        1269 :   return isolate->heap()->undefined_value();
     322             : }
     323             : 
     324       13454 : RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
     325        4478 :   HandleScope scope(isolate);
     326             :   DCHECK(args.length() == 1 || args.length() == 2);
     327             :   int status = 0;
     328        4478 :   if (!isolate->use_optimizer()) {
     329             :     status |= static_cast<int>(OptimizationStatus::kNeverOptimize);
     330             :   }
     331        4478 :   if (FLAG_always_opt || FLAG_prepare_always_opt) {
     332        1081 :     status |= static_cast<int>(OptimizationStatus::kAlwaysOptimize);
     333             :   }
     334        4478 :   if (FLAG_deopt_every_n_times) {
     335          30 :     status |= static_cast<int>(OptimizationStatus::kMaybeDeopted);
     336             :   }
     337             : 
     338             :   // This function is used by fuzzers to get coverage for optimizations
     339             :   // in compiler. Ignore calls on non-function objects to avoid runtime errors.
     340        4478 :   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
     341        4478 :   if (!function_object->IsJSFunction()) {
     342          18 :     return Smi::FromInt(status);
     343             :   }
     344        4460 :   Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
     345        4460 :   status |= static_cast<int>(OptimizationStatus::kIsFunction);
     346             : 
     347             :   bool sync_with_compiler_thread = true;
     348        4460 :   if (args.length() == 2) {
     349        4407 :     CONVERT_ARG_HANDLE_CHECKED(Object, sync_object, 1);
     350        4407 :     if (!sync_object->IsString()) return isolate->heap()->undefined_value();
     351        4407 :     Handle<String> sync = Handle<String>::cast(sync_object);
     352        8814 :     if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
     353             :       sync_with_compiler_thread = false;
     354             :     }
     355             :   }
     356             : 
     357        4460 :   if (isolate->concurrent_recompilation_enabled() &&
     358             :       sync_with_compiler_thread) {
     359        4444 :     while (function->IsInOptimizationQueue()) {
     360          38 :       isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
     361          38 :       base::OS::Sleep(base::TimeDelta::FromMilliseconds(50));
     362             :     }
     363             :   }
     364             : 
     365        4460 :   if (function->IsMarkedForOptimization()) {
     366          12 :     status |= static_cast<int>(OptimizationStatus::kMarkedForOptimization);
     367        4448 :   } else if (function->IsInOptimizationQueue()) {
     368             :     status |=
     369          41 :         static_cast<int>(OptimizationStatus::kMarkedForConcurrentOptimization);
     370        4407 :   } else if (function->IsInOptimizationQueue()) {
     371           0 :     status |= static_cast<int>(OptimizationStatus::kOptimizingConcurrently);
     372             :   }
     373             : 
     374        4460 :   if (function->IsOptimized()) {
     375        3607 :     status |= static_cast<int>(OptimizationStatus::kOptimized);
     376        3607 :     if (function->code()->is_turbofanned()) {
     377        3607 :       status |= static_cast<int>(OptimizationStatus::kTurboFanned);
     378             :     }
     379             :   }
     380        4460 :   if (function->IsInterpreted()) {
     381         534 :     status |= static_cast<int>(OptimizationStatus::kInterpreted);
     382             :   }
     383             : 
     384             :   // Additionally, detect activations of this frame on the stack, and report the
     385             :   // status of the topmost frame.
     386             :   JavaScriptFrame* frame = nullptr;
     387        8920 :   JavaScriptFrameIterator it(isolate);
     388       24784 :   while (!it.done()) {
     389       40688 :     if (it.frame()->function() == *function) {
     390          20 :       frame = it.frame();
     391             :       break;
     392             :     }
     393       20324 :     it.Advance();
     394             :   }
     395        4460 :   if (frame != nullptr) {
     396          20 :     status |= static_cast<int>(OptimizationStatus::kIsExecuting);
     397          20 :     if (frame->is_optimized()) {
     398             :       status |=
     399          14 :           static_cast<int>(OptimizationStatus::kTopmostFrameIsTurboFanned);
     400             :     }
     401             :   }
     402             : 
     403        8938 :   return Smi::FromInt(status);
     404             : }
     405             : 
     406         118 : RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
     407             :   DCHECK_EQ(0, args.length());
     408         118 :   if (FLAG_block_concurrent_recompilation &&
     409          59 :       isolate->concurrent_recompilation_enabled()) {
     410          49 :     isolate->optimizing_compile_dispatcher()->Unblock();
     411             :   }
     412          59 :   return isolate->heap()->undefined_value();
     413             : }
     414             : 
     415         166 : RUNTIME_FUNCTION(Runtime_GetDeoptCount) {
     416          83 :   HandleScope scope(isolate);
     417             :   DCHECK_EQ(1, args.length());
     418         166 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     419             :   // Functions without a feedback vector have never deoptimized.
     420          83 :   if (!function->has_feedback_vector()) return Smi::kZero;
     421          59 :   return Smi::FromInt(function->feedback_vector()->deopt_count());
     422             : }
     423             : 
     424         100 : static void ReturnThis(const v8::FunctionCallbackInfo<v8::Value>& args) {
     425             :   args.GetReturnValue().Set(args.This());
     426          50 : }
     427             : 
     428         260 : RUNTIME_FUNCTION(Runtime_GetUndetectable) {
     429         130 :   HandleScope scope(isolate);
     430             :   DCHECK_EQ(0, args.length());
     431             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     432             : 
     433         130 :   Local<v8::ObjectTemplate> desc = v8::ObjectTemplate::New(v8_isolate);
     434         130 :   desc->MarkAsUndetectable();
     435         130 :   desc->SetCallAsFunctionHandler(ReturnThis);
     436             :   Local<v8::Object> obj;
     437         260 :   if (!desc->NewInstance(v8_isolate->GetCurrentContext()).ToLocal(&obj)) {
     438             :     return nullptr;
     439             :   }
     440         260 :   return *Utils::OpenHandle(*obj);
     441             : }
     442             : 
     443         200 : static void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& args) {
     444             :   double v1 = args[0]
     445         100 :                   ->NumberValue(v8::Isolate::GetCurrent()->GetCurrentContext())
     446         200 :                   .ToChecked();
     447             :   double v2 = args[1]
     448         100 :                   ->NumberValue(v8::Isolate::GetCurrent()->GetCurrentContext())
     449         200 :                   .ToChecked();
     450             :   args.GetReturnValue().Set(
     451         100 :       v8::Number::New(v8::Isolate::GetCurrent(), v1 - v2));
     452         100 : }
     453             : 
     454             : // Returns a callable object. The object returns the difference of its two
     455             : // parameters when it is called.
     456          20 : RUNTIME_FUNCTION(Runtime_GetCallable) {
     457          10 :   HandleScope scope(isolate);
     458             :   DCHECK_EQ(0, args.length());
     459             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     460          10 :   Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(v8_isolate);
     461          10 :   Local<ObjectTemplate> instance_template = t->InstanceTemplate();
     462          10 :   instance_template->SetCallAsFunctionHandler(call_as_function);
     463          10 :   v8_isolate->GetCurrentContext();
     464             :   Local<v8::Object> instance =
     465          10 :       t->GetFunction(v8_isolate->GetCurrentContext())
     466          10 :           .ToLocalChecked()
     467          10 :           ->NewInstance(v8_isolate->GetCurrentContext())
     468          10 :           .ToLocalChecked();
     469          20 :   return *Utils::OpenHandle(*instance);
     470             : }
     471             : 
     472      115580 : RUNTIME_FUNCTION(Runtime_ClearFunctionFeedback) {
     473       57790 :   HandleScope scope(isolate);
     474             :   DCHECK_EQ(1, args.length());
     475      115580 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     476       57790 :   function->ClearTypeFeedbackInfo();
     477       57790 :   return isolate->heap()->undefined_value();
     478             : }
     479             : 
     480          20 : RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) {
     481             :   // This only supports the case where the function being exported
     482             :   // calls an intermediate function, and the intermediate function
     483             :   // calls exactly one imported function
     484          10 :   HandleScope scope(isolate);
     485          10 :   CHECK_EQ(args.length(), 2);
     486             :   // It takes two parameters, the first one is the JSFunction,
     487             :   // The second one is the type
     488          20 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
     489             :   // If type is 0, it means that it is supposed to be a direct call into a wasm
     490             :   // function.
     491             :   // If type is 1, it means that it is supposed to have wrappers.
     492          20 :   CONVERT_ARG_HANDLE_CHECKED(Smi, type, 1);
     493          10 :   Handle<Code> export_code = handle(function->code());
     494          10 :   CHECK(export_code->kind() == Code::JS_TO_WASM_FUNCTION);
     495          10 :   int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
     496             :   // check the type of the $export_fct
     497             :   Handle<Code> export_fct;
     498             :   int count = 0;
     499          40 :   for (RelocIterator it(*export_code, mask); !it.done(); it.next()) {
     500          30 :     RelocInfo* rinfo = it.rinfo();
     501             :     Address target_address = rinfo->target_address();
     502          30 :     Code* target = Code::GetCodeFromTargetAddress(target_address);
     503          30 :     if (target->kind() == Code::WASM_FUNCTION) {
     504          10 :       ++count;
     505             :       export_fct = handle(target);
     506             :     }
     507             :   }
     508          10 :   CHECK_EQ(count, 1);
     509             :   // check the type of the intermediate_fct
     510             :   Handle<Code> intermediate_fct;
     511             :   count = 0;
     512          30 :   for (RelocIterator it(*export_fct, mask); !it.done(); it.next()) {
     513          20 :     RelocInfo* rinfo = it.rinfo();
     514             :     Address target_address = rinfo->target_address();
     515          20 :     Code* target = Code::GetCodeFromTargetAddress(target_address);
     516          20 :     if (target->kind() == Code::WASM_FUNCTION) {
     517          10 :       ++count;
     518             :       intermediate_fct = handle(target);
     519             :     }
     520             :   }
     521          10 :   CHECK_EQ(count, 1);
     522             :   // Check the type of the imported exported function, it should be also a wasm
     523             :   // function in our case.
     524             :   Handle<Code> imported_fct;
     525          10 :   CHECK(type->value() == 0 || type->value() == 1);
     526             : 
     527             :   Code::Kind target_kind =
     528          10 :       type->value() == 0 ? Code::WASM_FUNCTION : Code::WASM_TO_JS_FUNCTION;
     529             :   count = 0;
     530          30 :   for (RelocIterator it(*intermediate_fct, mask); !it.done(); it.next()) {
     531          20 :     RelocInfo* rinfo = it.rinfo();
     532             :     Address target_address = rinfo->target_address();
     533          20 :     Code* target = Code::GetCodeFromTargetAddress(target_address);
     534          20 :     if (target->kind() == target_kind) {
     535          10 :       ++count;
     536             :       imported_fct = handle(target);
     537             :     }
     538             :   }
     539          10 :   CHECK_LE(count, 1);
     540          10 :   return isolate->heap()->ToBoolean(count == 1);
     541             : }
     542             : 
     543         120 : RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) {
     544          60 :   HandleScope scope(isolate);
     545          60 :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     546          60 :   CHECK_EQ(args.length(), 2);
     547         120 :   CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0);
     548         120 :   CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1);
     549          60 :   WasmCompileControls& ctrl = (*g_PerIsolateWasmControls.Pointer())[v8_isolate];
     550          60 :   ctrl.AllowAnySizeForAsync = allow_async;
     551          60 :   ctrl.MaxWasmBufferSize = static_cast<uint32_t>(block_size->value());
     552          60 :   v8_isolate->SetWasmModuleCallback(WasmModuleOverride);
     553          60 :   return isolate->heap()->undefined_value();
     554             : }
     555             : 
     556          20 : RUNTIME_FUNCTION(Runtime_SetWasmInstantiateControls) {
     557          10 :   HandleScope scope(isolate);
     558             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     559          10 :   CHECK_EQ(args.length(), 0);
     560          10 :   v8_isolate->SetWasmInstanceCallback(WasmInstanceOverride);
     561          10 :   return isolate->heap()->undefined_value();
     562             : }
     563             : 
     564         118 : RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
     565          59 :   HandleScope scope(isolate);
     566             :   DCHECK_EQ(0, args.length());
     567          59 :   isolate->heap()->NotifyContextDisposed(true);
     568          59 :   return isolate->heap()->undefined_value();
     569             : }
     570             : 
     571             : 
     572         652 : RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
     573             :   SealHandleScope shs(isolate);
     574             :   DCHECK(args.length() == 2 || args.length() == 3);
     575             : #ifdef DEBUG
     576             :   CONVERT_INT32_ARG_CHECKED(interval, 0);
     577             :   CONVERT_INT32_ARG_CHECKED(timeout, 1);
     578             :   isolate->heap()->set_allocation_timeout(timeout);
     579             :   FLAG_gc_interval = interval;
     580             :   if (args.length() == 3) {
     581             :     // Enable/disable inline allocation if requested.
     582             :     CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
     583             :     if (inline_allocation) {
     584             :       isolate->heap()->EnableInlineAllocation();
     585             :     } else {
     586             :       isolate->heap()->DisableInlineAllocation();
     587             :     }
     588             :   }
     589             : #endif
     590         326 :   return isolate->heap()->undefined_value();
     591             : }
     592             : 
     593             : 
     594        1726 : RUNTIME_FUNCTION(Runtime_DebugPrint) {
     595             :   SealHandleScope shs(isolate);
     596             :   DCHECK_EQ(1, args.length());
     597             : 
     598        1726 :   OFStream os(stdout);
     599             : #ifdef DEBUG
     600             :   if (args[0]->IsString() && isolate->context() != nullptr) {
     601             :     // If we have a string, assume it's a code "marker"
     602             :     // and print some interesting cpu debugging info.
     603             :     args[0]->Print(os);
     604             :     JavaScriptFrameIterator it(isolate);
     605             :     JavaScriptFrame* frame = it.frame();
     606             :     os << "fp = " << static_cast<void*>(frame->fp())
     607             :        << ", sp = " << static_cast<void*>(frame->sp())
     608             :        << ", caller_sp = " << static_cast<void*>(frame->caller_sp()) << ": ";
     609             :   } else {
     610             :     os << "DebugPrint: ";
     611             :     args[0]->Print(os);
     612             :   }
     613             :   if (args[0]->IsHeapObject()) {
     614             :     HeapObject::cast(args[0])->map()->Print(os);
     615             :   }
     616             : #else
     617             :   // ShortPrint is available in release mode. Print is not.
     618         863 :   os << Brief(args[0]);
     619             : #endif
     620         863 :   os << std::endl;
     621             : 
     622         863 :   return args[0];  // return TOS
     623             : }
     624             : 
     625           0 : RUNTIME_FUNCTION(Runtime_PrintWithNameForAssert) {
     626             :   SealHandleScope shs(isolate);
     627             :   DCHECK_EQ(2, args.length());
     628             : 
     629           0 :   CONVERT_ARG_CHECKED(String, name, 0);
     630             : 
     631           0 :   PrintF(" * ");
     632           0 :   StringCharacterStream stream(name);
     633           0 :   while (stream.HasMore()) {
     634           0 :     uint16_t character = stream.GetNext();
     635           0 :     PrintF("%c", character);
     636             :   }
     637           0 :   PrintF(": ");
     638           0 :   args[1]->ShortPrint();
     639           0 :   PrintF("\n");
     640             : 
     641           0 :   return isolate->heap()->undefined_value();
     642             : }
     643             : 
     644           0 : RUNTIME_FUNCTION(Runtime_DebugTrace) {
     645             :   SealHandleScope shs(isolate);
     646             :   DCHECK_EQ(0, args.length());
     647           0 :   isolate->PrintStack(stdout);
     648           0 :   return isolate->heap()->undefined_value();
     649             : }
     650             : 
     651           0 : RUNTIME_FUNCTION(Runtime_DebugTrackRetainingPath) {
     652           0 :   HandleScope scope(isolate);
     653             :   DCHECK_EQ(1, args.length());
     654           0 :   if (!FLAG_track_retaining_path) {
     655           0 :     PrintF("DebugTrackRetainingPath requires --track-retaining-path flag.\n");
     656             :   } else {
     657           0 :     CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
     658           0 :     isolate->heap()->AddRetainingPathTarget(object);
     659             :   }
     660           0 :   return isolate->heap()->undefined_value();
     661             : }
     662             : 
     663             : // This will not allocate (flatten the string), but it may run
     664             : // very slowly for very deeply nested ConsStrings.  For debugging use only.
     665           0 : RUNTIME_FUNCTION(Runtime_GlobalPrint) {
     666             :   SealHandleScope shs(isolate);
     667             :   DCHECK_EQ(1, args.length());
     668             : 
     669           0 :   CONVERT_ARG_CHECKED(String, string, 0);
     670           0 :   StringCharacterStream stream(string);
     671           0 :   while (stream.HasMore()) {
     672           0 :     uint16_t character = stream.GetNext();
     673           0 :     PrintF("%c", character);
     674             :   }
     675             :   return string;
     676             : }
     677             : 
     678             : 
     679           0 : RUNTIME_FUNCTION(Runtime_SystemBreak) {
     680             :   // The code below doesn't create handles, but when breaking here in GDB
     681             :   // having a handle scope might be useful.
     682           0 :   HandleScope scope(isolate);
     683             :   DCHECK_EQ(0, args.length());
     684           0 :   base::OS::DebugBreak();
     685           0 :   return isolate->heap()->undefined_value();
     686             : }
     687             : 
     688             : 
     689             : // Sets a v8 flag.
     690         100 : RUNTIME_FUNCTION(Runtime_SetFlags) {
     691             :   SealHandleScope shs(isolate);
     692             :   DCHECK_EQ(1, args.length());
     693         100 :   CONVERT_ARG_CHECKED(String, arg, 0);
     694             :   std::unique_ptr<char[]> flags =
     695         100 :       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
     696          50 :   FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
     697          50 :   return isolate->heap()->undefined_value();
     698             : }
     699             : 
     700             : 
     701           0 : RUNTIME_FUNCTION(Runtime_Abort) {
     702             :   SealHandleScope shs(isolate);
     703             :   DCHECK_EQ(1, args.length());
     704           0 :   CONVERT_SMI_ARG_CHECKED(message_id, 0);
     705             :   const char* message =
     706           0 :       GetBailoutReason(static_cast<BailoutReason>(message_id));
     707           0 :   base::OS::PrintError("abort: %s\n", message);
     708           0 :   isolate->PrintStack(stderr);
     709           0 :   base::OS::Abort();
     710             :   UNREACHABLE();
     711             : }
     712             : 
     713             : 
     714           0 : RUNTIME_FUNCTION(Runtime_AbortJS) {
     715           0 :   HandleScope scope(isolate);
     716             :   DCHECK_EQ(1, args.length());
     717           0 :   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
     718           0 :   base::OS::PrintError("abort: %s\n", message->ToCString().get());
     719           0 :   isolate->PrintStack(stderr);
     720           0 :   base::OS::Abort();
     721             :   UNREACHABLE();
     722             : }
     723             : 
     724             : 
     725          10 : RUNTIME_FUNCTION(Runtime_NativeScriptsCount) {
     726             :   DCHECK_EQ(0, args.length());
     727           5 :   return Smi::FromInt(Natives::GetBuiltinsCount());
     728             : }
     729             : 
     730             : 
     731          40 : RUNTIME_FUNCTION(Runtime_DisassembleFunction) {
     732          20 :   HandleScope scope(isolate);
     733             : #ifdef DEBUG
     734             :   DCHECK_EQ(1, args.length());
     735             :   // Get the function and make sure it is compiled.
     736             :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
     737             :   if (!func->is_compiled() &&
     738             :       !Compiler::Compile(func, Compiler::KEEP_EXCEPTION)) {
     739             :     return isolate->heap()->exception();
     740             :   }
     741             :   OFStream os(stdout);
     742             :   func->code()->Print(os);
     743             :   os << std::endl;
     744             : #endif  // DEBUG
     745          20 :   return isolate->heap()->undefined_value();
     746             : }
     747             : 
     748             : namespace {
     749             : 
     750           0 : int StackSize(Isolate* isolate) {
     751             :   int n = 0;
     752           0 :   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
     753           0 :   return n;
     754             : }
     755             : 
     756           0 : void PrintIndentation(Isolate* isolate) {
     757             :   const int nmax = 80;
     758           0 :   int n = StackSize(isolate);
     759           0 :   if (n <= nmax) {
     760           0 :     PrintF("%4d:%*s", n, n, "");
     761             :   } else {
     762           0 :     PrintF("%4d:%*s", n, nmax, "...");
     763             :   }
     764           0 : }
     765             : 
     766             : }  // namespace
     767             : 
     768           0 : RUNTIME_FUNCTION(Runtime_TraceEnter) {
     769             :   SealHandleScope shs(isolate);
     770             :   DCHECK_EQ(0, args.length());
     771           0 :   PrintIndentation(isolate);
     772           0 :   JavaScriptFrame::PrintTop(isolate, stdout, true, false);
     773           0 :   PrintF(" {\n");
     774           0 :   return isolate->heap()->undefined_value();
     775             : }
     776             : 
     777             : 
     778           0 : RUNTIME_FUNCTION(Runtime_TraceExit) {
     779             :   SealHandleScope shs(isolate);
     780             :   DCHECK_EQ(1, args.length());
     781           0 :   CONVERT_ARG_CHECKED(Object, obj, 0);
     782           0 :   PrintIndentation(isolate);
     783           0 :   PrintF("} -> ");
     784           0 :   obj->ShortPrint();
     785           0 :   PrintF("\n");
     786             :   return obj;  // return TOS
     787             : }
     788             : 
     789           0 : RUNTIME_FUNCTION(Runtime_GetExceptionDetails) {
     790           0 :   HandleScope shs(isolate);
     791             :   DCHECK_EQ(1, args.length());
     792           0 :   CONVERT_ARG_HANDLE_CHECKED(JSObject, exception_obj, 0);
     793             : 
     794           0 :   Factory* factory = isolate->factory();
     795             :   Handle<JSMessageObject> message_obj =
     796           0 :       isolate->CreateMessage(exception_obj, nullptr);
     797             : 
     798           0 :   Handle<JSObject> message = factory->NewJSObject(isolate->object_function());
     799             : 
     800             :   Handle<String> key;
     801             :   Handle<Object> value;
     802             : 
     803           0 :   key = factory->NewStringFromAsciiChecked("start_pos");
     804           0 :   value = handle(Smi::FromInt(message_obj->start_position()), isolate);
     805           0 :   JSObject::SetProperty(message, key, value, LanguageMode::kStrict).Assert();
     806             : 
     807           0 :   key = factory->NewStringFromAsciiChecked("end_pos");
     808           0 :   value = handle(Smi::FromInt(message_obj->end_position()), isolate);
     809           0 :   JSObject::SetProperty(message, key, value, LanguageMode::kStrict).Assert();
     810             : 
     811           0 :   return *message;
     812             : }
     813             : 
     814       23192 : RUNTIME_FUNCTION(Runtime_HaveSameMap) {
     815             :   SealHandleScope shs(isolate);
     816             :   DCHECK_EQ(2, args.length());
     817       23192 :   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
     818       23192 :   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
     819       11596 :   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
     820             : }
     821             : 
     822             : 
     823           0 : RUNTIME_FUNCTION(Runtime_InNewSpace) {
     824             :   SealHandleScope shs(isolate);
     825             :   DCHECK_EQ(1, args.length());
     826           0 :   CONVERT_ARG_CHECKED(Object, obj, 0);
     827           0 :   return isolate->heap()->ToBoolean(isolate->heap()->InNewSpace(obj));
     828             : }
     829             : 
     830       10396 : RUNTIME_FUNCTION(Runtime_IsAsmWasmCode) {
     831             :   SealHandleScope shs(isolate);
     832             :   DCHECK_EQ(1, args.length());
     833       10396 :   CONVERT_ARG_CHECKED(JSFunction, function, 0);
     834        5198 :   if (!function->shared()->HasAsmWasmData()) {
     835             :     // Doesn't have wasm data.
     836        1376 :     return isolate->heap()->false_value();
     837             :   }
     838        7644 :   if (function->shared()->code() !=
     839        3822 :       isolate->builtins()->builtin(Builtins::kInstantiateAsmJs)) {
     840             :     // Hasn't been compiled yet.
     841           0 :     return isolate->heap()->false_value();
     842             :   }
     843        3822 :   return isolate->heap()->true_value();
     844             : }
     845             : 
     846             : namespace {
     847          20 : bool DisallowCodegenFromStringsCallback(v8::Local<v8::Context> context,
     848             :                                         v8::Local<v8::String> source) {
     849          20 :   return false;
     850             : }
     851             : }
     852             : 
     853         160 : RUNTIME_FUNCTION(Runtime_DisallowCodegenFromStrings) {
     854             :   SealHandleScope shs(isolate);
     855             :   DCHECK_EQ(1, args.length());
     856         160 :   CONVERT_BOOLEAN_ARG_CHECKED(flag, 0);
     857             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     858          80 :   if (flag) {
     859             :     v8_isolate->SetAllowCodeGenerationFromStringsCallback(
     860          50 :         DisallowCodegenFromStringsCallback);
     861             :   } else {
     862          30 :     v8_isolate->SetAllowCodeGenerationFromStringsCallback(nullptr);
     863             :   }
     864          80 :   return isolate->heap()->undefined_value();
     865             : }
     866             : 
     867          80 : RUNTIME_FUNCTION(Runtime_IsWasmCode) {
     868             :   SealHandleScope shs(isolate);
     869             :   DCHECK_EQ(1, args.length());
     870          80 :   CONVERT_ARG_CHECKED(JSFunction, function, 0);
     871          40 :   bool is_js_to_wasm = function->code()->kind() == Code::JS_TO_WASM_FUNCTION;
     872          40 :   return isolate->heap()->ToBoolean(is_js_to_wasm);
     873             : }
     874             : 
     875       20060 : RUNTIME_FUNCTION(Runtime_IsWasmTrapHandlerEnabled) {
     876       10030 :   DisallowHeapAllocation no_gc;
     877             :   DCHECK_EQ(0, args.length());
     878       10030 :   bool is_enabled = trap_handler::UseTrapHandler();
     879       10030 :   return isolate->heap()->ToBoolean(is_enabled);
     880             : }
     881             : 
     882       22044 : RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) {
     883       11022 :   HandleScope shs(isolate);
     884             :   DCHECK_EQ(0, args.length());
     885       11022 :   size_t trap_count = trap_handler::GetRecoveredTrapCount();
     886       22044 :   return *isolate->factory()->NewNumberFromSize(trap_count);
     887             : }
     888             : 
     889             : #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)       \
     890             :   RUNTIME_FUNCTION(Runtime_Has##Name) {                  \
     891             :     CONVERT_ARG_CHECKED(JSObject, obj, 0);               \
     892             :     return isolate->heap()->ToBoolean(obj->Has##Name()); \
     893             :   }
     894             : 
     895     2020468 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SmiElements)
     896     3038760 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ObjectElements)
     897     3000000 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SmiOrObjectElements)
     898     3020820 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DoubleElements)
     899    11001750 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HoleyElements)
     900         732 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
     901         136 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
     902           0 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FixedTypedArrayElements)
     903             : // Properties test sitting with elements tests - not fooling anyone.
     904       12482 : ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
     905             : 
     906             : #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
     907             : 
     908             : 
     909             : #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \
     910             :   RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                        \
     911             :     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                    \
     912             :     return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());       \
     913             :   }
     914             : 
     915        1080 : TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
     916             : 
     917             : #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
     918             : 
     919             : 
     920         150 : RUNTIME_FUNCTION(Runtime_SpeciesProtector) {
     921             :   SealHandleScope shs(isolate);
     922             :   DCHECK_EQ(0, args.length());
     923          75 :   return isolate->heap()->ToBoolean(isolate->IsArraySpeciesLookupChainIntact());
     924             : }
     925             : 
     926             : // Take a compiled wasm module, serialize it and copy the buffer into an array
     927             : // buffer, which is then returned.
     928         180 : RUNTIME_FUNCTION(Runtime_SerializeWasmModule) {
     929          60 :   HandleScope shs(isolate);
     930             :   DCHECK_EQ(1, args.length());
     931         120 :   CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
     932             : 
     933          60 :   Handle<WasmCompiledModule> orig(module_obj->compiled_module());
     934             :   std::unique_ptr<ScriptData> data =
     935         120 :       WasmCompiledModuleSerializer::SerializeWasmModule(isolate, orig);
     936          60 :   void* buff = isolate->array_buffer_allocator()->Allocate(data->length());
     937          60 :   Handle<JSArrayBuffer> ret = isolate->factory()->NewJSArrayBuffer();
     938          60 :   JSArrayBuffer::Setup(ret, isolate, false, buff, data->length());
     939          60 :   memcpy(buff, data->data(), data->length());
     940          60 :   return *ret;
     941             : }
     942             : 
     943             : // Take an array buffer and attempt to reconstruct a compiled wasm module.
     944             : // Return undefined if unsuccessful.
     945         140 : RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
     946          70 :   HandleScope shs(isolate);
     947             :   DCHECK_EQ(2, args.length());
     948         140 :   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0);
     949         140 :   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, wire_bytes, 1);
     950             : 
     951          70 :   Address mem_start = static_cast<Address>(buffer->backing_store());
     952          70 :   int mem_size = static_cast<int>(buffer->byte_length()->Number());
     953             : 
     954             :   // DeserializeWasmModule will allocate. We assume JSArrayBuffer doesn't
     955             :   // get relocated.
     956         140 :   ScriptData sc(mem_start, mem_size);
     957          70 :   bool already_external = wire_bytes->is_external();
     958          70 :   if (!already_external) {
     959          70 :     wire_bytes->set_is_external(true);
     960          70 :     isolate->heap()->UnregisterArrayBuffer(*wire_bytes);
     961             :   }
     962             :   MaybeHandle<FixedArray> maybe_compiled_module =
     963             :       WasmCompiledModuleSerializer::DeserializeWasmModule(
     964             :           isolate, &sc,
     965             :           Vector<const uint8_t>(
     966          70 :               reinterpret_cast<uint8_t*>(wire_bytes->backing_store()),
     967         140 :               static_cast<int>(wire_bytes->byte_length()->Number())));
     968          70 :   if (!already_external) {
     969          70 :     wire_bytes->set_is_external(false);
     970          70 :     isolate->heap()->RegisterNewArrayBuffer(*wire_bytes);
     971             :   }
     972             :   Handle<FixedArray> compiled_module;
     973          70 :   if (!maybe_compiled_module.ToHandle(&compiled_module)) {
     974          10 :     return isolate->heap()->undefined_value();
     975             :   }
     976             :   return *WasmModuleObject::New(
     977         190 :       isolate, Handle<WasmCompiledModule>::cast(compiled_module));
     978             : }
     979             : 
     980         120 : RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) {
     981          60 :   HandleScope shs(isolate);
     982             :   DCHECK_EQ(2, args.length());
     983         120 :   CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
     984         120 :   CONVERT_ARG_HANDLE_CHECKED(Smi, instance_count, 1);
     985             :   WasmInstanceObject::ValidateInstancesChainForTesting(isolate, module_obj,
     986          60 :                                                        instance_count->value());
     987          60 :   return isolate->heap()->ToBoolean(true);
     988             : }
     989             : 
     990          40 : RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) {
     991          20 :   HandleScope shs(isolate);
     992             :   DCHECK_EQ(1, args.length());
     993          40 :   CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
     994          20 :   WasmModuleObject::ValidateStateForTesting(isolate, module_obj);
     995          20 :   return isolate->heap()->ToBoolean(true);
     996             : }
     997             : 
     998          20 : RUNTIME_FUNCTION(Runtime_ValidateWasmOrphanedInstance) {
     999          10 :   HandleScope shs(isolate);
    1000             :   DCHECK_EQ(1, args.length());
    1001          20 :   CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
    1002          10 :   WasmInstanceObject::ValidateOrphanedInstanceForTesting(isolate, instance);
    1003          10 :   return isolate->heap()->ToBoolean(true);
    1004             : }
    1005             : 
    1006       11528 : RUNTIME_FUNCTION(Runtime_HeapObjectVerify) {
    1007        5764 :   HandleScope shs(isolate);
    1008             :   DCHECK_EQ(1, args.length());
    1009        5764 :   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
    1010             : #ifdef VERIFY_HEAP
    1011             :   object->ObjectVerify();
    1012             : #else
    1013        5764 :   CHECK(object->IsObject());
    1014        5764 :   if (object->IsHeapObject()) {
    1015       11468 :     CHECK(HeapObject::cast(*object)->map()->IsMap());
    1016             :   } else {
    1017          30 :     CHECK(object->IsSmi());
    1018             :   }
    1019             : #endif
    1020        5764 :   return isolate->heap()->ToBoolean(true);
    1021             : }
    1022             : 
    1023         900 : RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) {
    1024             :   DCHECK_EQ(1, args.length());
    1025         450 :   HandleScope scope(isolate);
    1026         900 :   CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
    1027         450 :   if (!instance->has_debug_info()) return 0;
    1028         320 :   uint64_t num = instance->debug_info()->NumInterpretedCalls();
    1029         640 :   return *isolate->factory()->NewNumberFromSize(static_cast<size_t>(num));
    1030             : }
    1031             : 
    1032         200 : RUNTIME_FUNCTION(Runtime_RedirectToWasmInterpreter) {
    1033             :   DCHECK_EQ(2, args.length());
    1034         100 :   HandleScope scope(isolate);
    1035         200 :   CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
    1036         200 :   CONVERT_SMI_ARG_CHECKED(function_index, 1);
    1037             :   Handle<WasmDebugInfo> debug_info =
    1038         100 :       WasmInstanceObject::GetOrCreateDebugInfo(instance);
    1039             :   WasmDebugInfo::RedirectToInterpreter(debug_info,
    1040         100 :                                        Vector<int>(&function_index, 1));
    1041         100 :   return isolate->heap()->undefined_value();
    1042             : }
    1043             : 
    1044         108 : RUNTIME_FUNCTION(Runtime_WasmTraceMemory) {
    1045          54 :   HandleScope hs(isolate);
    1046             :   DCHECK_EQ(4, args.length());
    1047         108 :   CONVERT_SMI_ARG_CHECKED(is_store, 0);
    1048         108 :   CONVERT_SMI_ARG_CHECKED(mem_rep, 1);
    1049         108 :   CONVERT_SMI_ARG_CHECKED(addr_low, 2);
    1050         108 :   CONVERT_SMI_ARG_CHECKED(addr_high, 3);
    1051             : 
    1052             :   // Find the caller wasm frame.
    1053         108 :   StackTraceFrameIterator it(isolate);
    1054             :   DCHECK(!it.done());
    1055             :   DCHECK(it.is_wasm());
    1056          54 :   WasmCompiledFrame* frame = WasmCompiledFrame::cast(it.frame());
    1057             : 
    1058          54 :   uint32_t addr = (static_cast<uint32_t>(addr_low) & 0xffff) |
    1059          54 :                   (static_cast<uint32_t>(addr_high) << 16);
    1060             :   uint8_t* mem_start = reinterpret_cast<uint8_t*>(
    1061          54 :       frame->wasm_instance()->memory_buffer()->allocation_base());
    1062          54 :   int func_index = frame->function_index();
    1063          54 :   int pos = frame->position();
    1064             :   // TODO(titzer): eliminate dependency on WasmModule definition here.
    1065             :   int func_start =
    1066          54 :       frame->wasm_instance()->module()->functions[func_index].code.offset();
    1067             :   tracing::TraceMemoryOperation(tracing::kWasmCompiled, is_store,
    1068             :                                 MachineRepresentation(mem_rep), addr,
    1069          54 :                                 func_index, pos - func_start, mem_start);
    1070         108 :   return isolate->heap()->undefined_value();
    1071             : }
    1072             : 
    1073             : }  // namespace internal
    1074             : }  // namespace v8

Generated by: LCOV version 1.10