5 #include "src/runtime/runtime-utils.h" 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" 36 struct WasmCompileControls {
37 uint32_t MaxWasmBufferSize = std::numeric_limits<uint32_t>::max();
38 bool AllowAnySizeForAsync =
true;
44 base::LazyInstance<std::map<v8::Isolate*, WasmCompileControls>>::type
45 g_PerIsolateWasmControls = LAZY_INSTANCE_INITIALIZER;
46 base::LazyInstance<base::Mutex>::type g_PerIsolateWasmControlsMutex =
47 LAZY_INSTANCE_INITIALIZER;
51 base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer());
52 DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0);
53 const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate);
54 return (is_async && ctrls.AllowAnySizeForAsync) ||
55 (value->IsArrayBuffer() &&
57 ctrls.MaxWasmBufferSize);
61 bool IsWasmInstantiateAllowed(v8::Isolate* isolate,
64 base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer());
65 DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0);
66 const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate);
67 if (is_async && ctrls.AllowAnySizeForAsync)
return true;
68 if (!module_or_bytes->IsWebAssemblyCompiledModule()) {
69 return IsWasmCompileAllowed(isolate, module_or_bytes, is_async);
74 ctrls.MaxWasmBufferSize;
78 const char* message) {
79 return v8::Exception::RangeError(
81 reinterpret_cast<const uint8_t*>(message),
86 void ThrowRangeException(v8::Isolate* isolate,
const char* message) {
87 isolate->ThrowException(NewRangeException(isolate, message));
91 if (IsWasmCompileAllowed(args.GetIsolate(), args[0],
false))
return false;
92 ThrowRangeException(args.GetIsolate(),
"Sync compile not allowed");
97 if (IsWasmInstantiateAllowed(args.GetIsolate(), args[0],
false))
return false;
98 ThrowRangeException(args.GetIsolate(),
"Sync instantiate not allowed");
104 RUNTIME_FUNCTION(Runtime_ConstructDouble) {
105 HandleScope scope(isolate);
106 DCHECK_EQ(2, args.length());
107 CONVERT_NUMBER_CHECKED(
uint32_t, hi, Uint32, args[0]);
108 CONVERT_NUMBER_CHECKED(
uint32_t, lo, Uint32, args[1]);
109 uint64_t result = (
static_cast<uint64_t
>(hi) << 32) | lo;
110 return *isolate->factory()->NewNumber(uint64_to_double(result));
113 RUNTIME_FUNCTION(Runtime_ConstructConsString) {
114 HandleScope scope(isolate);
115 DCHECK_EQ(2, args.length());
116 CONVERT_ARG_HANDLE_CHECKED(String, left, 0);
117 CONVERT_ARG_HANDLE_CHECKED(String, right, 1);
119 CHECK(left->IsOneByteRepresentation());
120 CHECK(right->IsOneByteRepresentation());
122 const bool kIsOneByte =
true;
123 const int length = left->length() + right->length();
124 return *isolate->factory()->NewConsString(left, right, length, kIsOneByte);
127 RUNTIME_FUNCTION(Runtime_ConstructSlicedString) {
128 HandleScope scope(isolate);
129 DCHECK_EQ(2, args.length());
130 CONVERT_ARG_HANDLE_CHECKED(String,
string, 0);
131 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
133 CHECK(string->IsOneByteRepresentation());
134 CHECK_LT(index->value(),
string->length());
136 Handle<String> sliced_string = isolate->factory()->NewSubString(
137 string, index->value(),
string->length());
138 CHECK(sliced_string->IsSlicedString());
139 return *sliced_string;
142 RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
143 HandleScope scope(isolate);
144 DCHECK_EQ(1, args.length());
148 CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
149 if (!function_object->IsJSFunction()) {
150 return ReadOnlyRoots(isolate).undefined_value();
152 Handle<JSFunction>
function = Handle<JSFunction>::cast(function_object);
155 if (!function->IsOptimized())
return ReadOnlyRoots(isolate).undefined_value();
157 Deoptimizer::DeoptimizeFunction(*
function);
159 return ReadOnlyRoots(isolate).undefined_value();
162 RUNTIME_FUNCTION(Runtime_DeoptimizeNow) {
163 HandleScope scope(isolate);
164 DCHECK_EQ(0, args.length());
166 Handle<JSFunction>
function;
169 JavaScriptFrameIterator it(isolate);
170 if (!it.done())
function = handle(it.frame()->function(), isolate);
171 if (
function.is_null())
return ReadOnlyRoots(isolate).undefined_value();
174 if (!function->IsOptimized())
return ReadOnlyRoots(isolate).undefined_value();
176 Deoptimizer::DeoptimizeFunction(*
function);
178 return ReadOnlyRoots(isolate).undefined_value();
181 RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
182 SealHandleScope shs(isolate);
183 DCHECK_EQ(0, args.length());
184 #if defined(USE_SIMULATOR) 185 return ReadOnlyRoots(isolate).true_value();
187 return ReadOnlyRoots(isolate).false_value();
191 RUNTIME_FUNCTION(Runtime_ICsAreEnabled) {
192 SealHandleScope shs(isolate);
193 DCHECK_EQ(0, args.length());
194 return isolate->heap()->ToBoolean(FLAG_use_ic);
197 RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
198 SealHandleScope shs(isolate);
199 DCHECK_EQ(0, args.length());
200 return isolate->heap()->ToBoolean(
201 isolate->concurrent_recompilation_enabled());
204 RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
205 HandleScope scope(isolate);
208 if (args.length() != 1 && args.length() != 2) {
209 return ReadOnlyRoots(isolate).undefined_value();
214 CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
215 if (!function_object->IsJSFunction()) {
216 return ReadOnlyRoots(isolate).undefined_value();
218 Handle<JSFunction>
function = Handle<JSFunction>::cast(function_object);
223 if (!function->shared()->allows_lazy_compilation()) {
224 return ReadOnlyRoots(isolate).undefined_value();
228 if (!function->shared()->is_compiled() &&
229 !Compiler::Compile(
function, Compiler::CLEAR_EXCEPTION)) {
230 return ReadOnlyRoots(isolate).undefined_value();
234 if (function->IsOptimized() ||
function->shared()->HasAsmWasmData()) {
235 return ReadOnlyRoots(isolate).undefined_value();
239 if (function->HasOptimizedCode()) {
240 DCHECK(function->ChecksOptimizationMarker());
241 return ReadOnlyRoots(isolate).undefined_value();
244 ConcurrencyMode concurrency_mode = ConcurrencyMode::kNotConcurrent;
245 if (args.length() == 2) {
247 CONVERT_ARG_HANDLE_CHECKED(Object, type, 1);
248 if (!type->IsString()) {
249 return ReadOnlyRoots(isolate).undefined_value();
251 if (Handle<String>::cast(type)->IsOneByteEqualTo(
252 STATIC_CHAR_VECTOR(
"concurrent")) &&
253 isolate->concurrent_recompilation_enabled()) {
254 concurrency_mode = ConcurrencyMode::kConcurrent;
257 if (FLAG_trace_opt) {
258 PrintF(
"[manually marking ");
259 function->ShortPrint();
260 PrintF(
" for %s optimization]\n",
261 concurrency_mode == ConcurrencyMode::kConcurrent ?
"concurrent" 267 if (!function->is_compiled()) {
268 DCHECK(function->shared()->IsInterpreted());
269 function->set_code(*BUILTIN_CODE(isolate, InterpreterEntryTrampoline));
272 JSFunction::EnsureFeedbackVector(
function);
273 function->MarkForOptimization(concurrency_mode);
275 return ReadOnlyRoots(isolate).undefined_value();
278 RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
279 HandleScope scope(isolate);
280 DCHECK(args.length() == 0 || args.length() == 1);
282 Handle<JSFunction>
function;
285 int stack_depth = args.length() == 1 ? args.smi_at(0) : 0;
288 JavaScriptFrameIterator it(isolate);
289 while (!it.done() && stack_depth--) it.Advance();
290 if (!it.done())
function = handle(it.frame()->function(), isolate);
291 if (
function.is_null())
return ReadOnlyRoots(isolate).undefined_value();
294 if (function->IsOptimized())
return ReadOnlyRoots(isolate).undefined_value();
298 if (!function->HasOptimizedCode()) {
299 if (FLAG_trace_osr) {
300 PrintF(
"[OSR - OptimizeOsr marking ");
301 function->ShortPrint();
302 PrintF(
" for non-concurrent optimization]\n");
304 function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
308 if (it.frame()->type() == StackFrame::INTERPRETED) {
309 isolate->runtime_profiler()->AttemptOnStackReplacement(
310 InterpretedFrame::cast(it.frame()),
311 AbstractCode::kMaxLoopNestingMarker);
314 return ReadOnlyRoots(isolate).undefined_value();
318 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
319 HandleScope scope(isolate);
320 DCHECK_EQ(1, args.length());
323 CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
324 if (!function_object->IsJSFunction()) {
325 return ReadOnlyRoots(isolate).undefined_value();
327 Handle<JSFunction>
function = Handle<JSFunction>::cast(function_object);
328 function->shared()->DisableOptimization(
329 BailoutReason::kOptimizationDisabledForTest);
330 return ReadOnlyRoots(isolate).undefined_value();
333 RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
334 HandleScope scope(isolate);
335 DCHECK(args.length() == 1 || args.length() == 2);
337 if (FLAG_lite_mode) {
338 status |=
static_cast<int>(OptimizationStatus::kLiteMode);
340 if (!isolate->use_optimizer()) {
341 status |=
static_cast<int>(OptimizationStatus::kNeverOptimize);
343 if (FLAG_always_opt || FLAG_prepare_always_opt) {
344 status |=
static_cast<int>(OptimizationStatus::kAlwaysOptimize);
346 if (FLAG_deopt_every_n_times) {
347 status |=
static_cast<int>(OptimizationStatus::kMaybeDeopted);
352 CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
353 if (!function_object->IsJSFunction()) {
354 return Smi::FromInt(status);
356 Handle<JSFunction>
function = Handle<JSFunction>::cast(function_object);
357 status |=
static_cast<int>(OptimizationStatus::kIsFunction);
359 bool sync_with_compiler_thread =
true;
360 if (args.length() == 2) {
361 CONVERT_ARG_HANDLE_CHECKED(Object, sync_object, 1);
362 if (!sync_object->IsString())
363 return ReadOnlyRoots(isolate).undefined_value();
364 Handle<String> sync = Handle<String>::cast(sync_object);
365 if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR(
"no sync"))) {
366 sync_with_compiler_thread =
false;
370 if (isolate->concurrent_recompilation_enabled() &&
371 sync_with_compiler_thread) {
372 while (function->IsInOptimizationQueue()) {
373 isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
374 base::OS::Sleep(base::TimeDelta::FromMilliseconds(50));
378 if (function->IsMarkedForOptimization()) {
379 status |=
static_cast<int>(OptimizationStatus::kMarkedForOptimization);
380 }
else if (function->IsInOptimizationQueue()) {
382 static_cast<int>(OptimizationStatus::kMarkedForConcurrentOptimization);
383 }
else if (function->IsInOptimizationQueue()) {
384 status |=
static_cast<int>(OptimizationStatus::kOptimizingConcurrently);
387 if (function->IsOptimized()) {
388 status |=
static_cast<int>(OptimizationStatus::kOptimized);
389 if (function->code()->is_turbofanned()) {
390 status |=
static_cast<int>(OptimizationStatus::kTurboFanned);
393 if (function->IsInterpreted()) {
394 status |=
static_cast<int>(OptimizationStatus::kInterpreted);
399 JavaScriptFrame* frame =
nullptr;
400 JavaScriptFrameIterator it(isolate);
402 if (it.frame()->function() == *
function) {
408 if (frame !=
nullptr) {
409 status |=
static_cast<int>(OptimizationStatus::kIsExecuting);
410 if (frame->is_optimized()) {
412 static_cast<int>(OptimizationStatus::kTopmostFrameIsTurboFanned);
416 return Smi::FromInt(status);
419 RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
420 DCHECK_EQ(0, args.length());
421 if (FLAG_block_concurrent_recompilation &&
422 isolate->concurrent_recompilation_enabled()) {
423 isolate->optimizing_compile_dispatcher()->Unblock();
425 return ReadOnlyRoots(isolate).undefined_value();
428 RUNTIME_FUNCTION(Runtime_GetDeoptCount) {
429 HandleScope scope(isolate);
430 DCHECK_EQ(1, args.length());
431 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
433 if (!function->has_feedback_vector())
return Smi::kZero;
434 return Smi::FromInt(function->feedback_vector()->deopt_count());
438 args.GetReturnValue().Set(args.This());
441 RUNTIME_FUNCTION(Runtime_GetUndetectable) {
442 HandleScope scope(isolate);
443 DCHECK_EQ(0, args.length());
444 v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*
>(isolate);
447 desc->MarkAsUndetectable();
448 desc->SetCallAsFunctionHandler(ReturnThis);
449 Local<v8::Object> obj;
450 if (!desc->NewInstance(v8_isolate->GetCurrentContext()).ToLocal(&obj)) {
453 return *Utils::OpenHandle(*obj);
458 ->NumberValue(v8::Isolate::GetCurrent()->GetCurrentContext())
461 ->NumberValue(v8::Isolate::GetCurrent()->GetCurrentContext())
463 args.GetReturnValue().Set(
464 v8::Number::New(v8::Isolate::GetCurrent(), v1 - v2));
469 RUNTIME_FUNCTION(Runtime_GetCallable) {
470 HandleScope scope(isolate);
471 DCHECK_EQ(0, args.length());
472 v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*
>(isolate);
474 Local<ObjectTemplate> instance_template = t->InstanceTemplate();
475 instance_template->SetCallAsFunctionHandler(call_as_function);
476 v8_isolate->GetCurrentContext();
477 Local<v8::Object> instance =
478 t->GetFunction(v8_isolate->GetCurrentContext())
480 ->NewInstance(v8_isolate->GetCurrentContext())
482 return *Utils::OpenHandle(*instance);
485 RUNTIME_FUNCTION(Runtime_ClearFunctionFeedback) {
486 HandleScope scope(isolate);
487 DCHECK_EQ(1, args.length());
488 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
489 function->ClearTypeFeedbackInfo();
490 return ReadOnlyRoots(isolate).undefined_value();
493 RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) {
494 HandleScope scope(isolate);
495 v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*
>(isolate);
496 CHECK_EQ(args.length(), 2);
497 CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0);
498 CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1);
499 base::MutexGuard guard(g_PerIsolateWasmControlsMutex.Pointer());
500 WasmCompileControls& ctrl = (*g_PerIsolateWasmControls.Pointer())[v8_isolate];
501 ctrl.AllowAnySizeForAsync = allow_async;
502 ctrl.MaxWasmBufferSize =
static_cast<uint32_t>(block_size->value());
503 v8_isolate->SetWasmModuleCallback(WasmModuleOverride);
504 return ReadOnlyRoots(isolate).undefined_value();
507 RUNTIME_FUNCTION(Runtime_SetWasmInstantiateControls) {
508 HandleScope scope(isolate);
509 v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*
>(isolate);
510 CHECK_EQ(args.length(), 0);
511 v8_isolate->SetWasmInstanceCallback(WasmInstanceOverride);
512 return ReadOnlyRoots(isolate).undefined_value();
515 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
516 HandleScope scope(isolate);
517 DCHECK_EQ(0, args.length());
518 isolate->heap()->NotifyContextDisposed(
true);
519 return ReadOnlyRoots(isolate).undefined_value();
523 RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
524 SealHandleScope shs(isolate);
525 DCHECK(args.length() == 2 || args.length() == 3);
526 #ifdef V8_ENABLE_ALLOCATION_TIMEOUT 527 CONVERT_INT32_ARG_CHECKED(timeout, 1);
528 isolate->heap()->set_allocation_timeout(timeout);
531 CONVERT_INT32_ARG_CHECKED(interval, 0);
532 FLAG_gc_interval = interval;
533 if (args.length() == 3) {
535 CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
536 if (inline_allocation) {
537 isolate->heap()->EnableInlineAllocation();
539 isolate->heap()->DisableInlineAllocation();
543 return ReadOnlyRoots(isolate).undefined_value();
547 RUNTIME_FUNCTION(Runtime_DebugPrint) {
548 SealHandleScope shs(isolate);
549 DCHECK_EQ(1, args.length());
551 MaybeObject maybe_object(*args.address_of_arg_at(0));
554 if (maybe_object->IsCleared()) {
555 os <<
"[weak cleared]";
557 Object*
object = maybe_object.GetHeapObjectOrSmi();
558 bool weak = maybe_object.IsWeak();
561 if (object->IsString() && !isolate->context().is_null()) {
566 JavaScriptFrameIterator it(isolate);
567 JavaScriptFrame* frame = it.frame();
568 os <<
"fp = " <<
reinterpret_cast<void*
>(frame->fp())
569 <<
", sp = " << reinterpret_cast<void*>(frame->sp())
570 <<
", caller_sp = " << reinterpret_cast<void*>(frame->caller_sp())
573 os <<
"DebugPrint: ";
579 if (object->IsHeapObject()) {
580 HeapObject::cast(
object)->map()->Print(os);
595 RUNTIME_FUNCTION(Runtime_PrintWithNameForAssert) {
596 SealHandleScope shs(isolate);
597 DCHECK_EQ(2, args.length());
599 CONVERT_ARG_CHECKED(String, name, 0);
602 StringCharacterStream stream(name);
603 while (stream.HasMore()) {
604 uint16_t character = stream.GetNext();
605 PrintF(
"%c", character);
608 args[1]->ShortPrint();
611 return ReadOnlyRoots(isolate).undefined_value();
614 RUNTIME_FUNCTION(Runtime_DebugTrace) {
615 SealHandleScope shs(isolate);
616 DCHECK_EQ(0, args.length());
617 isolate->PrintStack(stdout);
618 return ReadOnlyRoots(isolate).undefined_value();
621 RUNTIME_FUNCTION(Runtime_DebugTrackRetainingPath) {
622 HandleScope scope(isolate);
623 DCHECK_LE(1, args.length());
624 DCHECK_GE(2, args.length());
625 if (!FLAG_track_retaining_path) {
626 PrintF(
"DebugTrackRetainingPath requires --track-retaining-path flag.\n");
628 CONVERT_ARG_HANDLE_CHECKED(HeapObject,
object, 0);
629 RetainingPathOption option = RetainingPathOption::kDefault;
630 if (args.length() == 2) {
631 CONVERT_ARG_HANDLE_CHECKED(String, str, 1);
632 const char track_ephemeron_path[] =
"track-ephemeron-path";
633 if (str->IsOneByteEqualTo(STATIC_CHAR_VECTOR(track_ephemeron_path))) {
634 option = RetainingPathOption::kTrackEphemeronPath;
635 }
else if (str->length() != 0) {
636 PrintF(
"Unexpected second argument of DebugTrackRetainingPath.\n");
637 PrintF(
"Expected an empty string or '%s', got '%s'.\n",
638 track_ephemeron_path, str->ToCString().get());
641 isolate->heap()->AddRetainingPathTarget(
object, option);
643 return ReadOnlyRoots(isolate).undefined_value();
648 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
649 SealHandleScope shs(isolate);
650 DCHECK_EQ(1, args.length());
652 CONVERT_ARG_CHECKED(String,
string, 0);
653 StringCharacterStream stream(
string);
654 while (stream.HasMore()) {
655 uint16_t character = stream.GetNext();
656 PrintF(
"%c", character);
662 RUNTIME_FUNCTION(Runtime_SystemBreak) {
665 HandleScope scope(isolate);
666 DCHECK_EQ(0, args.length());
667 base::OS::DebugBreak();
668 return ReadOnlyRoots(isolate).undefined_value();
672 RUNTIME_FUNCTION(Runtime_SetForceSlowPath) {
673 SealHandleScope shs(isolate);
674 DCHECK_EQ(1, args.length());
675 CONVERT_ARG_CHECKED(Object, arg, 0);
676 if (arg->IsTrue(isolate)) {
677 isolate->set_force_slow_path(
true);
679 DCHECK(arg->IsFalse(isolate));
680 isolate->set_force_slow_path(
false);
682 return ReadOnlyRoots(isolate).undefined_value();
685 RUNTIME_FUNCTION(Runtime_Abort) {
686 SealHandleScope shs(isolate);
687 DCHECK_EQ(1, args.length());
688 CONVERT_SMI_ARG_CHECKED(message_id, 0);
689 const char* message = GetAbortReason(static_cast<AbortReason>(message_id));
690 base::OS::PrintError(
"abort: %s\n", message);
691 isolate->PrintStack(stderr);
697 RUNTIME_FUNCTION(Runtime_AbortJS) {
698 HandleScope scope(isolate);
699 DCHECK_EQ(1, args.length());
700 CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
701 if (FLAG_disable_abortjs) {
702 base::OS::PrintError(
"[disabled] abort: %s\n", message->ToCString().get());
705 base::OS::PrintError(
"abort: %s\n", message->ToCString().get());
706 isolate->PrintStack(stderr);
712 RUNTIME_FUNCTION(Runtime_DisassembleFunction) {
713 HandleScope scope(isolate);
715 DCHECK_EQ(1, args.length());
717 CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
718 if (!func->is_compiled() &&
719 !Compiler::Compile(func, Compiler::KEEP_EXCEPTION)) {
720 return ReadOnlyRoots(isolate).exception();
723 func->code()->Print(os);
726 return ReadOnlyRoots(isolate).undefined_value();
731 int StackSize(Isolate* isolate) {
733 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
737 void PrintIndentation(Isolate* isolate) {
739 int n = StackSize(isolate);
741 PrintF(
"%4d:%*s", n, n,
"");
743 PrintF(
"%4d:%*s", n, nmax,
"...");
749 RUNTIME_FUNCTION(Runtime_TraceEnter) {
750 SealHandleScope shs(isolate);
751 DCHECK_EQ(0, args.length());
752 PrintIndentation(isolate);
753 JavaScriptFrame::PrintTop(isolate, stdout,
true,
false);
755 return ReadOnlyRoots(isolate).undefined_value();
759 RUNTIME_FUNCTION(Runtime_TraceExit) {
760 SealHandleScope shs(isolate);
761 DCHECK_EQ(1, args.length());
762 CONVERT_ARG_CHECKED(Object, obj, 0);
763 PrintIndentation(isolate);
770 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
771 SealHandleScope shs(isolate);
772 DCHECK_EQ(2, args.length());
773 CONVERT_ARG_CHECKED(JSObject, obj1, 0);
774 CONVERT_ARG_CHECKED(JSObject, obj2, 1);
775 return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
779 RUNTIME_FUNCTION(Runtime_InNewSpace) {
780 SealHandleScope shs(isolate);
781 DCHECK_EQ(1, args.length());
782 CONVERT_ARG_CHECKED(Object, obj, 0);
783 return isolate->heap()->ToBoolean(Heap::InNewSpace(obj));
786 RUNTIME_FUNCTION(Runtime_IsAsmWasmCode) {
787 SealHandleScope shs(isolate);
788 DCHECK_EQ(1, args.length());
789 CONVERT_ARG_CHECKED(JSFunction,
function, 0);
790 if (!function->shared()->HasAsmWasmData()) {
792 return ReadOnlyRoots(isolate).false_value();
794 if (function->shared()->HasBuiltinId() &&
795 function->shared()->builtin_id() == Builtins::kInstantiateAsmJs) {
797 return ReadOnlyRoots(isolate).false_value();
799 return ReadOnlyRoots(isolate).true_value();
809 RUNTIME_FUNCTION(Runtime_DisallowCodegenFromStrings) {
810 SealHandleScope shs(isolate);
811 DCHECK_EQ(1, args.length());
812 CONVERT_BOOLEAN_ARG_CHECKED(flag, 0);
813 v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*
>(isolate);
814 v8_isolate->SetAllowCodeGenerationFromStringsCallback(
815 flag ? DisallowCodegenFromStringsCallback :
nullptr);
816 return ReadOnlyRoots(isolate).undefined_value();
819 RUNTIME_FUNCTION(Runtime_DisallowWasmCodegen) {
820 SealHandleScope shs(isolate);
821 DCHECK_EQ(1, args.length());
822 CONVERT_BOOLEAN_ARG_CHECKED(flag, 0);
823 v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*
>(isolate);
824 v8_isolate->SetAllowWasmCodeGenerationCallback(
825 flag ? DisallowCodegenFromStringsCallback :
nullptr);
826 return ReadOnlyRoots(isolate).undefined_value();
829 RUNTIME_FUNCTION(Runtime_IsWasmCode) {
830 SealHandleScope shs(isolate);
831 DCHECK_EQ(1, args.length());
832 CONVERT_ARG_CHECKED(JSFunction,
function, 0);
833 bool is_js_to_wasm =
function->code()->kind() == Code::JS_TO_WASM_FUNCTION;
834 return isolate->heap()->ToBoolean(is_js_to_wasm);
837 RUNTIME_FUNCTION(Runtime_IsWasmTrapHandlerEnabled) {
838 DisallowHeapAllocation no_gc;
839 DCHECK_EQ(0, args.length());
840 return isolate->heap()->ToBoolean(trap_handler::IsTrapHandlerEnabled());
843 RUNTIME_FUNCTION(Runtime_IsThreadInWasm) {
844 DisallowHeapAllocation no_gc;
845 DCHECK_EQ(0, args.length());
846 return isolate->heap()->ToBoolean(trap_handler::IsThreadInWasm());
849 RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) {
850 HandleScope scope(isolate);
851 DCHECK_EQ(0, args.length());
852 size_t trap_count = trap_handler::GetRecoveredTrapCount();
853 return *isolate->factory()->NewNumberFromSize(trap_count);
856 RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) {
857 HandleScope scope(isolate);
858 DCHECK_EQ(2, args.length());
859 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0);
860 CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 1);
862 if (JSReceiver::GetProperty(isolate, exception,
863 isolate->factory()->wasm_exception_tag_symbol())
865 Handle<FixedArray> exceptions_table(instance->exceptions_table(), isolate);
866 for (
int index = 0; index < exceptions_table->length(); ++index) {
867 if (exceptions_table->get(index) == *tag)
return Smi::FromInt(index);
870 return ReadOnlyRoots(isolate).undefined_value();
873 RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) {
874 HandleScope scope(isolate);
875 DCHECK_EQ(1, args.length());
876 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0);
877 Handle<Object> values_obj;
878 CHECK(JSReceiver::GetProperty(
880 isolate->factory()->wasm_exception_values_symbol())
881 .ToHandle(&values_obj));
882 Handle<FixedArray> values = Handle<FixedArray>::cast(values_obj);
883 return *isolate->factory()->NewJSArrayWithElements(values);
894 RUNTIME_FUNCTION(Runtime_SetWasmThreadsEnabled) {
895 DCHECK_EQ(1, args.length());
896 CONVERT_BOOLEAN_ARG_CHECKED(flag, 0);
897 v8::Isolate* v8_isolate =
reinterpret_cast<v8::Isolate*
>(isolate);
898 v8_isolate->SetWasmThreadsEnabledCallback(flag ? EnableWasmThreads
899 : DisableWasmThreads);
900 return ReadOnlyRoots(isolate).undefined_value();
903 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ 904 RUNTIME_FUNCTION(Runtime_Has##Name) { \ 905 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ 906 return isolate->heap()->ToBoolean(obj->Has##Name()); \ 909 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
910 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SmiElements)
911 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ObjectElements)
912 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SmiOrObjectElements)
913 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DoubleElements)
914 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HoleyElements)
915 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
916 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
918 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
920 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION 922 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype) \ 923 RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \ 924 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ 925 return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \ 928 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
930 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION 932 RUNTIME_FUNCTION(Runtime_ArraySpeciesProtector) {
933 SealHandleScope shs(isolate);
934 DCHECK_EQ(0, args.length());
935 return isolate->heap()->ToBoolean(isolate->IsArraySpeciesLookupChainIntact());
938 RUNTIME_FUNCTION(Runtime_MapIteratorProtector) {
939 SealHandleScope shs(isolate);
940 DCHECK_EQ(0, args.length());
941 return isolate->heap()->ToBoolean(isolate->IsMapIteratorLookupChainIntact());
944 RUNTIME_FUNCTION(Runtime_SetIteratorProtector) {
945 SealHandleScope shs(isolate);
946 DCHECK_EQ(0, args.length());
947 return isolate->heap()->ToBoolean(isolate->IsSetIteratorLookupChainIntact());
950 RUNTIME_FUNCTION(Runtime_StringIteratorProtector) {
951 SealHandleScope shs(isolate);
952 DCHECK_EQ(0, args.length());
953 return isolate->heap()->ToBoolean(
954 isolate->IsStringIteratorLookupChainIntact());
959 RUNTIME_FUNCTION(Runtime_SerializeWasmModule) {
960 HandleScope scope(isolate);
961 DCHECK_EQ(1, args.length());
962 CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
964 wasm::NativeModule* native_module = module_obj->native_module();
965 wasm::WasmSerializer wasm_serializer(isolate, native_module);
966 size_t compiled_size = wasm_serializer.GetSerializedNativeModuleSize();
967 void* array_data = isolate->array_buffer_allocator()->Allocate(compiled_size);
968 Handle<JSArrayBuffer> array_buffer = isolate->factory()->NewJSArrayBuffer();
969 JSArrayBuffer::Setup(array_buffer, isolate,
false, array_data, compiled_size);
971 !wasm_serializer.SerializeNativeModule(
972 {reinterpret_cast<uint8_t*>(array_data), compiled_size})) {
973 return ReadOnlyRoots(isolate).undefined_value();
975 return *array_buffer;
980 RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
981 HandleScope scope(isolate);
982 DCHECK_EQ(2, args.length());
983 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0);
984 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, wire_bytes, 1);
988 MaybeHandle<WasmModuleObject> maybe_module_object =
989 wasm::DeserializeNativeModule(
991 {
reinterpret_cast<uint8_t*
>(buffer->backing_store()),
992 buffer->byte_length()},
993 {
reinterpret_cast<uint8_t*
>(wire_bytes->backing_store()),
994 wire_bytes->byte_length()});
995 Handle<WasmModuleObject> module_object;
996 if (!maybe_module_object.ToHandle(&module_object)) {
997 return ReadOnlyRoots(isolate).undefined_value();
999 return *module_object;
1002 RUNTIME_FUNCTION(Runtime_HeapObjectVerify) {
1003 HandleScope shs(isolate);
1004 DCHECK_EQ(1, args.length());
1005 CONVERT_ARG_HANDLE_CHECKED(Object,
object, 0);
1007 object->ObjectVerify(isolate);
1009 CHECK(object->IsObject());
1010 if (object->IsHeapObject()) {
1011 CHECK(HeapObject::cast(*object)->map()->IsMap());
1013 CHECK(object->IsSmi());
1016 return isolate->heap()->ToBoolean(
true);
1019 RUNTIME_FUNCTION(Runtime_WasmGetNumberOfInstances) {
1020 SealHandleScope shs(isolate);
1021 DCHECK_EQ(1, args.length());
1022 CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
1023 int instance_count = 0;
1024 WeakArrayList* weak_instance_list = module_obj->weak_instance_list();
1025 for (
int i = 0;
i < weak_instance_list->length(); ++
i) {
1026 if (weak_instance_list->Get(
i)->IsWeak()) instance_count++;
1028 return Smi::FromInt(instance_count);
1031 RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) {
1032 DCHECK_EQ(1, args.length());
1033 HandleScope scope(isolate);
1034 CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
1035 if (!instance->has_debug_info())
return nullptr;
1036 uint64_t num = instance->debug_info()->NumInterpretedCalls();
1037 return *isolate->factory()->NewNumberFromSize(static_cast<size_t>(num));
1040 RUNTIME_FUNCTION(Runtime_RedirectToWasmInterpreter) {
1041 DCHECK_EQ(2, args.length());
1042 HandleScope scope(isolate);
1043 CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
1044 CONVERT_SMI_ARG_CHECKED(function_index, 1);
1045 Handle<WasmDebugInfo> debug_info =
1046 WasmInstanceObject::GetOrCreateDebugInfo(instance);
1047 WasmDebugInfo::RedirectToInterpreter(debug_info,
1048 Vector<int>(&function_index, 1));
1049 return ReadOnlyRoots(isolate).undefined_value();
1052 RUNTIME_FUNCTION(Runtime_WasmTraceMemory) {
1053 HandleScope scope(isolate);
1054 DCHECK_EQ(1, args.length());
1055 CONVERT_ARG_CHECKED(Smi, info_addr, 0);
1057 wasm::MemoryTracingInfo* info =
1058 reinterpret_cast<wasm::MemoryTracingInfo*
>(info_addr.ptr());
1061 StackTraceFrameIterator it(isolate);
1063 DCHECK(it.is_wasm());
1064 WasmCompiledFrame* frame = WasmCompiledFrame::cast(it.frame());
1066 uint8_t* mem_start =
reinterpret_cast<uint8_t*
>(
1067 frame->wasm_instance()->memory_object()->array_buffer()->backing_store());
1068 int func_index = frame->function_index();
1069 int pos = frame->position();
1072 frame->wasm_instance()->module()->functions[func_index].code.offset();
1073 wasm::ExecutionTier tier = frame->wasm_code()->is_liftoff()
1074 ? wasm::ExecutionTier::kBaseline
1075 : wasm::ExecutionTier::kOptimized;
1076 wasm::TraceMemoryOperation(tier, info, func_index, pos - func_start,
1078 return ReadOnlyRoots(isolate).undefined_value();
1081 RUNTIME_FUNCTION(Runtime_WasmTierUpFunction) {
1082 HandleScope scope(isolate);
1083 DCHECK_EQ(2, args.length());
1084 CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
1085 CONVERT_SMI_ARG_CHECKED(function_index, 1);
1086 if (!isolate->wasm_engine()->CompileFunction(
1087 isolate, instance->module_object()->native_module(), function_index,
1088 wasm::ExecutionTier::kOptimized)) {
1089 return ReadOnlyRoots(isolate).exception();
1091 return ReadOnlyRoots(isolate).undefined_value();
1094 RUNTIME_FUNCTION(Runtime_IsLiftoffFunction) {
1095 HandleScope scope(isolate);
1096 DCHECK_EQ(1, args.length());
1097 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
1098 CHECK(WasmExportedFunction::IsWasmExportedFunction(*
function));
1099 Handle<WasmExportedFunction> exp_fun =
1100 Handle<WasmExportedFunction>::cast(
function);
1101 wasm::NativeModule* native_module =
1102 exp_fun->instance()->module_object()->native_module();
1103 uint32_t func_index = exp_fun->function_index();
1104 return isolate->heap()->ToBoolean(
1105 native_module->has_code(func_index) &&
1106 native_module->code(func_index)->is_liftoff());
1109 RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTracking) {
1110 HandleScope scope(isolate);
1111 DCHECK_EQ(1, args.length());
1113 CONVERT_ARG_HANDLE_CHECKED(JSObject,
object, 0);
1114 object->map()->CompleteInobjectSlackTracking(isolate);
1116 return ReadOnlyRoots(isolate).undefined_value();
1119 RUNTIME_FUNCTION(Runtime_FreezeWasmLazyCompilation) {
1120 DCHECK_EQ(1, args.length());
1121 DisallowHeapAllocation no_gc;
1122 CONVERT_ARG_CHECKED(WasmInstanceObject, instance, 0);
1124 instance->module_object()->native_module()->set_lazy_compile_frozen(
true);
1125 return ReadOnlyRoots(isolate).undefined_value();
1128 RUNTIME_FUNCTION(Runtime_WasmMemoryHasFullGuardRegion) {
1129 DCHECK_EQ(1, args.length());
1130 DisallowHeapAllocation no_gc;
1131 CONVERT_ARG_CHECKED(WasmMemoryObject, memory, 0);
1133 return isolate->heap()->ToBoolean(memory->has_full_guard_region(isolate));
static V8_WARN_UNUSED_RESULT MaybeLocal< String > NewFromOneByte(Isolate *isolate, const uint8_t *data, v8::NewStringType type, int length=-1)
BufferReference GetWasmWireBytesRef()
static V8_INLINE Local< T > Cast(Local< S > that)
static Local< ObjectTemplate > New(Isolate *isolate, Local< FunctionTemplate > constructor=Local< FunctionTemplate >())
static Local< FunctionTemplate > New(Isolate *isolate, FunctionCallback callback=nullptr, Local< Value > data=Local< Value >(), Local< Signature > signature=Local< Signature >(), int length=0, ConstructorBehavior behavior=ConstructorBehavior::kAllow, SideEffectType side_effect_type=SideEffectType::kHasSideEffect)