v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
runtime-test.cc
Go to the documentation of this file.
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 <stdio.h>
6
7#include <iomanip>
8#include <memory>
9
10#include "include/v8-function.h"
11#include "include/v8-profiler.h"
12#include "src/api/api-inl.h"
13#include "src/base/macros.h"
27#include "src/flags/flags.h"
31#include "src/ic/stub-cache.h"
35#include "src/utils/utils.h"
36#ifdef V8_ENABLE_MAGLEV
38#endif // V8_ENABLE_MAGLEV
43#include "src/objects/smi.h"
45#include "src/regexp/regexp.h"
47
48#ifdef V8_ENABLE_MAGLEV
49#include "src/maglev/maglev.h"
50#endif // V8_ENABLE_MAGLEV
51
52#if V8_ENABLE_WEBASSEMBLY
54#endif // V8_ENABLE_WEBASSEMBLY
55
56namespace v8 {
57namespace internal {
58
59namespace {
60// This function is mostly used instead of (D)CHECKs for functions exposed to
61// fuzzers. TODO(353685107): consider being more permissive in functions using
62// this. For example, for fuzzing we could probably allow excess arguments,
63V8_WARN_UNUSED_RESULT Tagged<Object> CrashUnlessFuzzing(Isolate* isolate) {
64 CHECK(v8_flags.fuzzing);
65 return ReadOnlyRoots(isolate).undefined_value();
66}
67
68V8_WARN_UNUSED_RESULT bool CrashUnlessFuzzingReturnFalse(Isolate* isolate) {
69 CHECK(v8_flags.fuzzing);
70 return false;
71}
72
73V8_WARN_UNUSED_RESULT bool CheckMarkedForManualOptimization(
74 Isolate* isolate, Tagged<JSFunction> function) {
76 function)) {
77 PrintF("Error: Function ");
78 ShortPrint(function);
79 PrintF(
80 " should be prepared for optimization with "
81 "%%PrepareFunctionForOptimization before "
82 "%%OptimizeFunctionOnNextCall / %%OptimizeMaglevOnNextCall / "
83 "%%OptimizeOsr ");
84 return false;
85 }
86 return true;
87}
88
89// Returns |value| unless correctness-fuzzer-supressions is enabled,
90// otherwise returns undefined_value.
92 Isolate* isolate) {
93 return v8_flags.correctness_fuzzer_suppressions
94 ? ReadOnlyRoots(isolate).undefined_value()
95 : value;
96}
97
98// Assert that the given argument is a number within the Int32 range
99// and convert it to int32_t. If the argument is not an Int32 we crash if not
100// in fuzzing mode.
101#define CONVERT_INT32_ARG_FUZZ_SAFE(name, index) \
102 if (!IsNumber(args[index])) return CrashUnlessFuzzing(isolate); \
103 int32_t name = 0; \
104 if (!Object::ToInt32(args[index], &name)) return CrashUnlessFuzzing(isolate);
105
106// Cast the given object to a boolean and store it in a variable with
107// the given name. If the object is not a boolean we crash if not in
108// fuzzing mode.
109#define CONVERT_BOOLEAN_ARG_FUZZ_SAFE(name, index) \
110 if (!IsBoolean(args[index])) return CrashUnlessFuzzing(isolate); \
111 bool name = IsTrue(args[index], isolate);
112
113bool IsAsmWasmFunction(Isolate* isolate, Tagged<JSFunction> function) {
115#if V8_ENABLE_WEBASSEMBLY
116 // For simplicity we include invalid asm.js functions whose code hasn't yet
117 // been updated to CompileLazy but is still the InstantiateAsmJs builtin.
118 return function->shared()->HasAsmWasmData() ||
119 function->code(isolate)->builtin_id() == Builtin::kInstantiateAsmJs;
120#else
121 return false;
122#endif // V8_ENABLE_WEBASSEMBLY
123}
124
125} // namespace
126
127RUNTIME_FUNCTION(Runtime_ClearMegamorphicStubCache) {
128 HandleScope scope(isolate);
129 isolate->load_stub_cache()->Clear();
130 isolate->store_stub_cache()->Clear();
131 isolate->define_own_stub_cache()->Clear();
132 return ReadOnlyRoots(isolate).undefined_value();
133}
134
135RUNTIME_FUNCTION(Runtime_ConstructDouble) {
136 HandleScope scope(isolate);
137 // This isn't exposed to fuzzers so doesn't need to handle invalid arguments.
138 DCHECK_EQ(args.length(), 2);
139 uint32_t hi = NumberToUint32(args[0]);
140 uint32_t lo = NumberToUint32(args[1]);
141 uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
142 return *isolate->factory()->NewNumber(base::uint64_to_double(result));
143}
144
145RUNTIME_FUNCTION(Runtime_StringIsFlat) {
146 HandleScope scope(isolate);
147 DCHECK_EQ(args.length(), 1);
149 return isolate->heap()->ToBoolean(s->IsFlat());
150}
151
152RUNTIME_FUNCTION(Runtime_ConstructConsString) {
153 HandleScope scope(isolate);
154 // This isn't exposed to fuzzers so doesn't need to handle invalid arguments.
155 DCHECK_EQ(args.length(), 2);
156 DirectHandle<String> left = args.at<String>(0);
157 DirectHandle<String> right = args.at<String>(1);
158
159 const bool is_one_byte =
160 left->IsOneByteRepresentation() && right->IsOneByteRepresentation();
161 const int length = left->length() + right->length();
162 return *isolate->factory()->NewConsString(left, right, length, is_one_byte);
163}
164
165RUNTIME_FUNCTION(Runtime_ConstructSlicedString) {
166 HandleScope scope(isolate);
167 // This isn't exposed to fuzzers so doesn't need to handle invalid arguments.
168 DCHECK_EQ(args.length(), 2);
169 Handle<String> string = args.at<String>(0);
170 int index = args.smi_value_at(1);
171
172 CHECK_LT(index, string->length());
173
174 DirectHandle<String> sliced_string =
175 isolate->factory()->NewSubString(string, index, string->length());
176 CHECK(IsSlicedString(*sliced_string));
177 return *sliced_string;
178}
179
180RUNTIME_FUNCTION(Runtime_ConstructInternalizedString) {
181 HandleScope scope(isolate);
182 // This isn't exposed to fuzzers so doesn't need to handle invalid arguments.
183 DCHECK_EQ(args.length(), 1);
184 Handle<String> string = args.at<String>(0);
185 CHECK(string->IsOneByteRepresentation());
186 DirectHandle<String> internalized =
187 isolate->factory()->InternalizeString(string);
188 CHECK(IsInternalizedString(*string));
189 return *internalized;
190}
191
192RUNTIME_FUNCTION(Runtime_ConstructThinString) {
193 HandleScope scope(isolate);
194 // This isn't exposed to fuzzers so doesn't need to handle invalid arguments.
195 DCHECK_EQ(args.length(), 1);
196 Handle<String> string = args.at<String>(0);
197 if (!IsConsString(*string)) {
198 string = isolate->factory()->NewConsString(
199 isolate->factory()->empty_string(), string, string->length(),
200 string->IsOneByteRepresentation(),
201 // Pretenure to ensure it stays thin.
203 }
204 CHECK(IsConsString(*string));
205 DirectHandle<String> internalized =
206 isolate->factory()->InternalizeString(string);
207 CHECK_NE(*internalized, *string);
208 CHECK(IsThinString(*string));
209 return *string;
210}
211
212RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
213 HandleScope scope(isolate);
214 if (args.length() != 1) {
215 return CrashUnlessFuzzing(isolate);
216 }
217
218 Handle<Object> function_object = args.at(0);
219 if (!IsJSFunction(*function_object)) return CrashUnlessFuzzing(isolate);
220 auto function = Cast<JSFunction>(function_object);
221
222 if (function->IsTieringRequestedOrInProgress()) {
223 if (function->tiering_in_progress()) {
224 // Abort optimization so that calling DeoptimizeFunction on a function
225 // currently being optimized ends up with a non-optimized function.
226 isolate->AbortConcurrentOptimization(BlockingBehavior::kBlock);
227 }
228 function->ResetTieringRequests();
229 }
230
231 if (function->HasAttachedOptimizedCode(isolate)) {
232 Deoptimizer::DeoptimizeFunction(*function, LazyDeoptimizeReason::kTesting);
233 }
234
235 return ReadOnlyRoots(isolate).undefined_value();
236}
237
238RUNTIME_FUNCTION(Runtime_DeoptimizeNow) {
239 HandleScope scope(isolate);
240
242
243 // Find the JavaScript function on the top of the stack.
245 if (!it.done()) function = direct_handle(it.frame()->function(), isolate);
246 if (function.is_null()) return CrashUnlessFuzzing(isolate);
247
248 if (function->HasAttachedOptimizedCode(isolate)) {
249 Deoptimizer::DeoptimizeFunction(*function, LazyDeoptimizeReason::kTesting);
250 }
251
252 return ReadOnlyRoots(isolate).undefined_value();
253}
254
255RUNTIME_FUNCTION(Runtime_LeakHole) {
256 HandleScope scope(isolate);
257
258 // TODO(chromium:1445008): once we have multiple different hole values, we
259 // could make this function take a number as argument and return the nth hole
260 // value, or a random hole if the argument is undefined.
261 return ReadOnlyRoots(isolate).the_hole_value();
262}
263
264RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
265 SealHandleScope shs(isolate);
266#if defined(USE_SIMULATOR)
267 return ReadOnlyRoots(isolate).true_value();
268#else
269 return ReadOnlyRoots(isolate).false_value();
270#endif
271}
272
273RUNTIME_FUNCTION(Runtime_RuntimeEvaluateREPL) {
274 HandleScope scope(isolate);
275 if (args.length() != 1 || !IsString(args[0])) {
276 return CrashUnlessFuzzing(isolate);
277 }
278 Handle<String> source = args.at<String>(0);
281 isolate, result,
282 DebugEvaluate::Global(isolate, source,
285
286 return *result;
287}
288
289RUNTIME_FUNCTION(Runtime_ICsAreEnabled) {
290 SealHandleScope shs(isolate);
291 return isolate->heap()->ToBoolean(v8_flags.use_ic);
292}
293
294RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
295 SealHandleScope shs(isolate);
296 return isolate->heap()->ToBoolean(
297 isolate->concurrent_recompilation_enabled());
298}
299
300RUNTIME_FUNCTION(Runtime_IsAtomicsWaitAllowed) {
301 SealHandleScope shs(isolate);
302 return isolate->heap()->ToBoolean(isolate->allow_atomics_wait());
303}
304
305namespace {
306
307bool CanOptimizeFunction(CodeKind target_kind,
308 DirectHandle<JSFunction> function, Isolate* isolate,
309 IsCompiledScope* is_compiled_scope) {
310 // The following conditions were lifted (in part) from the DCHECK inside
311 // JSFunction::MarkForOptimization().
312
313 // If function isn't compiled, compile it now.
314 if (!is_compiled_scope->is_compiled() &&
316 is_compiled_scope)) {
317 return CrashUnlessFuzzingReturnFalse(isolate);
318 }
319
320 if (target_kind == CodeKind::TURBOFAN_JS && !v8_flags.turbofan) return false;
321 if (target_kind == CodeKind::MAGLEV && !maglev::IsMaglevEnabled()) {
322 return false;
323 }
324
325 if (function->shared()->optimization_disabled() &&
326 function->shared()->disabled_optimization_reason() ==
327 BailoutReason::kNeverOptimize) {
328 return CrashUnlessFuzzingReturnFalse(isolate);
329 }
330
331 if (IsAsmWasmFunction(isolate, *function)) {
332 return CrashUnlessFuzzingReturnFalse(isolate);
333 }
334
335 if (v8_flags.testing_d8_test_runner) {
336 if (!CheckMarkedForManualOptimization(isolate, *function)) {
337 return CrashUnlessFuzzingReturnFalse(isolate);
338 }
339 }
340
341 if (function->is_compiled(isolate) &&
342 !function->HasAvailableCodeKind(isolate,
343 CodeKind::INTERPRETED_FUNCTION)) {
344 return CrashUnlessFuzzingReturnFalse(isolate);
345 }
346
347 if (function->HasAvailableCodeKind(isolate, target_kind) ||
348 function->HasAvailableHigherTierCodeThan(isolate, target_kind)) {
349 DCHECK(function->HasAttachedOptimizedCode(isolate) ||
350 function->ChecksTieringState(isolate));
351 return false;
352 }
353
354 return true;
355}
356
357Tagged<Object> OptimizeFunctionOnNextCall(RuntimeArguments& args,
358 Isolate* isolate,
359 CodeKind target_kind) {
360 if (args.length() != 1 && args.length() != 2) {
361 return CrashUnlessFuzzing(isolate);
362 }
363
364 DirectHandle<Object> function_object = args.at(0);
365 if (!IsJSFunction(*function_object)) return CrashUnlessFuzzing(isolate);
366 DirectHandle<JSFunction> function = Cast<JSFunction>(function_object);
367
368 IsCompiledScope is_compiled_scope(
369 function->shared()->is_compiled_scope(isolate));
370 if (!CanOptimizeFunction(target_kind, function, isolate,
371 &is_compiled_scope)) {
372 return ReadOnlyRoots(isolate).undefined_value();
373 }
374
376 if (args.length() == 2) {
377 DirectHandle<Object> type = args.at(1);
378 if (!IsString(*type)) return CrashUnlessFuzzing(isolate);
379 if (Cast<String>(type)->IsOneByteEqualTo(
380 base::StaticCharVector("concurrent")) &&
381 isolate->concurrent_recompilation_enabled()) {
382 concurrency_mode = ConcurrencyMode::kConcurrent;
383 }
384 }
385
386 // This function may not have been lazily compiled yet, even though its shared
387 // function has.
388 if (!function->is_compiled(isolate)) {
389 DCHECK(function->shared()->HasBytecodeArray());
390 Tagged<Code> code = *BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
391 if (function->shared()->HasBaselineCode()) {
392 code = function->shared()->baseline_code(kAcquireLoad);
393 }
394 function->UpdateCode(code);
395 }
396
397 TraceManualRecompile(*function, target_kind, concurrency_mode);
398 JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
399 if (function->GetActiveTier(isolate) != target_kind) {
400 function->RequestOptimization(isolate, target_kind, concurrency_mode);
401 }
402
403 return ReadOnlyRoots(isolate).undefined_value();
404}
405
406bool EnsureCompiledAndFeedbackVector(Isolate* isolate,
407 DirectHandle<JSFunction> function,
408 IsCompiledScope* is_compiled_scope) {
409 *is_compiled_scope =
410 function->shared()->is_compiled_scope(function->GetIsolate());
411
412 // If function isn't compiled, compile it now.
413 if (!is_compiled_scope->is_compiled()) {
414 // Check function allows lazy compilation.
415 DCHECK(function->shared()->allows_lazy_compilation());
416 if (!Compiler::Compile(isolate, function, Compiler::CLEAR_EXCEPTION,
417 is_compiled_scope)) {
418 return false;
419 }
420 }
421
422 // Ensure function has a feedback vector to hold type feedback for
423 // optimization.
424 if (!function->shared()->HasFeedbackMetadata()) {
425 return false;
426 }
427 JSFunction::EnsureFeedbackVector(isolate, function, is_compiled_scope);
428 return true;
429}
430
431} // namespace
432
433RUNTIME_FUNCTION(Runtime_CompileBaseline) {
434 HandleScope scope(isolate);
435 if (args.length() != 1) {
436 return CrashUnlessFuzzing(isolate);
437 }
438 DirectHandle<Object> function_object = args.at(0);
439 if (!IsJSFunction(*function_object)) return CrashUnlessFuzzing(isolate);
440 DirectHandle<JSFunction> function = Cast<JSFunction>(function_object);
441
442 IsCompiledScope is_compiled_scope =
443 function->shared(isolate)->is_compiled_scope(isolate);
444
445 if (!function->shared(isolate)->IsUserJavaScript()) {
446 return CrashUnlessFuzzing(isolate);
447 }
448
449 // First compile the bytecode, if we have to.
450 if (!is_compiled_scope.is_compiled() &&
452 &is_compiled_scope)) {
453 return CrashUnlessFuzzing(isolate);
454 }
455
457 &is_compiled_scope)) {
458 return CrashUnlessFuzzing(isolate);
459 }
460
461 return ReadOnlyRoots(isolate).undefined_value();
462}
463
464// TODO(v8:7700): Remove this function once we no longer need it to measure
465// maglev compile times. For normal tierup, OptimizeMaglevOnNextCall should be
466// used instead.
467#ifdef V8_ENABLE_MAGLEV
468RUNTIME_FUNCTION(Runtime_BenchMaglev) {
469 HandleScope scope(isolate);
470 DCHECK_EQ(args.length(), 2);
471 Handle<JSFunction> function = args.at<JSFunction>(0);
472 int count = args.smi_value_at(1);
473
474 DirectHandle<Code> code;
475 base::ElapsedTimer timer;
476 timer.Start();
477 code = Maglev::Compile(isolate, function, BytecodeOffset::None())
478 .ToHandleChecked();
479 for (int i = 1; i < count; ++i) {
480 HandleScope handle_scope(isolate);
481 Maglev::Compile(isolate, function, BytecodeOffset::None());
482 }
483 PrintF("Maglev compile time: %g ms!\n",
484 timer.Elapsed().InMillisecondsF() / count);
485
486 function->UpdateOptimizedCode(isolate, *code);
487
488 return ReadOnlyRoots(isolate).undefined_value();
489}
490#else
491RUNTIME_FUNCTION(Runtime_BenchMaglev) {
492 PrintF("Maglev is not enabled.\n");
493 return ReadOnlyRoots(isolate).undefined_value();
494}
495#endif // V8_ENABLE_MAGLEV
496
497RUNTIME_FUNCTION(Runtime_BenchTurbofan) {
498 HandleScope scope(isolate);
499 DCHECK_EQ(args.length(), 2);
500 DirectHandle<JSFunction> function = args.at<JSFunction>(0);
501 int count = args.smi_value_at(1);
502
503 base::ElapsedTimer timer;
504 timer.Start();
506 CodeKind::TURBOFAN_JS);
507 for (int i = 1; i < count; ++i) {
509 CodeKind::TURBOFAN_JS);
510 }
511
512 double compile_time = timer.Elapsed().InMillisecondsF() / count;
513
514 return *isolate->factory()->NewNumber(compile_time);
515}
516
517RUNTIME_FUNCTION(Runtime_ActiveTierIsIgnition) {
518 HandleScope scope(isolate);
519 if (args.length() != 1 || !IsJSFunction(args[0])) {
520 return CrashUnlessFuzzing(isolate);
521 }
522 DirectHandle<JSFunction> function = args.at<JSFunction>(0);
523 return isolate->heap()->ToBoolean(function->ActiveTierIsIgnition(isolate));
524}
525
526RUNTIME_FUNCTION(Runtime_ActiveTierIsSparkplug) {
527 HandleScope scope(isolate);
528 if (args.length() != 1 || !IsJSFunction(args[0])) {
529 return CrashUnlessFuzzing(isolate);
530 }
531 DirectHandle<JSFunction> function = args.at<JSFunction>(0);
532 return isolate->heap()->ToBoolean(function->ActiveTierIsBaseline(isolate));
533}
534
535RUNTIME_FUNCTION(Runtime_ActiveTierIsMaglev) {
536 HandleScope scope(isolate);
537 if (args.length() != 1 || !IsJSFunction(args[0])) {
538 return CrashUnlessFuzzing(isolate);
539 }
540 DirectHandle<JSFunction> function = args.at<JSFunction>(0);
541 return isolate->heap()->ToBoolean(function->ActiveTierIsMaglev(isolate));
542}
543
544RUNTIME_FUNCTION(Runtime_ActiveTierIsTurbofan) {
545 HandleScope scope(isolate);
546 if (args.length() != 1 || !IsJSFunction(args[0])) {
547 return CrashUnlessFuzzing(isolate);
548 }
549 DirectHandle<JSFunction> function = args.at<JSFunction>(0);
550 return isolate->heap()->ToBoolean(function->ActiveTierIsTurbofan(isolate));
551}
552
553RUNTIME_FUNCTION(Runtime_IsSparkplugEnabled) {
554 return isolate->heap()->ToBoolean(v8_flags.sparkplug);
555}
556
557RUNTIME_FUNCTION(Runtime_IsMaglevEnabled) {
558 return isolate->heap()->ToBoolean(maglev::IsMaglevEnabled());
559}
560
561RUNTIME_FUNCTION(Runtime_IsTurbofanEnabled) {
562 return isolate->heap()->ToBoolean(v8_flags.turbofan);
563}
564
565RUNTIME_FUNCTION(Runtime_CurrentFrameIsTurbofan) {
566 HandleScope scope(isolate);
568 return isolate->heap()->ToBoolean(it.frame()->is_turbofan());
569}
570
571#ifdef V8_ENABLE_MAGLEV
572RUNTIME_FUNCTION(Runtime_OptimizeMaglevOnNextCall) {
573 HandleScope scope(isolate);
574 return OptimizeFunctionOnNextCall(
575 args, isolate,
576 v8_flags.optimize_maglev_optimizes_to_turbofan ? CodeKind::TURBOFAN_JS
577 : CodeKind::MAGLEV);
578}
579#else
580RUNTIME_FUNCTION(Runtime_OptimizeMaglevOnNextCall) {
581 if (!v8_flags.fuzzing) PrintF("Maglev is not enabled.\n");
582 return ReadOnlyRoots(isolate).undefined_value();
583}
584#endif // V8_ENABLE_MAGLEV
585
586// TODO(jgruber): Rename to OptimizeTurbofanOnNextCall.
587RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
588 HandleScope scope(isolate);
589 return OptimizeFunctionOnNextCall(
590 args, isolate,
591 v8_flags.optimize_on_next_call_optimizes_to_maglev
592 ? CodeKind::MAGLEV
593 : CodeKind::TURBOFAN_JS);
594}
595
596RUNTIME_FUNCTION(Runtime_EnsureFeedbackVectorForFunction) {
597 HandleScope scope(isolate);
598 if (args.length() != 1 || !IsJSFunction(args[0])) {
599 return CrashUnlessFuzzing(isolate);
600 }
601 DirectHandle<JSFunction> function = args.at<JSFunction>(0);
602 if (function->has_feedback_vector()) {
603 return ReadOnlyRoots(isolate).undefined_value();
604 }
605
606 IsCompiledScope is_compiled_scope;
607 EnsureCompiledAndFeedbackVector(isolate, function, &is_compiled_scope);
608 return ReadOnlyRoots(isolate).undefined_value();
609}
610
611RUNTIME_FUNCTION(Runtime_PrepareFunctionForOptimization) {
612 HandleScope scope(isolate);
613 if ((args.length() != 1 && args.length() != 2) || !IsJSFunction(args[0])) {
614 return CrashUnlessFuzzing(isolate);
615 }
616 DirectHandle<JSFunction> function = args.at<JSFunction>(0);
617
618 IsCompiledScope is_compiled_scope;
619 if (!EnsureCompiledAndFeedbackVector(isolate, function, &is_compiled_scope)) {
620 return CrashUnlessFuzzing(isolate);
621 }
622
623 // If optimization is disabled for the function, return without marking it for
624 // manual optimization
625 if (function->shared()->optimization_disabled() &&
626 function->shared()->disabled_optimization_reason() ==
627 BailoutReason::kNeverOptimize) {
628 return CrashUnlessFuzzing(isolate);
629 }
630
631 if (IsAsmWasmFunction(isolate, *function)) return CrashUnlessFuzzing(isolate);
632
633 // Hold onto the bytecode array between marking and optimization to ensure
634 // it's not flushed.
635 if (v8_flags.testing_d8_test_runner || v8_flags.allow_natives_syntax) {
637 isolate, function, &is_compiled_scope);
638 }
639
640 return ReadOnlyRoots(isolate).undefined_value();
641}
642
643namespace {
644
645void FinalizeOptimization(Isolate* isolate) {
646 DCHECK(isolate->concurrent_recompilation_enabled());
647 isolate->optimizing_compile_dispatcher()->WaitUntilCompilationJobsDone();
648 isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
649 isolate->optimizing_compile_dispatcher()->set_finalize(true);
650
651#if V8_ENABLE_MAGLEV
652 if (isolate->maglev_concurrent_dispatcher()->is_enabled()) {
653 isolate->maglev_concurrent_dispatcher()->AwaitCompileJobs();
654 isolate->maglev_concurrent_dispatcher()->FinalizeFinishedJobs();
655 }
656#endif // V8_ENABLE_MAGLEV
657}
658
659BytecodeOffset OffsetOfNextJumpLoop(Isolate* isolate,
660 Handle<BytecodeArray> bytecode_array,
661 int current_offset) {
662 interpreter::BytecodeArrayIterator it(bytecode_array, current_offset);
663
664 // First, look for a loop that contains the current bytecode offset.
665 for (; !it.done(); it.Advance()) {
666 if (it.current_bytecode() != interpreter::Bytecode::kJumpLoop) {
667 continue;
668 }
669 if (!base::IsInRange(current_offset, it.GetJumpTargetOffset(),
670 it.current_offset())) {
671 continue;
672 }
673
674 return BytecodeOffset(it.current_offset());
675 }
676
677 // Fall back to any loop after the current offset.
678 it.SetOffset(current_offset);
679 for (; !it.done(); it.Advance()) {
680 if (it.current_bytecode() == interpreter::Bytecode::kJumpLoop) {
681 return BytecodeOffset(it.current_offset());
682 }
683 }
684
685 return BytecodeOffset::None();
686}
687
688} // namespace
689
690RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
691 HandleScope handle_scope(isolate);
692
694
695 // The optional parameter determines the frame being targeted.
696 int stack_depth = 0;
697 if (args.length() == 1) {
698 if (!IsSmi(args[0])) return CrashUnlessFuzzing(isolate);
699 stack_depth = args.smi_value_at(0);
700 }
701
702 // Find the JavaScript function on the top of the stack.
704 while (!it.done() && stack_depth--) it.Advance();
705 if (!it.done()) {
706 if (it.frame()->is_turbofan()) {
707 if (v8_flags.trace_osr) {
708 CodeTracer::Scope scope(isolate->GetCodeTracer());
709 PrintF(scope.file(),
710 "[OSR - %%OptimizeOsr failed because the current function could "
711 "not be found.]\n");
712 }
713 // This can happen if %OptimizeOsr is in inlined function.
714 return ReadOnlyRoots(isolate).undefined_value();
715 } else if (it.frame()->is_maglev()) {
716 function = MaglevFrame::cast(it.frame())->GetInnermostFunction();
717 } else {
718 function = direct_handle(it.frame()->function(), isolate);
719 }
720 }
721 if (function.is_null()) return CrashUnlessFuzzing(isolate);
722
723 if (V8_UNLIKELY((!v8_flags.turbofan && !maglev::IsMaglevEnabled()) ||
724 (!v8_flags.use_osr && !maglev::IsMaglevOsrEnabled()))) {
725 return ReadOnlyRoots(isolate).undefined_value();
726 }
727
728 if (!function->shared()->allows_lazy_compilation()) {
729 return CrashUnlessFuzzing(isolate);
730 }
731
732 if (function->shared()->optimization_disabled() &&
733 function->shared()->disabled_optimization_reason() ==
734 BailoutReason::kNeverOptimize) {
735 return CrashUnlessFuzzing(isolate);
736 }
737
738 if (v8_flags.testing_d8_test_runner) {
739 if (!CheckMarkedForManualOptimization(isolate, *function)) {
740 return CrashUnlessFuzzing(isolate);
741 }
742 }
743
744 if (function->HasAvailableOptimizedCode(isolate) &&
745 (!function->code(isolate)->is_maglevved() || !v8_flags.osr_from_maglev)) {
746 DCHECK(function->HasAttachedOptimizedCode(isolate) ||
747 function->ChecksTieringState(isolate));
748 // If function is already optimized, return.
749 return ReadOnlyRoots(isolate).undefined_value();
750 }
751
752 if (!it.frame()->is_unoptimized() &&
753 (!it.frame()->is_maglev() || !v8_flags.osr_from_maglev)) {
754 // Nothing to be done.
755 return ReadOnlyRoots(isolate).undefined_value();
756 }
757
758 IsCompiledScope is_compiled_scope(
759 function->shared()->is_compiled_scope(isolate));
760 JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
761 isolate->tiering_manager()->RequestOsrAtNextOpportunity(*function);
762
763 // If concurrent OSR is enabled, the testing workflow is a bit tricky. We
764 // must guarantee that the next JumpLoop installs the finished OSR'd code
765 // object, but we still want to exercise concurrent code paths. To do so,
766 // we attempt to find the next JumpLoop, start an OSR job for it now, and
767 // immediately force finalization.
768 // If this succeeds and we correctly match up the next JumpLoop, once we
769 // reach the JumpLoop we'll hit the OSR cache and install the generated code.
770 // If not (e.g. because we enter a nested loop first), the next JumpLoop will
771 // see the cached OSR code with a mismatched offset, and trigger
772 // non-concurrent OSR compilation and installation.
773 // To tier up from Maglev to TF we always do this, because the non-concurrent
774 // recompilation in `CompileOptimizedOSRFromMaglev` is broken. See the comment
775 // in `runtime-compiler.cc`.
776 bool concurrent_osr =
777 isolate->concurrent_recompilation_enabled() && v8_flags.concurrent_osr;
778 bool is_maglev = false;
779 if (it.frame()->is_maglev() || concurrent_osr) {
781 if (it.frame()->is_unoptimized()) {
782 UnoptimizedJSFrame* frame = UnoptimizedJSFrame::cast(it.frame());
783 Handle<BytecodeArray> bytecode_array(frame->GetBytecodeArray(), isolate);
784 const int current_offset = frame->GetBytecodeOffset();
785 osr_offset =
786 OffsetOfNextJumpLoop(isolate, bytecode_array, current_offset);
787 } else {
788 MaglevFrame* frame = MaglevFrame::cast(it.frame());
789 Handle<BytecodeArray> bytecode_array(
790 function->shared()->GetBytecodeArray(isolate), isolate);
791 const BytecodeOffset current_offset = frame->GetBytecodeOffsetForOSR();
792 osr_offset = OffsetOfNextJumpLoop(
793 isolate, bytecode_array,
794 current_offset.IsNone() ? 0 : current_offset.ToInt());
795 is_maglev = true;
796 }
797
798 if (osr_offset.IsNone()) {
799 // The loop may have been elided by bytecode generation (e.g. for
800 // patterns such as `do { ... } while (false);` or we are in an inlined
801 // constructor stub.
802 return ReadOnlyRoots(isolate).undefined_value();
803 }
804
805 // Finalize first to ensure all pending tasks are done (since we can't
806 // queue more than one OSR job for each function).
807 if (concurrent_osr) {
808 FinalizeOptimization(isolate);
809 }
810
811 // Queue the job.
812 auto unused_result = Compiler::CompileOptimizedOSR(
813 isolate, function, osr_offset,
814 concurrent_osr ? ConcurrencyMode::kConcurrent
816 (maglev::IsMaglevOsrEnabled() && !it.frame()->is_maglev())
817 ? CodeKind::MAGLEV
818 : CodeKind::TURBOFAN_JS);
819 USE(unused_result);
820
821 // Finalize again to finish the queued job. The next call into
822 // Runtime::kCompileOptimizedOSR will pick up the cached InstructionStream
823 // object.
824 if (concurrent_osr) {
825 FinalizeOptimization(isolate);
826 }
827
828 if (is_maglev) {
829 // Maglev ignores the maybe_has_optimized_osr_code flag, thus we also need
830 // to set a maximum urgency.
831 function->feedback_vector()->set_osr_urgency(
833 }
834 }
835
836 return ReadOnlyRoots(isolate).undefined_value();
837}
838
839RUNTIME_FUNCTION(Runtime_BaselineOsr) {
840 HandleScope scope(isolate);
841
842 // Find the JavaScript function on the top of the stack.
844 DirectHandle<JSFunction> function(it.frame()->function(), isolate);
845 if (function.is_null()) return CrashUnlessFuzzing(isolate);
846 if (!v8_flags.sparkplug || !v8_flags.use_osr) {
847 return ReadOnlyRoots(isolate).undefined_value();
848 }
849 if (!it.frame()->is_unoptimized()) {
850 return ReadOnlyRoots(isolate).undefined_value();
851 }
852
853 IsCompiledScope is_compiled_scope(
854 function->shared()->is_compiled_scope(isolate));
856 &is_compiled_scope);
857
858 return ReadOnlyRoots(isolate).undefined_value();
859}
860
861RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
862 HandleScope scope(isolate);
863 if (args.length() != 1) {
864 return CrashUnlessFuzzing(isolate);
865 }
866 Handle<Object> function_object = args.at(0);
867 PtrComprCageBase cage_base(isolate);
868 if (!IsJSFunction(*function_object, cage_base)) {
869 return CrashUnlessFuzzing(isolate);
870 }
871 auto function = Cast<JSFunction>(function_object);
872 DirectHandle<SharedFunctionInfo> sfi(function->shared(cage_base), isolate);
873 CodeKind code_kind = sfi->abstract_code(isolate)->kind(cage_base);
874 switch (code_kind) {
875 case CodeKind::INTERPRETED_FUNCTION:
876 break;
877 case CodeKind::BUILTIN:
878 if (HeapLayout::InReadOnlySpace(*sfi)) {
879 // SFIs for builtin functions are in RO space and thus we cannot set
880 // the never-optimize bit. But such SFIs cannot be optimized anyways.
881 return CrashUnlessFuzzing(isolate);
882 }
883 break;
884 default:
885 return CrashUnlessFuzzing(isolate);
886 }
887
888 // Make sure to finish compilation if there is a parallel lazy compilation in
889 // progress, to make sure that the compilation finalization doesn't clobber
890 // the SharedFunctionInfo's disable_optimization field.
891 if (isolate->lazy_compile_dispatcher() &&
892 isolate->lazy_compile_dispatcher()->IsEnqueued(sfi)) {
893 isolate->lazy_compile_dispatcher()->FinishNow(sfi);
894 }
895
896 sfi->DisableOptimization(isolate, BailoutReason::kNeverOptimize);
897 return ReadOnlyRoots(isolate).undefined_value();
898}
899
900RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
901 HandleScope scope(isolate);
902 DCHECK_EQ(args.length(), 1);
903
904 int status = 0;
905 if (v8_flags.lite_mode || v8_flags.jitless || !V8_ENABLE_TURBOFAN_BOOL) {
906 // These modes cannot optimize. Unit tests should handle these the same
907 // way.
908 status |= static_cast<int>(OptimizationStatus::kLiteMode);
909 }
910 if (!isolate->use_optimizer()) {
911 status |= static_cast<int>(OptimizationStatus::kNeverOptimize);
912 }
913 if (v8_flags.always_turbofan || v8_flags.prepare_always_turbofan) {
914 status |= static_cast<int>(OptimizationStatus::kAlwaysOptimize);
915 }
916 if (v8_flags.deopt_every_n_times) {
917 status |= static_cast<int>(OptimizationStatus::kMaybeDeopted);
918 }
919 if (v8_flags.optimize_on_next_call_optimizes_to_maglev) {
920 status |= static_cast<int>(
922 }
923 if (v8_flags.optimize_maglev_optimizes_to_turbofan) {
924 status |= static_cast<int>(
926 }
927
928 Handle<Object> function_object = args.at(0);
929 if (IsUndefined(*function_object)) return Smi::FromInt(status);
930 if (!IsJSFunction(*function_object)) return CrashUnlessFuzzing(isolate);
931
932 auto function = Cast<JSFunction>(function_object);
933 status |= static_cast<int>(OptimizationStatus::kIsFunction);
934
935 if (function->has_feedback_vector()) {
936 if (function->tiering_in_progress()) {
937 status |= static_cast<int>(OptimizationStatus::kOptimizingConcurrently);
938 } else if (function->GetRequestedOptimizationIfAny(
939 isolate, ConcurrencyMode::kConcurrent) == CodeKind::MAGLEV) {
940 status |= static_cast<int>(
942 } else if (function->GetRequestedOptimizationIfAny(
944 CodeKind::MAGLEV) {
945 status |=
947 } else if (function->GetRequestedOptimizationIfAny(
949 CodeKind::TURBOFAN_JS) {
950 status |= static_cast<int>(
952 } else if (function->GetRequestedOptimizationIfAny(
954 CodeKind::TURBOFAN_JS) {
955 status |= static_cast<int>(OptimizationStatus::kMarkedForOptimization);
956 }
957 }
958
959 if (function->HasAttachedOptimizedCode(isolate)) {
960 Tagged<Code> code = function->code(isolate);
961 if (code->marked_for_deoptimization()) {
962 status |= static_cast<int>(OptimizationStatus::kMarkedForDeoptimization);
963 } else {
964 status |= static_cast<int>(OptimizationStatus::kOptimized);
965 }
966 if (code->is_maglevved()) {
967 status |= static_cast<int>(OptimizationStatus::kMaglevved);
968 } else if (code->is_turbofanned()) {
969 status |= static_cast<int>(OptimizationStatus::kTurboFanned);
970 }
971 }
972 if (function->HasAttachedCodeKind(isolate, CodeKind::BASELINE)) {
973 status |= static_cast<int>(OptimizationStatus::kBaseline);
974 }
975 if (function->ActiveTierIsIgnition(isolate)) {
976 status |= static_cast<int>(OptimizationStatus::kInterpreted);
977 }
978 if (!function->is_compiled(isolate)) {
979 status |= static_cast<int>(OptimizationStatus::kIsLazy);
980 }
981
982 // Additionally, detect activations of this frame on the stack, and report the
983 // status of the topmost frame.
984 JavaScriptFrame* frame = nullptr;
986 while (!it.done()) {
987 if (it.frame()->function() == *function) {
988 frame = it.frame();
989 break;
990 }
991 it.Advance();
992 }
993 if (frame != nullptr) {
994 status |= static_cast<int>(OptimizationStatus::kIsExecuting);
995 if (frame->is_turbofan()) {
996 status |=
998 } else if (frame->is_interpreted()) {
999 status |=
1001 } else if (frame->is_baseline()) {
1002 status |= static_cast<int>(OptimizationStatus::kTopmostFrameIsBaseline);
1003 } else if (frame->is_maglev()) {
1004 status |= static_cast<int>(OptimizationStatus::kTopmostFrameIsMaglev);
1005 }
1006 }
1007
1008 return Smi::FromInt(status);
1009}
1010
1011RUNTIME_FUNCTION(Runtime_GetFunctionForCurrentFrame) {
1012 HandleScope scope(isolate);
1013 // This isn't exposed to fuzzers so doesn't need to handle invalid arguments.
1014 DCHECK_EQ(args.length(), 0);
1015
1016 JavaScriptStackFrameIterator it(isolate);
1017 DCHECK(!it.done());
1018 return it.frame()->function();
1019}
1020
1021RUNTIME_FUNCTION(Runtime_DisableOptimizationFinalization) {
1022 if (isolate->concurrent_recompilation_enabled()) {
1023 isolate->optimizing_compile_dispatcher()->WaitUntilCompilationJobsDone();
1024 isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
1025 isolate->stack_guard()->ClearInstallCode();
1026 isolate->optimizing_compile_dispatcher()->set_finalize(false);
1027 }
1028 return ReadOnlyRoots(isolate).undefined_value();
1029}
1030
1031RUNTIME_FUNCTION(Runtime_WaitForBackgroundOptimization) {
1032 if (isolate->concurrent_recompilation_enabled()) {
1033 isolate->optimizing_compile_dispatcher()->WaitUntilCompilationJobsDone();
1034#if V8_ENABLE_MAGLEV
1035 if (isolate->maglev_concurrent_dispatcher()->is_enabled()) {
1036 isolate->maglev_concurrent_dispatcher()->AwaitCompileJobs();
1037 }
1038#endif // V8_ENABLE_MAGLEV
1039 }
1040 return ReadOnlyRoots(isolate).undefined_value();
1041}
1042
1043RUNTIME_FUNCTION(Runtime_FinalizeOptimization) {
1044 if (isolate->concurrent_recompilation_enabled()) {
1045 FinalizeOptimization(isolate);
1046 }
1047 return ReadOnlyRoots(isolate).undefined_value();
1048}
1049
1050RUNTIME_FUNCTION(Runtime_ForceFlush) {
1051 HandleScope scope(isolate);
1052 if (args.length() != 1) return CrashUnlessFuzzing(isolate);
1053
1054 Handle<Object> function_object = args.at(0);
1055 if (!IsJSFunction(*function_object)) return CrashUnlessFuzzing(isolate);
1056 auto function = Cast<JSFunction>(function_object);
1057 Tagged<SharedFunctionInfo> sfi = function->shared(isolate);
1058
1059 // Don't try to flush functions that cannot be flushed.
1060 if (!sfi->CanDiscardCompiled()) {
1061 return CrashUnlessFuzzing(isolate);
1062 }
1063
1064 // Don't flush functions that are active on the stack.
1065 for (JavaScriptStackFrameIterator frame_it(isolate); !frame_it.done();
1066 frame_it.Advance()) {
1067 std::vector<Tagged<SharedFunctionInfo>> infos;
1068 frame_it.frame()->GetFunctions(&infos);
1069 for (auto infos_it = infos.rbegin(); infos_it != infos.rend(); ++infos_it) {
1070 if ((*infos_it) == sfi) return CrashUnlessFuzzing(isolate);
1071 }
1072 }
1073
1074 SharedFunctionInfo::DiscardCompiled(isolate, direct_handle(sfi, isolate));
1075 function->ResetIfCodeFlushed(isolate);
1076 return ReadOnlyRoots(isolate).undefined_value();
1077}
1078
1081 info.GetReturnValue().SetNull();
1082}
1083
1084RUNTIME_FUNCTION(Runtime_GetUndetectable) {
1085 HandleScope scope(isolate);
1086 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
1088 desc->MarkAsUndetectable();
1089 desc->SetCallAsFunctionHandler(ReturnNull);
1090 Local<v8::Object> obj =
1091 desc->NewInstance(v8_isolate->GetCurrentContext()).ToLocalChecked();
1092 return *Utils::OpenDirectHandle(*obj);
1093}
1094
1095namespace {
1096// Does globalThis[target_function_name](...args).
1097void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& info) {
1099 v8::Isolate* isolate = info.GetIsolate();
1100 auto context = isolate->GetCurrentContext();
1101 auto global = context->Global();
1102 auto target_function_name = info.Data().As<v8::String>();
1104 {
1106 if (!global->Get(context, target_function_name).ToLocal(&result)) {
1107 return;
1108 }
1109 if (!result->IsFunction()) {
1110 isolate->ThrowError("Target function is not callable");
1111 return;
1112 }
1113 target = result.As<Function>();
1114 }
1115 int argc = info.Length();
1116 v8::LocalVector<v8::Value> args(isolate, argc);
1117 for (int i = 0; i < argc; i++) {
1118 args[i] = info[i];
1119 }
1120 Local<Value> result;
1121 if (!target->Call(context, info.This(), argc, args.data()).ToLocal(&result)) {
1122 return;
1123 }
1124 info.GetReturnValue().Set(result);
1125}
1126} // namespace
1127
1128RUNTIME_FUNCTION(Runtime_GetAbstractModuleSource) {
1129 // This isn't exposed to fuzzers. Crash if the native context is been
1130 // modified.
1131 HandleScope scope(isolate);
1133 Tagged<JSFunction> abstract_module_source_function =
1134 isolate->native_context()->abstract_module_source_function();
1135 CHECK(IsJSFunction(*abstract_module_source_function));
1136 return abstract_module_source_function;
1137}
1138
1139// Returns a callable object which redirects [[Call]] requests to
1140// globalThis[target_function_name] function.
1141RUNTIME_FUNCTION(Runtime_GetCallable) {
1142 HandleScope scope(isolate);
1143 if (args.length() != 1) {
1144 return CrashUnlessFuzzing(isolate);
1145 }
1146 DirectHandle<String> target_function_name = args.at<String>(0);
1147 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
1149 Local<v8::ObjectTemplate> instance_template = t->InstanceTemplate();
1150 instance_template->SetCallAsFunctionHandler(
1151 call_as_function, v8::Utils::ToLocal(target_function_name));
1152 v8_isolate->GetCurrentContext();
1153 Local<v8::Object> instance =
1154 t->GetFunction(v8_isolate->GetCurrentContext())
1155 .ToLocalChecked()
1156 ->NewInstance(v8_isolate->GetCurrentContext())
1157 .ToLocalChecked();
1158 return *Utils::OpenDirectHandle(*instance);
1159}
1160
1161RUNTIME_FUNCTION(Runtime_ClearFunctionFeedback) {
1162 HandleScope scope(isolate);
1163 // This isn't exposed to fuzzers so doesn't need to handle invalid arguments.
1164 DCHECK_EQ(args.length(), 1);
1165 DirectHandle<JSFunction> function = args.at<JSFunction>(0);
1167 // Typically tests use this function to start from scratch. Thus, we should
1168 // also clear tiering requests.
1169 function->ResetTieringRequests();
1170 return ReadOnlyRoots(isolate).undefined_value();
1171}
1172
1173RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
1174 HandleScope scope(isolate);
1175 isolate->heap()->NotifyContextDisposed(true);
1176 return ReadOnlyRoots(isolate).undefined_value();
1177}
1178
1179RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
1180 SealHandleScope shs(isolate);
1181 if (args.length() != 2 && args.length() != 3) {
1182 return CrashUnlessFuzzing(isolate);
1183 }
1184#ifdef V8_ENABLE_ALLOCATION_TIMEOUT
1185 CONVERT_INT32_ARG_FUZZ_SAFE(interval, 0);
1186 HeapAllocator::SetAllocationGcInterval(interval);
1187 CONVERT_INT32_ARG_FUZZ_SAFE(timeout, 1);
1188 isolate->heap()->set_allocation_timeout(timeout);
1189#endif
1190#ifdef DEBUG
1191 if (args.length() == 3) {
1192 // Enable/disable inline allocation if requested.
1193 CONVERT_BOOLEAN_ARG_FUZZ_SAFE(inline_allocation, 2);
1194 if (inline_allocation) {
1195 isolate->heap()->EnableInlineAllocation();
1196 } else {
1197 isolate->heap()->DisableInlineAllocation();
1198 }
1199 }
1200#endif
1201 return ReadOnlyRoots(isolate).undefined_value();
1202}
1203
1204namespace {
1205
1206int FixedArrayLenFromSize(int size) {
1207 return std::min({(size - OFFSET_OF_DATA_START(FixedArray)) / kTaggedSize,
1209}
1210
1211void FillUpOneNewSpacePage(Isolate* isolate, Heap* heap,
1212 SemiSpaceNewSpace* space) {
1213 DCHECK(!v8_flags.single_generation);
1214 heap->FreeMainThreadLinearAllocationAreas();
1215 PauseAllocationObserversScope pause_observers(heap);
1216 while (space->GetSpaceRemainingOnCurrentPageForTesting() > 0) {
1217 int space_remaining = space->GetSpaceRemainingOnCurrentPageForTesting();
1218 int length = FixedArrayLenFromSize(space_remaining);
1219 if (length > 0) {
1220 DirectHandle<FixedArray> padding =
1221 isolate->factory()->NewFixedArray(length, AllocationType::kYoung);
1222 DCHECK(heap->new_space()->Contains(*padding));
1223 space_remaining -= padding->Size();
1224 } else {
1225 // Not enough room to create another fixed array. Create a filler instead.
1226 space->FillCurrentPageForTesting();
1227 }
1228 heap->FreeMainThreadLinearAllocationAreas();
1229 }
1230}
1231
1232} // namespace
1233
1234RUNTIME_FUNCTION(Runtime_SimulateNewspaceFull) {
1235 HandleScope scope(isolate);
1236 Heap* heap = isolate->heap();
1237 heap->FreeMainThreadLinearAllocationAreas();
1238 AlwaysAllocateScopeForTesting always_allocate(heap);
1239 if (v8_flags.minor_ms) {
1240 if (heap->minor_sweeping_in_progress()) {
1241 heap->EnsureYoungSweepingCompleted();
1242 }
1243 auto* space = heap->paged_new_space()->paged_space();
1244 space->AllocatePageUpToCapacityForTesting();
1245 space->ResetFreeList();
1246 } else {
1247 SemiSpaceNewSpace* space = heap->semi_space_new_space();
1248 do {
1249 FillUpOneNewSpacePage(isolate, heap, space);
1250 } while (space->AddFreshPage());
1251 }
1252 return ReadOnlyRoots(isolate).undefined_value();
1253}
1254
1255RUNTIME_FUNCTION(Runtime_ScheduleGCInStackCheck) {
1256 SealHandleScope shs(isolate);
1257 isolate->RequestInterrupt(
1258 [](v8::Isolate* isolate, void*) {
1259 isolate->RequestGarbageCollectionForTesting(
1261 },
1262 nullptr);
1263 return ReadOnlyRoots(isolate).undefined_value();
1264}
1265
1266RUNTIME_FUNCTION(Runtime_TakeHeapSnapshot) {
1267 if (v8_flags.fuzzing) {
1268 // We don't want to create snapshots in fuzzers.
1269 return ReadOnlyRoots(isolate).undefined_value();
1270 }
1271
1272 std::string filename = "heap.heapsnapshot";
1273
1274 if (args.length() >= 1) {
1275 HandleScope hs(isolate);
1276 DirectHandle<String> filename_as_js_string = args.at<String>(0);
1277 std::unique_ptr<char[]> buffer = filename_as_js_string->ToCString();
1278 filename = std::string(buffer.get());
1279 }
1280
1281 HeapProfiler* heap_profiler = isolate->heap()->heap_profiler();
1282 // Since this API is intended for V8 devs, we do not treat globals as roots
1283 // here on purpose.
1287 heap_profiler->TakeSnapshotToFile(options, filename);
1288 return ReadOnlyRoots(isolate).undefined_value();
1289}
1290
1291static void DebugPrintImpl(Tagged<MaybeObject> maybe_object, std::ostream& os) {
1292 if (maybe_object.IsCleared()) {
1293 os << "[weak cleared]";
1294 } else {
1295 Tagged<Object> object = maybe_object.GetHeapObjectOrSmi();
1296 bool weak = maybe_object.IsWeak();
1297
1298#ifdef OBJECT_PRINT
1299 os << "DebugPrint: ";
1300 if (weak) os << "[weak] ";
1301 Print(object, os);
1302 if (IsHeapObject(object)) {
1303 Print(Cast<HeapObject>(object)->map(), os);
1304 }
1305#else
1306 if (weak) os << "[weak] ";
1307 // ShortPrint is available in release mode. Print is not.
1308 os << Brief(object);
1309#endif
1310 }
1311 os << std::endl;
1312}
1313
1314RUNTIME_FUNCTION(Runtime_DebugPrint) {
1315 SealHandleScope shs(isolate);
1316
1317 if (args.length() == 0) {
1318 // This runtime method has variable number of arguments, but if there is no
1319 // argument, undefined behavior may happen.
1320 return ReadOnlyRoots(isolate).undefined_value();
1321 }
1322
1323 // This is exposed to tests / fuzzers; handle variable arguments gracefully.
1324 std::unique_ptr<std::ostream> output_stream(new StdoutStream());
1325 if (args.length() >= 2) {
1326 // Args: object, stream.
1327 if (IsSmi(args[1])) {
1328 int output_int = Cast<Smi>(args[1]).value();
1329 if (output_int == fileno(stderr)) {
1330 output_stream.reset(new StderrStream());
1331 }
1332 }
1333 }
1334
1335 Tagged<MaybeObject> maybe_object(*args.address_of_arg_at(0));
1336 DebugPrintImpl(maybe_object, *output_stream);
1337 return args[0];
1338}
1339
1340RUNTIME_FUNCTION(Runtime_DebugPrintPtr) {
1341 SealHandleScope shs(isolate);
1342 StdoutStream os;
1343 if (args.length() != 1) {
1344 return CrashUnlessFuzzing(isolate);
1345 }
1346
1347 Tagged<MaybeObject> maybe_object(*args.address_of_arg_at(0));
1348 if (!maybe_object.IsCleared()) {
1349 Tagged<Object> object = maybe_object.GetHeapObjectOrSmi();
1350 size_t pointer;
1351 if (Object::ToIntegerIndex(object, &pointer)) {
1352 Tagged<MaybeObject> from_pointer(static_cast<Address>(pointer));
1353 DebugPrintImpl(from_pointer, os);
1354 }
1355 }
1356 // We don't allow the converted pointer to leak out to JavaScript.
1357 return args[0];
1358}
1359
1360RUNTIME_FUNCTION(Runtime_DebugPrintWord) {
1361 static constexpr int kNum16BitChunks = 4;
1362 SealHandleScope shs(isolate);
1363
1364 // Args are: <bits 63-48>, <bits 47-32>, <bits 31-16>, <bits 15-0>, stream.
1365 if (args.length() != kNum16BitChunks + 1) {
1366 return CrashUnlessFuzzing(isolate);
1367 }
1368
1369 uint64_t value = 0;
1370 for (int i = 0; i < kNum16BitChunks; ++i) {
1371 value <<= 16;
1372 CHECK(IsSmi(args[i]));
1373 uint32_t chunk = Cast<Smi>(args[i]).value();
1374 // We encode 16 bit per chunk only!
1375 CHECK_EQ(chunk & 0xFFFF0000, 0);
1376 value |= chunk;
1377 }
1378
1379 if (!IsSmi(args[4]) || (Cast<Smi>(args[4]).value() == fileno(stderr))) {
1380 StderrStream os;
1381 os << "0x" << std::hex << value << std::dec << std::endl;
1382 } else {
1383 StdoutStream os;
1384 os << "0x" << std::hex << value << std::dec << std::endl;
1385 }
1386 return ReadOnlyRoots(isolate).undefined_value();
1387}
1388
1389RUNTIME_FUNCTION(Runtime_DebugPrintFloat) {
1390 static constexpr int kNum16BitChunks = 4;
1391 SealHandleScope shs(isolate);
1392
1393 // Args are: <bits 63-48>, <bits 47-32>, <bits 31-16>, <bits 15-0>, stream.
1394 if (args.length() != kNum16BitChunks + 1) {
1395 return CrashUnlessFuzzing(isolate);
1396 }
1397
1398 uint64_t value = 0;
1399 for (int i = 0; i < kNum16BitChunks; ++i) {
1400 value <<= 16;
1401 CHECK(IsSmi(args[i]));
1402 uint32_t chunk = Cast<Smi>(args[i]).value();
1403 // We encode 16 bit per chunk only!
1404 CHECK_EQ(chunk & 0xFFFF0000, 0);
1405 value |= chunk;
1406 }
1407
1408 if (!IsSmi(args[4]) || (Cast<Smi>(args[4]).value() == fileno(stderr))) {
1409 StderrStream os;
1410 std::streamsize precision = os.precision();
1411 os << std::setprecision(20) << base::bit_cast<double>(value) << std::endl;
1412 os.precision(precision);
1413 } else {
1414 StdoutStream os;
1415 std::streamsize precision = os.precision();
1416 os << std::setprecision(20) << base::bit_cast<double>(value) << std::endl;
1417 os.precision(precision);
1418 }
1419 return ReadOnlyRoots(isolate).undefined_value();
1420}
1421
1422RUNTIME_FUNCTION(Runtime_PrintWithNameForAssert) {
1423 SealHandleScope shs(isolate);
1424 if (args.length() != 2) {
1425 return CrashUnlessFuzzing(isolate);
1426 }
1427
1428 if (!IsString(args[0])) return CrashUnlessFuzzing(isolate);
1429 auto name = Cast<String>(args[0]);
1430
1431 PrintF(" * ");
1432 StringCharacterStream stream(name);
1433 while (stream.HasMore()) {
1434 uint16_t character = stream.GetNext();
1435 PrintF("%c", character);
1436 }
1437 PrintF(": ");
1438 ShortPrint(args[1]);
1439 PrintF("\n");
1440
1441 return ReadOnlyRoots(isolate).undefined_value();
1442}
1443
1444RUNTIME_FUNCTION(Runtime_DebugTrace) {
1445 SealHandleScope shs(isolate);
1446 isolate->PrintStack(stdout);
1447 return ReadOnlyRoots(isolate).undefined_value();
1448}
1449
1450// This will not allocate (flatten the string), but it may run
1451// very slowly for very deeply nested ConsStrings. For debugging use only.
1452RUNTIME_FUNCTION(Runtime_GlobalPrint) {
1453 SealHandleScope shs(isolate);
1454
1455 // This is exposed to tests / fuzzers; handle variable arguments gracefully.
1456 FILE* output_stream = stdout;
1457 if (args.length() >= 2) {
1458 // Args: object, stream.
1459 if (IsSmi(args[1])) {
1460 int output_int = Cast<Smi>(args[1]).value();
1461 if (output_int == fileno(stderr)) {
1462 output_stream = stderr;
1463 }
1464 }
1465 }
1466
1467 if (!IsString(args[0])) {
1468 return args[0];
1469 }
1470
1471 auto string = Cast<String>(args[0]);
1472 StringCharacterStream stream(string);
1473 while (stream.HasMore()) {
1474 uint16_t character = stream.GetNext();
1475 PrintF(output_stream, "%c", character);
1476 }
1477 fflush(output_stream);
1478 return string;
1479}
1480
1481RUNTIME_FUNCTION(Runtime_SystemBreak) {
1482 // The code below doesn't create handles, but when breaking here in GDB
1483 // having a handle scope might be useful.
1484 HandleScope scope(isolate);
1486 return ReadOnlyRoots(isolate).undefined_value();
1487}
1488
1489RUNTIME_FUNCTION(Runtime_SetForceSlowPath) {
1490 SealHandleScope shs(isolate);
1491 if (args.length() != 1) {
1492 return CrashUnlessFuzzing(isolate);
1493 }
1494 Tagged<Object> arg = args[0];
1495 if (IsTrue(arg, isolate)) {
1496 isolate->set_force_slow_path(true);
1497 } else {
1498 // This function is fuzzer exposed and as such we might not always have an
1499 // input that IsTrue or IsFalse. In these cases we assume that if !IsTrue
1500 // then it IsFalse when fuzzing.
1501 DCHECK(IsFalse(arg, isolate) || v8_flags.fuzzing);
1502 isolate->set_force_slow_path(false);
1503 }
1504 return ReadOnlyRoots(isolate).undefined_value();
1505}
1506
1507RUNTIME_FUNCTION(Runtime_Abort) {
1508 SealHandleScope shs(isolate);
1509 if (args.length() != 1) {
1510 return CrashUnlessFuzzing(isolate);
1511 }
1512 int message_id = args.smi_value_at(0);
1513 const char* message = GetAbortReason(static_cast<AbortReason>(message_id));
1514 base::OS::PrintError("abort: %s\n", message);
1515 isolate->PrintStack(stderr);
1517 UNREACHABLE();
1518}
1519
1520RUNTIME_FUNCTION(Runtime_AbortJS) {
1521 HandleScope scope(isolate);
1522 if (args.length() != 1) {
1523 return CrashUnlessFuzzing(isolate);
1524 }
1525 DirectHandle<String> message = args.at<String>(0);
1526 if (v8_flags.disable_abortjs) {
1527 base::OS::PrintError("[disabled] abort: %s\n", message->ToCString().get());
1528 return Tagged<Object>();
1529 }
1530 base::OS::PrintError("abort: %s\n", message->ToCString().get());
1531 isolate->PrintStack(stderr);
1533 UNREACHABLE();
1534}
1535
1536RUNTIME_FUNCTION(Runtime_AbortCSADcheck) {
1537 HandleScope scope(isolate);
1538 if (args.length() != 1) {
1539 return CrashUnlessFuzzing(isolate);
1540 }
1541 DirectHandle<String> message = args.at<String>(0);
1543 base::OS::PrintError(
1544 "Safely terminating process due to CSA check failure\n");
1545 // Also prefix the error message (printed below). This has two purposes:
1546 // (1) it makes it clear that this error is deemed "safe" (2) it causes
1547 // fuzzers that pattern-match on stderr output to ignore these failures.
1548 base::OS::PrintError("The following harmless failure was encountered: %s\n",
1549 message->ToCString().get());
1550 } else {
1551 base::OS::PrintError("abort: CSA_DCHECK failed: %s\n",
1552 message->ToCString().get());
1553 isolate->PrintStack(stderr);
1554 }
1556 UNREACHABLE();
1557}
1558
1559RUNTIME_FUNCTION(Runtime_DisassembleFunction) {
1560 HandleScope scope(isolate);
1561#ifdef DEBUG
1562 if (args.length() != 1) {
1563 return CrashUnlessFuzzing(isolate);
1564 }
1565 // Get the function and make sure it is compiled.
1567 IsCompiledScope is_compiled_scope;
1568#ifndef V8_ENABLE_LEAPTIERING
1569 if (!func->is_compiled(isolate) && func->HasAvailableOptimizedCode(isolate)) {
1570 func->UpdateOptimizedCode(isolate,
1571 func->feedback_vector()->optimized_code(isolate));
1572 }
1573#endif // !V8_ENABLE_LEAPTIERING
1574 CHECK(func->shared()->is_compiled() ||
1576 &is_compiled_scope));
1577 StdoutStream os;
1578 Print(func->code(isolate), os);
1579 os << std::endl;
1580#endif // DEBUG
1581 return ReadOnlyRoots(isolate).undefined_value();
1582}
1583
1584namespace {
1585
1586int StackSize(Isolate* isolate) {
1587 int n = 0;
1588 for (JavaScriptStackFrameIterator it(isolate); !it.done(); it.Advance()) n++;
1589 return n;
1590}
1591
1592void PrintIndentation(int stack_size) {
1593 const int max_display = 80;
1594 if (stack_size <= max_display) {
1595 PrintF("%4d:%*s", stack_size, stack_size, "");
1596 } else {
1597 PrintF("%4d:%*s", stack_size, max_display, "...");
1598 }
1599}
1600
1601} // namespace
1602
1603RUNTIME_FUNCTION(Runtime_TraceEnter) {
1604 SealHandleScope shs(isolate);
1605 PrintIndentation(StackSize(isolate));
1606 JavaScriptFrame::PrintTop(isolate, stdout, true, false);
1607 PrintF(" {\n");
1608 return ReadOnlyRoots(isolate).undefined_value();
1609}
1610
1611RUNTIME_FUNCTION(Runtime_TraceExit) {
1612 SealHandleScope shs(isolate);
1613 if (args.length() != 1) {
1614 return CrashUnlessFuzzing(isolate);
1615 }
1616 Tagged<Object> obj = args[0];
1617 PrintIndentation(StackSize(isolate));
1618 PrintF("} -> ");
1619 ShortPrint(obj);
1620 PrintF("\n");
1621 return obj; // return TOS
1622}
1623
1624RUNTIME_FUNCTION(Runtime_HaveSameMap) {
1625 SealHandleScope shs(isolate);
1626 if (args.length() != 2) {
1627 return CrashUnlessFuzzing(isolate);
1628 }
1629 if (IsSmi(args[0]) || IsSmi(args[1])) {
1630 return CrashUnlessFuzzing(isolate);
1631 }
1632 auto obj1 = Cast<HeapObject>(args[0]);
1633 auto obj2 = Cast<HeapObject>(args[1]);
1634 return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
1635}
1636
1637RUNTIME_FUNCTION(Runtime_InLargeObjectSpace) {
1638 SealHandleScope shs(isolate);
1639 if (args.length() != 1 || !IsHeapObject(args[0])) {
1640 return CrashUnlessFuzzing(isolate);
1641 }
1642 auto obj = Cast<HeapObject>(args[0]);
1643 return isolate->heap()->ToBoolean(
1644 isolate->heap()->new_lo_space()->Contains(obj) ||
1645 isolate->heap()->code_lo_space()->Contains(obj) ||
1646 isolate->heap()->lo_space()->Contains(obj));
1647}
1648
1649RUNTIME_FUNCTION(Runtime_HasElementsInALargeObjectSpace) {
1650 SealHandleScope shs(isolate);
1651 if (args.length() != 1 || !IsJSArray(args[0])) {
1652 return CrashUnlessFuzzing(isolate);
1653 }
1654 auto array = Cast<JSArray>(args[0]);
1655 Tagged<FixedArrayBase> elements = array->elements();
1656 return isolate->heap()->ToBoolean(
1657 isolate->heap()->new_lo_space()->Contains(elements) ||
1658 isolate->heap()->lo_space()->Contains(elements));
1659}
1660
1661RUNTIME_FUNCTION(Runtime_HasCowElements) {
1662 SealHandleScope shs(isolate);
1663 if (args.length() != 1 || !IsJSArray(args[0])) {
1664 return CrashUnlessFuzzing(isolate);
1665 }
1666 auto array = Cast<JSArray>(args[0]);
1667 Tagged<FixedArrayBase> elements = array->elements();
1668 return isolate->heap()->ToBoolean(elements->IsCowArray());
1669}
1670
1671RUNTIME_FUNCTION(Runtime_InYoungGeneration) {
1672 SealHandleScope shs(isolate);
1673 if (args.length() != 1) {
1674 return CrashUnlessFuzzing(isolate);
1675 }
1676 Tagged<Object> obj = args[0];
1677 return isolate->heap()->ToBoolean(HeapLayout::InYoungGeneration(obj));
1678}
1679
1680// Force pretenuring for the allocation site the passed object belongs to.
1681RUNTIME_FUNCTION(Runtime_PretenureAllocationSite) {
1683
1684 if (args.length() != 1) return CrashUnlessFuzzing(isolate);
1685 Tagged<Object> arg = args[0];
1686 if (!IsJSObject(arg)) return CrashUnlessFuzzing(isolate);
1687 Tagged<JSObject> object = Cast<JSObject>(arg);
1688
1689 Heap* heap = object->GetHeap();
1690 if (!v8_flags.sticky_mark_bits && !HeapLayout::InYoungGeneration(object)) {
1691 // Object is not in new space, thus there is no memento and nothing to do.
1692 return ReturnFuzzSafe(ReadOnlyRoots(isolate).false_value(), isolate);
1693 }
1694
1695 PretenuringHandler* pretenuring_handler = heap->pretenuring_handler();
1697 PretenuringHandler::kForRuntime>(heap, object->map(), object);
1698 if (memento.is_null())
1699 return ReturnFuzzSafe(ReadOnlyRoots(isolate).false_value(), isolate);
1700 Tagged<AllocationSite> site = memento->GetAllocationSite();
1701 pretenuring_handler->PretenureAllocationSiteOnNextCollection(site);
1702 return ReturnFuzzSafe(ReadOnlyRoots(isolate).true_value(), isolate);
1703}
1704
1705namespace {
1706
1707v8::ModifyCodeGenerationFromStringsResult DisallowCodegenFromStringsCallback(
1709 bool is_code_kind) {
1710 return {false, {}};
1711}
1712
1713} // namespace
1714
1715RUNTIME_FUNCTION(Runtime_DisallowCodegenFromStrings) {
1716 SealHandleScope shs(isolate);
1717 if (args.length() != 1) {
1718 return CrashUnlessFuzzing(isolate);
1719 }
1720 bool flag = Cast<Boolean>(args[0])->ToBool(isolate);
1721 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
1723 flag ? DisallowCodegenFromStringsCallback : nullptr);
1724 return ReadOnlyRoots(isolate).undefined_value();
1725}
1726
1727RUNTIME_FUNCTION(Runtime_RegexpHasBytecode) {
1728 SealHandleScope shs(isolate);
1729 if (args.length() != 2 || !IsJSRegExp(args[0]) || !IsBoolean(args[1])) {
1730 return CrashUnlessFuzzing(isolate);
1731 }
1732 auto regexp = args.at<JSRegExp>(0);
1733 bool is_latin1 = args.at<Boolean>(1)->ToBool(isolate);
1734 bool result = false;
1735 if (regexp->has_data()) {
1736 Tagged<RegExpData> data = regexp->data(isolate);
1737 if (data->type_tag() == RegExpData::Type::IRREGEXP) {
1738 result = Cast<IrRegExpData>(data)->has_bytecode(is_latin1);
1739 }
1740 }
1741 return isolate->heap()->ToBoolean(result);
1742}
1743
1744RUNTIME_FUNCTION(Runtime_RegexpHasNativeCode) {
1745 SealHandleScope shs(isolate);
1746 if (args.length() != 2 || !IsJSRegExp(args[0]) || !IsBoolean(args[1])) {
1747 return CrashUnlessFuzzing(isolate);
1748 }
1749 auto regexp = args.at<JSRegExp>(0);
1750 bool is_latin1 = args.at<Boolean>(1)->ToBool(isolate);
1751 bool result = false;
1752 if (regexp->has_data()) {
1753 Tagged<RegExpData> data = regexp->data(isolate);
1754 if (data->type_tag() == RegExpData::Type::IRREGEXP) {
1755 result = Cast<IrRegExpData>(data)->has_code(is_latin1);
1756 }
1757 }
1758 return isolate->heap()->ToBoolean(result);
1759}
1760
1761RUNTIME_FUNCTION(Runtime_RegexpTypeTag) {
1762 HandleScope shs(isolate);
1763 if (args.length() != 1 || !IsJSRegExp(args[0])) {
1764 return CrashUnlessFuzzing(isolate);
1765 }
1766 auto regexp = Cast<JSRegExp>(args[0]);
1767 const char* type_str;
1768 if (regexp->has_data()) {
1769 switch (regexp->data(isolate)->type_tag()) {
1771 type_str = "ATOM";
1772 break;
1774 type_str = "IRREGEXP";
1775 break;
1777 type_str = "EXPERIMENTAL";
1778 break;
1779 default:
1780 UNREACHABLE();
1781 }
1782 } else {
1783 type_str = "NOT_COMPILED";
1784 }
1785 return *isolate->factory()->NewStringFromAsciiChecked(type_str);
1786}
1787
1788RUNTIME_FUNCTION(Runtime_RegexpIsUnmodified) {
1789 HandleScope shs(isolate);
1790 if (args.length() != 1 || !IsJSRegExp(args[0])) {
1791 return CrashUnlessFuzzing(isolate);
1792 }
1793 DirectHandle<JSRegExp> regexp = args.at<JSRegExp>(0);
1794 return isolate->heap()->ToBoolean(
1795 RegExp::IsUnmodifiedRegExp(isolate, regexp));
1796}
1797
1798#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
1799 RUNTIME_FUNCTION(Runtime_##Name) { \
1800 if (args.length() != 1 || !IsJSObject(args[0])) { \
1801 return CrashUnlessFuzzing(isolate); \
1802 } \
1803 auto obj = args.at<JSObject>(0); \
1804 return isolate->heap()->ToBoolean(obj->Name()); \
1805 }
1806
1809ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HasObjectElements)
1810ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HasSmiOrObjectElements)
1811ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HasDoubleElements)
1813ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HasDictionaryElements)
1814ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HasPackedElements)
1815ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HasSloppyArgumentsElements)
1816// Properties test sitting with elements tests - not fooling anyone.
1817ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HasFastProperties)
1818
1819#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
1820
1821#define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype) \
1822 RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \
1823 if (args.length() != 1 || !IsJSObject(args[0])) { \
1824 return CrashUnlessFuzzing(isolate); \
1825 } \
1826 auto obj = Cast<JSObject>(args[0]); \
1827 return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \
1828 }
1829
1831
1832#undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
1833
1834RUNTIME_FUNCTION(Runtime_IsConcatSpreadableProtector) {
1835 SealHandleScope shs(isolate);
1836 return isolate->heap()->ToBoolean(
1837 Protectors::IsIsConcatSpreadableLookupChainIntact(isolate));
1838}
1839
1840RUNTIME_FUNCTION(Runtime_TypedArrayLengthProtector) {
1841 SealHandleScope shs(isolate);
1842 return isolate->heap()->ToBoolean(
1843 Protectors::IsTypedArrayLengthLookupChainIntact(isolate));
1844}
1845
1846RUNTIME_FUNCTION(Runtime_TypedArraySpeciesProtector) {
1847 SealHandleScope shs(isolate);
1848 return isolate->heap()->ToBoolean(
1849 Protectors::IsTypedArraySpeciesLookupChainIntact(isolate));
1850}
1851
1852RUNTIME_FUNCTION(Runtime_RegExpSpeciesProtector) {
1853 SealHandleScope shs(isolate);
1854 return isolate->heap()->ToBoolean(
1855 Protectors::IsRegExpSpeciesLookupChainIntact(isolate));
1856}
1857
1858RUNTIME_FUNCTION(Runtime_PromiseSpeciesProtector) {
1859 SealHandleScope shs(isolate);
1860 return isolate->heap()->ToBoolean(
1861 Protectors::IsPromiseSpeciesLookupChainIntact(isolate));
1862}
1863
1864RUNTIME_FUNCTION(Runtime_ArraySpeciesProtector) {
1865 SealHandleScope shs(isolate);
1866 return isolate->heap()->ToBoolean(
1867 Protectors::IsArraySpeciesLookupChainIntact(isolate));
1868}
1869
1870RUNTIME_FUNCTION(Runtime_MapIteratorProtector) {
1871 SealHandleScope shs(isolate);
1872 return isolate->heap()->ToBoolean(
1873 Protectors::IsMapIteratorLookupChainIntact(isolate));
1874}
1875
1876RUNTIME_FUNCTION(Runtime_SetIteratorProtector) {
1877 SealHandleScope shs(isolate);
1878 return isolate->heap()->ToBoolean(
1879 Protectors::IsSetIteratorLookupChainIntact(isolate));
1880}
1881
1882RUNTIME_FUNCTION(Runtime_StringIteratorProtector) {
1883 SealHandleScope shs(isolate);
1884 return isolate->heap()->ToBoolean(
1885 Protectors::IsStringIteratorLookupChainIntact(isolate));
1886}
1887
1888RUNTIME_FUNCTION(Runtime_ArrayIteratorProtector) {
1889 SealHandleScope shs(isolate);
1890 return isolate->heap()->ToBoolean(
1891 Protectors::IsArrayIteratorLookupChainIntact(isolate));
1892}
1893
1894RUNTIME_FUNCTION(Runtime_NoElementsProtector) {
1895 SealHandleScope shs(isolate);
1896 return isolate->heap()->ToBoolean(Protectors::IsNoElementsIntact(isolate));
1897}
1898
1899RUNTIME_FUNCTION(Runtime_StringWrapperToPrimitiveProtector) {
1900 SealHandleScope shs(isolate);
1901 return isolate->heap()->ToBoolean(
1902 Protectors::IsStringWrapperToPrimitiveIntact(isolate));
1903}
1904
1905// For use by tests and fuzzers. It
1906//
1907// 1. serializes a snapshot of the current isolate,
1908// 2. deserializes the snapshot,
1909// 3. and runs VerifyHeap on the resulting isolate.
1910//
1911// The current isolate should not be modified by this call and can keep running
1912// once it completes.
1913RUNTIME_FUNCTION(Runtime_SerializeDeserializeNow) {
1914 // TODO(353971258): This function is not currently exposed to fuzzers.
1915 // Investigate if it should be.
1916 HandleScope scope(isolate);
1918 isolate->native_context());
1919 return ReadOnlyRoots(isolate).undefined_value();
1920}
1921
1922RUNTIME_FUNCTION(Runtime_HeapObjectVerify) {
1923 HandleScope shs(isolate);
1924 if (args.length() != 1) {
1925 return CrashUnlessFuzzing(isolate);
1926 }
1927 DirectHandle<Object> object = args.at(0);
1928#ifdef VERIFY_HEAP
1929 Object::ObjectVerify(*object, isolate);
1930#else
1931 CHECK(IsObject(*object));
1932 if (IsHeapObject(*object)) {
1933 CHECK(IsMap(Cast<HeapObject>(*object)->map()));
1934 } else {
1935 CHECK(IsSmi(*object));
1936 }
1937#endif
1938 return isolate->heap()->ToBoolean(true);
1939}
1940
1941RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTracking) {
1942 // TODO(353928347): This function is not currently exposed to fuzzers.
1943 // Investigate if it should be.
1944 HandleScope scope(isolate);
1945 if (args.length() != 1 || !IsJSObject(args[0])) {
1946 return CrashUnlessFuzzing(isolate);
1947 }
1948
1949 DirectHandle<JSObject> object = args.at<JSObject>(0);
1950 MapUpdater::CompleteInobjectSlackTracking(isolate, object->map());
1951
1952 return ReadOnlyRoots(isolate).undefined_value();
1953}
1954
1955RUNTIME_FUNCTION(Runtime_TurbofanStaticAssert) {
1956 SealHandleScope shs(isolate);
1957 // Always lowered to StaticAssert node in Turbofan, so we never get here in
1958 // compiled code.
1959 return ReadOnlyRoots(isolate).undefined_value();
1960}
1961
1962RUNTIME_FUNCTION(Runtime_IsBeingInterpreted) {
1963 SealHandleScope shs(isolate);
1964 // Always lowered to false in Turbofan, so we never get here in compiled code.
1965 return ReadOnlyRoots(isolate).true_value();
1966}
1967
1968RUNTIME_FUNCTION(Runtime_EnableCodeLoggingForTesting) {
1969 // The {NoopListener} currently does nothing on any callback, but reports
1970 // {true} on {is_listening_to_code_events()}. Feel free to add assertions to
1971 // any method to further test the code logging callbacks.
1972 class NoopListener final : public LogEventListener {
1973 void CodeCreateEvent(CodeTag tag, DirectHandle<AbstractCode> code,
1974 const char* name) final {}
1975 void CodeCreateEvent(CodeTag tag, DirectHandle<AbstractCode> code,
1976 DirectHandle<Name> name) final {}
1977 void CodeCreateEvent(CodeTag tag, DirectHandle<AbstractCode> code,
1979 DirectHandle<Name> script_name) final {}
1980 void CodeCreateEvent(CodeTag tag, DirectHandle<AbstractCode> code,
1982 DirectHandle<Name> script_name, int line,
1983 int column) final {}
1984#if V8_ENABLE_WEBASSEMBLY
1985 void CodeCreateEvent(CodeTag tag, const wasm::WasmCode* code,
1986 wasm::WasmName name, const char* source_url,
1987 int code_offset, int script_id) final {}
1988#endif // V8_ENABLE_WEBASSEMBLY
1989
1990 void CallbackEvent(DirectHandle<Name> name, Address entry_point) final {}
1991 void GetterCallbackEvent(DirectHandle<Name> name,
1992 Address entry_point) final {}
1993 void SetterCallbackEvent(DirectHandle<Name> name,
1994 Address entry_point) final {}
1995 void RegExpCodeCreateEvent(DirectHandle<AbstractCode> code,
1996 DirectHandle<String> source,
1997 RegExpFlags flags) final {}
1998 void CodeMoveEvent(Tagged<InstructionStream> from,
1999 Tagged<InstructionStream> to) final {}
2000 void BytecodeMoveEvent(Tagged<BytecodeArray> from,
2001 Tagged<BytecodeArray> to) final {}
2002 void SharedFunctionInfoMoveEvent(Address from, Address to) final {}
2003 void NativeContextMoveEvent(Address from, Address to) final {}
2004 void CodeMovingGCEvent() final {}
2005 void CodeDisableOptEvent(DirectHandle<AbstractCode> code,
2006 DirectHandle<SharedFunctionInfo> shared) final {}
2007 void CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind,
2008 Address pc, int fp_to_sp_delta) final {}
2009 void CodeDependencyChangeEvent(DirectHandle<Code> code,
2011 const char* reason) final {}
2012 void WeakCodeClearEvent() final {}
2013
2014 bool is_listening_to_code_events() final { return true; }
2015 };
2016 static base::LeakyObject<NoopListener> noop_listener;
2017#if V8_ENABLE_WEBASSEMBLY
2019#endif // V8_ENABLE_WEBASSEMBLY
2020 isolate->logger()->AddListener(noop_listener.get());
2021 return ReadOnlyRoots(isolate).undefined_value();
2022}
2023
2024RUNTIME_FUNCTION(Runtime_NewRegExpWithBacktrackLimit) {
2025 HandleScope scope(isolate);
2026 if (args.length() != 3 || !IsString(args[0]) || !IsString(args[1]) ||
2027 !IsSmi(args[2])) {
2028 return CrashUnlessFuzzing(isolate);
2029 }
2030
2032 DirectHandle<String> flags_string = args.at<String>(1);
2033 int backtrack_limit = args.smi_value_at(2);
2034 if (backtrack_limit < 0) {
2035 return CrashUnlessFuzzing(isolate);
2036 }
2037
2038 auto maybe_flags = JSRegExp::FlagsFromString(isolate, flags_string);
2039 if (!maybe_flags.has_value()) {
2040 return CrashUnlessFuzzing(isolate);
2041 }
2042 JSRegExp::Flags flags = maybe_flags.value();
2043
2045 isolate, JSRegExp::New(isolate, pattern, flags, backtrack_limit));
2046}
2047
2048RUNTIME_FUNCTION(Runtime_Is64Bit) {
2049 SealHandleScope shs(isolate);
2050 return isolate->heap()->ToBoolean(kSystemPointerSize == 8);
2051}
2052
2053RUNTIME_FUNCTION(Runtime_BigIntMaxLengthBits) {
2054 HandleScope scope(isolate);
2055 return *isolate->factory()->NewNumber(BigInt::kMaxLengthBits);
2056}
2057
2058RUNTIME_FUNCTION(Runtime_IsSameHeapObject) {
2059 HandleScope scope(isolate);
2060 if (args.length() != 2 || !IsHeapObject(args[0]) || !IsHeapObject(args[1])) {
2061 return CrashUnlessFuzzing(isolate);
2062 }
2065 return isolate->heap()->ToBoolean(obj1->address() == obj2->address());
2066}
2067
2068RUNTIME_FUNCTION(Runtime_IsSharedString) {
2069 HandleScope scope(isolate);
2070 if (args.length() != 1 || !IsHeapObject(args[0])) {
2071 return CrashUnlessFuzzing(isolate);
2072 }
2074 return isolate->heap()->ToBoolean(IsString(*obj) &&
2075 Cast<String>(obj)->IsShared());
2076}
2077
2078RUNTIME_FUNCTION(Runtime_ShareObject) {
2079 // TODO(354005312): This function is not currently exposed to fuzzers.
2080 // Investigate if it should be.
2081 HandleScope scope(isolate);
2082 if (args.length() != 1 || !IsHeapObject(args[0])) {
2083 return CrashUnlessFuzzing(isolate);
2084 }
2085 Handle<HeapObject> obj = args.at<HeapObject>(0);
2086 ShouldThrow should_throw = v8_flags.fuzzing ? kDontThrow : kThrowOnError;
2087 MaybeDirectHandle<Object> maybe_shared =
2088 Object::Share(isolate, obj, should_throw);
2090 if (!maybe_shared.ToHandle(&shared)) {
2091 return CrashUnlessFuzzing(isolate);
2092 }
2093 return *shared;
2094}
2095
2096RUNTIME_FUNCTION(Runtime_IsInPlaceInternalizableString) {
2097 HandleScope scope(isolate);
2098 if (args.length() != 1 || !IsHeapObject(args[0])) {
2099 return CrashUnlessFuzzing(isolate);
2100 }
2102 return isolate->heap()->ToBoolean(
2103 IsString(*obj) && String::IsInPlaceInternalizable(Cast<String>(*obj)));
2104}
2105
2106RUNTIME_FUNCTION(Runtime_IsInternalizedString) {
2107 HandleScope scope(isolate);
2108 if (args.length() != 1 || !IsHeapObject(args[0])) {
2109 return CrashUnlessFuzzing(isolate);
2110 }
2112 return isolate->heap()->ToBoolean(IsInternalizedString(*obj));
2113}
2114
2115RUNTIME_FUNCTION(Runtime_StringToCString) {
2116 HandleScope scope(isolate);
2117 if (args.length() != 1 || !IsString(args[0])) {
2118 return CrashUnlessFuzzing(isolate);
2119 }
2120 DirectHandle<String> string = args.at<String>(0);
2121
2122 size_t output_length;
2123 auto bytes = string->ToCString(&output_length);
2124
2126 isolate->factory()
2127 ->NewJSArrayBufferAndBackingStore(output_length,
2129 .ToHandleChecked();
2130 memcpy(result->backing_store(), bytes.get(), output_length);
2131 return *result;
2132}
2133
2134RUNTIME_FUNCTION(Runtime_StringUtf8Value) {
2135 HandleScope scope(isolate);
2136 if (args.length() != 1 || !IsString(args[0])) {
2137 return CrashUnlessFuzzing(isolate);
2138 }
2139 DirectHandle<String> string = args.at<String>(0);
2140
2141 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
2142 v8::String::Utf8Value value(v8_isolate, v8::Utils::ToLocal(string));
2143
2145 isolate->factory()
2146 ->NewJSArrayBufferAndBackingStore(value.length(),
2148 .ToHandleChecked();
2149 memcpy(result->backing_store(), *value, value.length());
2150 return *result;
2151}
2152
2153RUNTIME_FUNCTION(Runtime_SharedGC) {
2154 SealHandleScope scope(isolate);
2155 if (!isolate->has_shared_space()) {
2156 return CrashUnlessFuzzing(isolate);
2157 }
2158 isolate->heap()->CollectGarbageShared(isolate->main_thread_local_heap(),
2160 return ReadOnlyRoots(isolate).undefined_value();
2161}
2162
2163RUNTIME_FUNCTION(Runtime_AtomicsSynchronizationPrimitiveNumWaitersForTesting) {
2164 HandleScope scope(isolate);
2165 if (args.length() != 1) {
2166 return CrashUnlessFuzzing(isolate);
2167 }
2170 return primitive->NumWaitersForTesting(isolate);
2171}
2172
2174 Runtime_AtomicsSychronizationNumAsyncWaitersInIsolateForTesting) {
2175 return Smi::FromInt(
2176 static_cast<uint32_t>(isolate->async_waiter_queue_nodes().size()));
2177}
2178
2179RUNTIME_FUNCTION(Runtime_GetWeakCollectionSize) {
2180 HandleScope scope(isolate);
2181 if (args.length() != 1 || !IsJSWeakCollection(args[0])) {
2182 return CrashUnlessFuzzing(isolate);
2183 }
2185
2186 return Smi::FromInt(
2187 Cast<EphemeronHashTable>(collection->table())->NumberOfElements());
2188}
2189
2190RUNTIME_FUNCTION(Runtime_SetPriorityBestEffort) {
2191 isolate->SetPriority(v8::Isolate::Priority::kBestEffort);
2192 return ReadOnlyRoots(isolate).undefined_value();
2193}
2194
2195RUNTIME_FUNCTION(Runtime_SetPriorityUserVisible) {
2196 isolate->SetPriority(v8::Isolate::Priority::kUserVisible);
2197 return ReadOnlyRoots(isolate).undefined_value();
2198}
2199
2200RUNTIME_FUNCTION(Runtime_SetPriorityUserBlocking) {
2201 isolate->SetPriority(v8::Isolate::Priority::kUserBlocking);
2202 return ReadOnlyRoots(isolate).undefined_value();
2203}
2204
2205RUNTIME_FUNCTION(Runtime_IsEfficiencyModeEnabled) {
2206 if (isolate->EfficiencyModeEnabled()) {
2207 return ReadOnlyRoots(isolate).true_value();
2208 }
2209 return ReadOnlyRoots(isolate).false_value();
2210}
2211
2212RUNTIME_FUNCTION(Runtime_SetBatterySaverMode) {
2213 HandleScope scope(isolate);
2214 if (args.length() != 1) {
2215 return CrashUnlessFuzzing(isolate);
2216 }
2217 if (*args.at<Object>(0) == ReadOnlyRoots(isolate).true_value()) {
2218 isolate->set_battery_saver_mode_enabled(true);
2219 } else {
2220 isolate->set_battery_saver_mode_enabled(false);
2221 }
2222 // If the override flag is set changing the mode has no effect.
2223 if (v8_flags.battery_saver_mode.value().has_value()) {
2224 return ReadOnlyRoots(isolate).false_value();
2225 }
2226 return ReadOnlyRoots(isolate).true_value();
2227}
2228
2229// Returns true if the tiering state (liftoff, turbofan) of wasm functions can
2230// be asserted in a predictable way.
2231RUNTIME_FUNCTION(Runtime_IsWasmTieringPredictable) {
2232 DCHECK_EQ(args.length(), 0);
2233 const bool single_isolate = g_num_isolates_for_testing == 1;
2234 const bool stress_deopt = v8_flags.deopt_every_n_times > 0;
2235 return ReadOnlyRoots(isolate).boolean_value(single_isolate && !stress_deopt);
2236}
2237
2238RUNTIME_FUNCTION(Runtime_GetFeedback) {
2239 HandleScope scope(isolate);
2240 if (args.length() != 1) {
2241 return CrashUnlessFuzzing(isolate);
2242 }
2243 DirectHandle<Object> function_object = args.at(0);
2244 if (!IsJSFunction(*function_object)) return CrashUnlessFuzzing(isolate);
2245 DirectHandle<JSFunction> function = Cast<JSFunction>(function_object);
2246
2247 if (!function->has_feedback_vector()) {
2248 return CrashUnlessFuzzing(isolate);
2249 }
2250
2251#ifdef V8_JITLESS
2252 // No feedback is collected in jitless mode, so tests calling %GetFeedback
2253 // don't make sense.
2254 return ReadOnlyRoots(isolate).undefined_value();
2255#else
2256#ifdef OBJECT_PRINT
2257 DirectHandle<FeedbackVector> feedback_vector =
2258 direct_handle(function->feedback_vector(), isolate);
2259
2261 isolate->factory()->NewFixedArray(feedback_vector->length());
2262 int result_ix = 0;
2263
2264 FeedbackMetadataIterator iter(feedback_vector->metadata());
2265 while (iter.HasNext()) {
2266 FeedbackSlot slot = iter.Next();
2267 FeedbackSlotKind kind = iter.kind();
2268
2269 DirectHandle<FixedArray> sub_result = isolate->factory()->NewFixedArray(2);
2270 {
2271 std::ostringstream out;
2272 out << kind;
2273 DirectHandle<String> kind_string =
2274 isolate->factory()->NewStringFromAsciiChecked(out.str().c_str());
2275 sub_result->set(0, *kind_string);
2276 }
2277
2278 FeedbackNexus nexus(isolate, *feedback_vector, slot);
2279 {
2280 std::ostringstream out;
2281 nexus.Print(out);
2282 DirectHandle<String> nexus_string =
2283 isolate->factory()->NewStringFromAsciiChecked(out.str().c_str());
2284 sub_result->set(1, *nexus_string);
2285 }
2286
2287 DirectHandle<JSArray> sub_result_array =
2288 isolate->factory()->NewJSArrayWithElements(sub_result);
2289 result->set(result_ix++, *sub_result_array);
2290 }
2291
2292 return *isolate->factory()->NewJSArrayWithElements(result);
2293#else
2294 return ReadOnlyRoots(isolate).undefined_value();
2295#endif // OBJECT_PRINT
2296#endif // not V8_JITLESS
2297}
2298
2299RUNTIME_FUNCTION(Runtime_CheckNoWriteBarrierNeeded) {
2300#if defined(V8_ENABLE_DEBUG_CODE) && !V8_DISABLE_WRITE_BARRIERS_BOOL
2302 if (args.length() != 2) {
2303 return CrashUnlessFuzzing(isolate);
2304 }
2305 Tagged<Object> object = args[0];
2306 if (!object.IsHeapObject()) {
2307 return CrashUnlessFuzzing(isolate);
2308 }
2309 auto heap_object = Cast<HeapObject>(object);
2310 Tagged<Object> value = args[1];
2311 CHECK(!WriteBarrier::IsRequired(heap_object, value));
2312 return args[0];
2313#else
2314 UNREACHABLE();
2315#endif
2316}
2317
2318RUNTIME_FUNCTION(Runtime_ArrayBufferDetachForceWasm) {
2319 HandleScope scope(isolate);
2321 if (args.length() > 2 || !IsJSArrayBuffer(*args.at(0))) {
2322 return CrashUnlessFuzzing(isolate);
2323 }
2324 auto array_buffer = Cast<JSArrayBuffer>(args.at(0));
2325 if (!array_buffer->GetBackingStore()->is_wasm_memory() ||
2326 array_buffer->is_shared()) {
2327 return CrashUnlessFuzzing(isolate);
2328 }
2329 constexpr bool kForceForWasmMemory = true;
2330 MAYBE_RETURN(JSArrayBuffer::Detach(array_buffer, kForceForWasmMemory,
2331 args.atOrUndefined(isolate, 1)),
2332 ReadOnlyRoots(isolate).exception());
2333 return ReadOnlyRoots(isolate).undefined_value();
2334}
2335
2336} // namespace internal
2337} // namespace v8
Builtins::Kind kind
Definition builtins.cc:40
#define BUILTIN_CODE(isolate, name)
Definition builtins.h:45
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, const CFunction *c_function=nullptr, uint16_t instance_type=0, uint16_t allowed_receiver_instance_type_range_start=0, uint16_t allowed_receiver_instance_type_range_end=0)
Definition api.cc:1101
void SetModifyCodeGenerationFromStringsCallback(ModifyCodeGenerationFromStringsCallback2 callback)
@ kFullGarbageCollection
Definition v8-isolate.h:456
Local< Context > GetCurrentContext()
Definition api.cc:9756
static Local< ObjectTemplate > New(Isolate *isolate, Local< FunctionTemplate > constructor=Local< FunctionTemplate >())
Definition api.cc:1376
static v8::internal::DirectHandle< To > OpenDirectHandle(v8::Local< From > handle)
Definition api.h:279
static void Abort()
static void DebugBreak()
static const uint32_t kMaxLengthBits
Definition bigint.h:105
static constexpr BytecodeOffset None()
Definition utils.h:675
constexpr bool IsNone() const
Definition utils.h:684
constexpr int ToInt() const
Definition utils.h:673
static bool CompileBaseline(Isolate *isolate, DirectHandle< JSFunction > function, ClearExceptionFlag flag, IsCompiledScope *is_compiled_scope)
Definition compiler.cc:3132
static void CompileOptimized(Isolate *isolate, DirectHandle< JSFunction > function, ConcurrencyMode mode, CodeKind code_kind)
Definition compiler.cc:3176
static bool Compile(Isolate *isolate, Handle< SharedFunctionInfo > shared, ClearExceptionFlag flag, IsCompiledScope *is_compiled_scope, CreateSourcePositions create_source_positions_flag=CreateSourcePositions::kNo)
Definition compiler.cc:2906
static V8_WARN_UNUSED_RESULT MaybeHandle< Code > CompileOptimizedOSR(Isolate *isolate, DirectHandle< JSFunction > function, BytecodeOffset osr_offset, ConcurrencyMode mode, CodeKind code_kind)
Definition compiler.cc:4368
static V8_EXPORT_PRIVATE MaybeDirectHandle< Object > Global(Isolate *isolate, Handle< String > source, debug::EvaluateGlobalMode mode, REPLMode repl_mode=REPLMode::kNo)
static void DeoptimizeFunction(Tagged< JSFunction > function, LazyDeoptimizeReason reason, Tagged< Code > code={})
V8_INLINE Address address() const
Definition handles.h:695
void Print(std::ostream &os)
static constexpr int kMaxOsrUrgency
static constexpr int kMaxRegularLength
static V8_INLINE bool InYoungGeneration(Tagged< Object > object)
static V8_INLINE bool InReadOnlySpace(Tagged< HeapObject > object)
void TakeSnapshotToFile(const v8::HeapProfiler::HeapSnapshotOptions options, std::string filename)
HeapProfiler * heap_profiler() const
Definition heap.h:366
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > Detach(DirectHandle< JSArrayBuffer > buffer, bool force_for_wasm_memory=false, DirectHandle< Object > key={})
static V8_EXPORT_PRIVATE void EnsureFeedbackVector(Isolate *isolate, DirectHandle< JSFunction > function, IsCompiledScope *compiled_scope)
FeedbackVector eventually. Generally this shouldn't be used to get the.
static V8_EXPORT_PRIVATE MaybeDirectHandle< JSRegExp > New(Isolate *isolate, DirectHandle< String > source, Flags flags, uint32_t backtrack_limit=kNoBacktrackLimit)
Definition js-regexp.cc:152
static std::optional< Flags > FlagsFromString(Isolate *isolate, DirectHandle< String > flags)
Definition js-regexp.cc:123
static void PrintTop(Isolate *isolate, FILE *file, bool print_args, bool print_line_number)
Definition frames.cc:2562
BytecodeOffset GetBytecodeOffsetForOSR() const
Definition frames.cc:2208
DirectHandle< JSFunction > GetInnermostFunction() const
Definition frames.cc:2204
static MaglevFrame * cast(StackFrame *frame)
Definition frames.h:1199
static void MarkFunctionForManualOptimization(Isolate *isolate, DirectHandle< JSFunction > function, IsCompiledScope *is_compiled_scope)
static bool IsMarkedForManualOptimization(Isolate *isolate, Tagged< JSFunction > function)
static void CompleteInobjectSlackTracking(Isolate *isolate, Tagged< Map > initial_map)
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
static bool ToIntegerIndex(Tagged< Object > obj, size_t *index)
static HandleType< Object >::MaybeType Share(Isolate *isolate, HandleType< T > value, ShouldThrow throw_if_cannot_be_shared)
static Tagged< AllocationMemento > FindAllocationMemento(Heap *heap, Tagged< Map > map, Tagged< HeapObject > object)
V8_EXPORT_PRIVATE void PretenureAllocationSiteOnNextCollection(Tagged< AllocationSite > site)
V8_INLINE Tagged< Boolean > boolean_value(bool value) const
Definition roots-inl.h:119
static bool IsUnmodifiedRegExp(Isolate *isolate, DirectHandle< JSRegExp > regexp)
Definition regexp.cc:166
static V8_EXPORT_PRIVATE void DiscardCompiled(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared_info)
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static V8_EXPORT_PRIVATE void SerializeDeserializeAndVerifyForTesting(Isolate *isolate, DirectHandle< Context > default_context)
Definition snapshot.cc:346
bool is_baseline() const
Definition frames.h:242
bool is_maglev() const
Definition frames.h:243
bool is_interpreted() const
Definition frames.h:241
static bool IsInPlaceInternalizable(Tagged< String > string)
std::unique_ptr< char[]> ToCString(uint32_t offset, uint32_t length, size_t *length_output=nullptr)
Definition string.cc:711
constexpr bool IsCleared() const
constexpr bool IsWeak() const
Tagged< Object > GetHeapObjectOrSmi() const
V8_INLINE constexpr bool is_null() const
Definition tagged.h:502
static UnoptimizedJSFrame * cast(StackFrame *frame)
Definition frames.h:1123
Tagged< BytecodeArray > GetBytecodeArray() const
Definition frames.cc:3299
virtual int GetBytecodeOffset() const =0
Handle< Code > code
uint32_t count
#define TYPED_ARRAYS(V)
#define RUNTIME_FUNCTION(Name)
Definition arguments.h:162
#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:284
#define MAYBE_RETURN(call, value)
Definition isolate.h:408
#define RETURN_RESULT_OR_FAILURE(isolate, call)
Definition isolate.h:264
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
#define V8_ENABLE_TURBOFAN_BOOL
std::string filename
Isolate * isolate
TNode< Object > target
SharedFunctionInfoRef shared
std::map< const std::string, const std::string > map
std::string pattern
DirectHandle< JSReceiver > options
Precision precision
ZoneVector< RpoNumber > & result
int n
Definition mul-fft.cc:296
constexpr double uint64_to_double(uint64_t d64)
Definition double.h:20
constexpr Vector< const char > StaticCharVector(const char(&array)[N])
Definition vector.h:326
constexpr bool IsInRange(T value, U lower_limit, U higher_limit)
Definition bounds.h:20
V8_INLINE bool ControlledCrashesAreHarmless()
Definition abort-mode.h:41
static bool IsMaglevOsrEnabled()
Definition compiler.h:59
static bool IsMaglevEnabled()
Definition compiler.h:57
WasmEngine * GetWasmEngine()
constexpr int kTaggedSize
Definition globals.h:542
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
static void ReturnNull(const v8::FunctionCallbackInfo< v8::Value > &info)
static void DebugPrintImpl(Tagged< MaybeObject > maybe_object, std::ostream &os)
void PrintF(const char *format,...)
Definition utils.cc:39
Tagged(T object) -> Tagged< T >
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL int character
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
int g_num_isolates_for_testing
Definition runtime.cc:382
void Print(Tagged< Object > obj)
Definition objects.h:774
constexpr int kSystemPointerSize
Definition globals.h:410
const char * GetAbortReason(AbortReason reason)
bool IsShared(Tagged< Object > obj)
bool V8_EXPORT ValidateCallbackInfo(const FunctionCallbackInfo< void > &info)
Definition api.cc:12301
uint32_t NumberToUint32(Tagged< Object > number)
void ShortPrint(Tagged< Object > obj, FILE *out)
Definition objects.cc:1865
void TraceManualRecompile(Tagged< JSFunction > function, CodeKind code_kind, ConcurrencyMode concurrency_mode)
V8_INLINE constexpr bool IsObject(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:661
V8_INLINE constexpr bool IsHeapObject(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:669
V8_EXPORT_PRIVATE FlagValues v8_flags
return value
Definition map-inl.h:893
Arguments< ArgumentsType::kRuntime > RuntimeArguments
Definition globals.h:1047
template const char * string
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
Local< T > Handle
static constexpr AcquireLoadTag kAcquireLoad
Definition globals.h:2908
#define CONVERT_INT32_ARG_FUZZ_SAFE(name, index)
#define CONVERT_BOOLEAN_ARG_FUZZ_SAFE(name, index)
#define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype)
#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)
#define CHECK(condition)
Definition logging.h:124
#define CHECK_LT(lhs, rhs)
#define CHECK_NE(lhs, rhs)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define USE(...)
Definition macros.h:293
#define OFFSET_OF_DATA_START(Type)
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671
#define V8_UNLIKELY(condition)
Definition v8config.h:660