v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
runtime-scopes.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 <memory>
6
14#include "src/handles/handles.h"
15#include "src/heap/heap-inl.h" // For ToBoolean. TODO(jkummerow): Drop.
22#include "src/objects/objects.h"
23#include "src/objects/oddball.h"
24#include "src/objects/smi.h"
25#include "src/objects/tagged.h"
27
28namespace v8 {
29namespace internal {
30
31RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) {
32 HandleScope scope(isolate);
34 NewTypeError(MessageTemplate::kConstAssign));
35}
36
37RUNTIME_FUNCTION(Runtime_ThrowUsingAssignError) {
38 HandleScope scope(isolate);
40 NewTypeError(MessageTemplate::kUsingAssign));
41}
42
43namespace {
44
45enum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 };
46
47Tagged<Object> ThrowRedeclarationError(Isolate* isolate, Handle<String> name,
48 RedeclarationType redeclaration_type) {
49 HandleScope scope(isolate);
50 if (redeclaration_type == RedeclarationType::kSyntaxError) {
52 isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name));
53 } else {
55 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name));
56 }
57}
58
59// May throw a RedeclarationError.
60Tagged<Object> DeclareGlobal(Isolate* isolate,
61 DirectHandle<JSGlobalObject> global,
62 Handle<String> name, Handle<Object> value,
63 PropertyAttributes attr, bool is_var,
64 RedeclarationType redeclaration_type) {
65 DirectHandle<ScriptContextTable> script_contexts(
66 global->native_context()->script_context_table(), isolate);
67 VariableLookupResult lookup;
68 if (script_contexts->Lookup(name, &lookup) &&
69 IsLexicalVariableMode(lookup.mode)) {
70 // ES#sec-globaldeclarationinstantiation 6.a:
71 // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
72 // exception.
73 return ThrowRedeclarationError(isolate, name,
74 RedeclarationType::kSyntaxError);
75 }
76
77 // Do the lookup own properties only, see ES5 erratum.
80 if (!is_var) {
81 // For function declarations, use the interceptor on the declaration. For
82 // non-functions, use it only on initialization.
84 }
85 LookupIterator it(isolate, global, name, global, lookup_config);
86 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
87 if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
88
89 if (it.IsFound()) {
90 PropertyAttributes old_attributes = maybe.FromJust();
91 // The name was declared before; check for conflicting re-declarations.
92
93 // Skip var re-declarations.
94 if (is_var) return ReadOnlyRoots(isolate).undefined_value();
95
96 if ((old_attributes & DONT_DELETE) != 0) {
97 // Only allow reconfiguring globals to functions in user code (no
98 // natives, which are marked as read-only).
99 DCHECK_EQ(attr & READ_ONLY, 0);
100
101 // Check whether we can reconfigure the existing property into a
102 // function.
103 if (old_attributes & READ_ONLY || old_attributes & DONT_ENUM ||
104 (it.state() == LookupIterator::ACCESSOR)) {
105 // ECMA-262 section 15.1.11 GlobalDeclarationInstantiation 5.d:
106 // If hasRestrictedGlobal is true, throw a SyntaxError exception.
107 // ECMA-262 section 18.2.1.3 EvalDeclarationInstantiation 8.a.iv.1.b:
108 // If fnDefinable is false, throw a TypeError exception.
109 return ThrowRedeclarationError(isolate, name, redeclaration_type);
110 }
111 // If the existing property is not configurable, keep its attributes. Do
112 attr = old_attributes;
113 }
114
115 // If the current state is ACCESSOR, this could mean it's an AccessorInfo
116 // type property. We are not allowed to call into such setters during global
117 // function declaration since this would break e.g., onload. Meaning
118 // 'function onload() {}' would invalidly register that function as the
119 // onload callback. To avoid this situation, we first delete the property
120 // before readding it as a regular data property below.
121 if (it.state() == LookupIterator::ACCESSOR) it.Delete();
122 }
123
124 if (!is_var) it.Restart();
125
126 // Define or redefine own property.
128 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr));
129
130 return ReadOnlyRoots(isolate).undefined_value();
131}
132
133} // namespace
134
135RUNTIME_FUNCTION(Runtime_DeclareModuleExports) {
136 HandleScope scope(isolate);
137 DCHECK_EQ(2, args.length());
138
139 DirectHandle<FixedArray> declarations = args.at<FixedArray>(0);
141
142 DirectHandle<ClosureFeedbackCellArray> closure_feedback_cell_array(
143 closure->has_feedback_vector()
144 ? closure->feedback_vector()->closure_feedback_cell_array()
145 : closure->closure_feedback_cell_array(),
146 isolate);
147
148 DirectHandle<Context> context(isolate->context(), isolate);
149 DCHECK(context->IsModuleContext());
151 Cast<SourceTextModule>(context->extension())->regular_exports(), isolate);
152
153 int length = declarations->length();
154 FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i++, {
155 Tagged<Object> decl = declarations->get(i);
156 int index;
158 if (IsSmi(decl)) {
159 index = Smi::ToInt(decl);
160 value = ReadOnlyRoots(isolate).the_hole_value();
161 } else {
163 Cast<SharedFunctionInfo>(declarations->get(i)), isolate);
164 int feedback_index = Smi::ToInt(declarations->get(++i));
165 index = Smi::ToInt(declarations->get(++i));
166 DirectHandle<FeedbackCell> feedback_cell(
167 closure_feedback_cell_array->get(feedback_index), isolate);
168 value = *Factory::JSFunctionBuilder(isolate, sfi, context)
169 .set_feedback_cell(feedback_cell)
170 .Build();
171 }
172
173 Cast<Cell>(exports->get(index - 1))->set_value(value);
174 });
175
176 return ReadOnlyRoots(isolate).undefined_value();
177}
178
179RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
180 HandleScope scope(isolate);
181 DCHECK_EQ(2, args.length());
182
183 DirectHandle<FixedArray> declarations = args.at<FixedArray>(0);
185
186 DirectHandle<JSGlobalObject> global(isolate->global_object());
187 DirectHandle<Context> context(isolate->context(), isolate);
188
189 DirectHandle<ClosureFeedbackCellArray> closure_feedback_cell_array(
190 closure->has_feedback_vector()
191 ? closure->feedback_vector()->closure_feedback_cell_array()
192 : closure->closure_feedback_cell_array(),
193 isolate);
194
195 // Traverse the name/value pairs and set the properties.
196 int length = declarations->length();
197 FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i++, {
198 Handle<Object> decl(declarations->get(i), isolate);
201 bool is_var = IsString(*decl);
202
203 if (is_var) {
204 name = Cast<String>(decl);
205 value = isolate->factory()->undefined_value();
206 } else {
208 name = handle(sfi->Name(), isolate);
209 int index = Smi::ToInt(declarations->get(++i));
210 DirectHandle<FeedbackCell> feedback_cell(
211 closure_feedback_cell_array->get(index), isolate);
212 value = Factory::JSFunctionBuilder(isolate, sfi, context)
213 .set_feedback_cell(feedback_cell)
214 .Build();
215 }
216
217 // Compute the property attributes. According to ECMA-262,
218 // the property must be non-configurable except in eval.
219 Tagged<Script> script = Cast<Script>(closure->shared()->script());
220 PropertyAttributes attr =
221 script->compilation_type() == Script::CompilationType::kEval
222 ? NONE
223 : DONT_DELETE;
224
225 // ES#sec-globaldeclarationinstantiation 5.d:
226 // If hasRestrictedGlobal is true, throw a SyntaxError exception.
228 DeclareGlobal(isolate, global, name, value, attr, is_var,
229 RedeclarationType::kSyntaxError);
230 if (IsException(result)) return result;
231 });
232
233 return ReadOnlyRoots(isolate).undefined_value();
234}
235
236RUNTIME_FUNCTION(Runtime_InitializeDisposableStack) {
237 HandleScope scope(isolate);
238 DCHECK_EQ(0, args.length());
239
240 DirectHandle<JSDisposableStackBase> disposable_stack =
241 isolate->factory()->NewJSDisposableStackBase();
243 disposable_stack);
244 return *disposable_stack;
245}
246
247namespace {
248Maybe<bool> AddToDisposableStack(Isolate* isolate,
249 DirectHandle<JSDisposableStackBase> stack,
250 DirectHandle<JSAny> value,
252 DisposeMethodHint hint) {
253 DirectHandle<Object> method;
255 isolate, method,
257 hint),
258 Nothing<bool>());
259
260 // Return the DisposableResource Record { [[ResourceValue]]: V, [[Hint]]:
261 // hint, [[DisposeMethod]]: method }.
262 JSDisposableStackBase::Add(isolate, stack, value, method, type, hint);
263 return Just(true);
264}
265} // namespace
266
267RUNTIME_FUNCTION(Runtime_AddDisposableValue) {
268 HandleScope scope(isolate);
269 DCHECK_EQ(2, args.length());
270
272 DirectHandle<JSAny> value = args.at<JSAny>(1);
273
274 // a. If V is either null or undefined and hint is sync-dispose, return
275 // unused.
276 if (!IsNullOrUndefined(*value)) {
277 MAYBE_RETURN(AddToDisposableStack(isolate, stack, value,
280 ReadOnlyRoots(isolate).exception());
281 }
282 return *value;
283}
284
285RUNTIME_FUNCTION(Runtime_AddAsyncDisposableValue) {
286 HandleScope scope(isolate);
287 DCHECK_EQ(2, args.length());
288
290 DirectHandle<JSAny> value = args.at<JSAny>(1);
291
292 // CreateDisposableResource
293 // 1. If method is not present, then
294 // a. If V is either null or undefined, then
295 // i. Set V to undefined.
296 // ii. Set method to undefined.
297 MAYBE_RETURN(AddToDisposableStack(isolate, stack,
298 IsNullOrUndefined(*value)
299 ? isolate->factory()->undefined_value()
300 : value,
303 ReadOnlyRoots(isolate).exception());
304 return *value;
305}
306
307RUNTIME_FUNCTION(Runtime_DisposeDisposableStack) {
308 HandleScope scope(isolate);
309 DCHECK_EQ(5, args.length());
310
311 DirectHandle<JSDisposableStackBase> disposable_stack =
313 DirectHandle<Smi> continuation_token = args.at<Smi>(1);
314 Handle<Object> continuation_error = args.at<Object>(2);
315 Handle<Object> continuation_message = args.at<Object>(3);
316 DirectHandle<Smi> has_await_using = args.at<Smi>(4);
317
318 // If state is not kDisposed, then the disposing of the resources has
319 // not started yet. So, if the continuation token is kRethrow we need
320 // to set error and error message on the disposable stack.
321 if (disposable_stack->state() != DisposableStackState::kDisposed &&
322 *continuation_token ==
323 Smi::FromInt(static_cast<int>(
325 disposable_stack->set_error(*continuation_error);
326 disposable_stack->set_error_message(*continuation_message);
327 }
328
330 disposable_stack->state() == DisposableStackState::kDisposed,
331 static_cast<DisposableStackResourcesType>(Smi::ToInt(*has_await_using)) ==
333
334 disposable_stack->set_state(DisposableStackState::kDisposed);
335
338 isolate, result,
340 isolate, disposable_stack,
341 static_cast<DisposableStackResourcesType>(
342 Smi::ToInt(*has_await_using))));
343 return *result;
344}
345
346RUNTIME_FUNCTION(Runtime_HandleExceptionsInDisposeDisposableStack) {
347 HandleScope scope(isolate);
348 DCHECK_EQ(3, args.length());
349
350 DirectHandle<JSDisposableStackBase> disposable_stack =
352 DirectHandle<Object> exception = args.at<Object>(1);
353 DirectHandle<Object> message = args.at<Object>(2);
354
355 if (!isolate->is_catchable_by_javascript(*exception)) {
356 return isolate->Throw(*exception);
357 }
358
359 JSDisposableStackBase::HandleErrorInDisposal(isolate, disposable_stack,
360 exception, message);
361 return *disposable_stack;
362}
363
364namespace {
365
366Tagged<Object> DeclareEvalHelper(Isolate* isolate, Handle<String> name,
367 Handle<Object> value) {
368 // Declarations are always made in a function, native, eval, or script
369 // context, or a declaration block scope. Since this is called from eval, the
370 // context passed is the context of the caller, which may be some nested
371 // context and not the declaration context.
372 Handle<Context> context(isolate->context()->declaration_context(), isolate);
373
374 // For debug-evaluate we always use sloppy eval, in which case context could
375 // also be a module context. As module contexts reuse the extension slot
376 // we need to check for this.
377 const bool is_debug_evaluate_in_module =
378 isolate->context()->IsDebugEvaluateContext() &&
379 context->IsModuleContext();
380
381 DCHECK(context->IsFunctionContext() || IsNativeContext(*context) ||
382 context->IsScriptContext() || context->IsEvalContext() ||
383 (context->IsBlockContext() &&
384 context->scope_info()->is_declaration_scope()) ||
385 is_debug_evaluate_in_module);
386
387 bool is_var = IsUndefined(*value, isolate);
388 DCHECK_IMPLIES(!is_var, IsJSFunction(*value));
389
390 int index;
391 PropertyAttributes attributes;
392 InitializationFlag init_flag;
394
395 DirectHandle<Object> holder =
396 Context::Lookup(context, name, DONT_FOLLOW_CHAINS, &index, &attributes,
397 &init_flag, &mode);
398 DCHECK(holder.is_null() || !IsSourceTextModule(*holder));
399 DCHECK(!isolate->has_exception());
400
401 DirectHandle<JSObject> object;
402
403 if (attributes != ABSENT && IsJSGlobalObject(*holder)) {
404 // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b:
405 // If fnDefinable is false, throw a TypeError exception.
406 return DeclareGlobal(isolate, Cast<JSGlobalObject>(holder), name, value,
407 NONE, is_var, RedeclarationType::kTypeError);
408 }
409 if (context->has_extension() && IsJSGlobalObject(context->extension())) {
410 DirectHandle<JSGlobalObject> global(
411 Cast<JSGlobalObject>(context->extension()), isolate);
412 return DeclareGlobal(isolate, global, name, value, NONE, is_var,
413 RedeclarationType::kTypeError);
414 } else if (context->IsScriptContext()) {
415 DCHECK(IsJSGlobalObject(context->global_object()));
416 DirectHandle<JSGlobalObject> global(
417 Cast<JSGlobalObject>(context->global_object()), isolate);
418 return DeclareGlobal(isolate, global, name, value, NONE, is_var,
419 RedeclarationType::kTypeError);
420 }
421
422 if (attributes != ABSENT) {
423 DCHECK_EQ(NONE, attributes);
424
425 // Skip var re-declarations.
426 if (is_var) return ReadOnlyRoots(isolate).undefined_value();
427
428 if (index != Context::kNotFound) {
429 DCHECK(holder.is_identical_to(context));
430 context->set(index, *value);
431 return ReadOnlyRoots(isolate).undefined_value();
432 }
433
434 object = Cast<JSObject>(holder);
435
436 } else if (context->has_extension() && !is_debug_evaluate_in_module) {
437 object = direct_handle(context->extension_object(), isolate);
438 DCHECK(IsJSContextExtensionObject(*object));
439 } else if (context->scope_info()->HasContextExtensionSlot() &&
440 !is_debug_evaluate_in_module) {
441 // Sloppy varblock and function contexts might not have an extension object
442 // yet. Sloppy eval will never have an extension object, as vars are hoisted
443 // out, and lets are known statically.
444 DCHECK((context->IsBlockContext() &&
445 context->scope_info()->is_declaration_scope()) ||
446 context->IsFunctionContext());
447 DCHECK(context->scope_info()->SloppyEvalCanExtendVars());
448 object =
449 isolate->factory()->NewJSObject(isolate->context_extension_function());
450 context->set_extension(*object);
451 {
452 Tagged<ScopeInfo> scope_info = context->scope_info();
453 if (!scope_info->SomeContextHasExtension()) {
454 scope_info->mark_some_context_has_extension();
456 isolate, scope_info, DependentCode::kEmptyContextExtensionGroup);
457 }
458 }
459 } else {
461 isolate,
462 NewEvalError(MessageTemplate::kVarNotAllowedInEvalScope, name));
463 }
464
466 object, name, value, NONE));
467
468 return ReadOnlyRoots(isolate).undefined_value();
469}
470
471} // namespace
472
473RUNTIME_FUNCTION(Runtime_DeclareEvalFunction) {
474 HandleScope scope(isolate);
475 DCHECK_EQ(2, args.length());
476 Handle<String> name = args.at<String>(0);
477 Handle<Object> value = args.at(1);
478 return DeclareEvalHelper(isolate, name, value);
479}
480
481RUNTIME_FUNCTION(Runtime_DeclareEvalVar) {
482 HandleScope scope(isolate);
483 DCHECK_EQ(1, args.length());
484 Handle<String> name = args.at<String>(0);
485 return DeclareEvalHelper(isolate, name,
486 isolate->factory()->undefined_value());
487}
488
489namespace {
490
491// Find the arguments of the JavaScript function invocation that called
492// into C++ code. Collect these in a newly allocated array of handles.
493DirectHandleVector<Object> GetCallerArguments(Isolate* isolate) {
494 // Find frame containing arguments passed to the caller.
495 JavaScriptStackFrameIterator it(isolate);
496 JavaScriptFrame* frame = it.frame();
497 std::vector<Tagged<SharedFunctionInfo>> functions;
498 frame->GetFunctions(&functions);
499 if (functions.size() > 1) {
500 int inlined_jsframe_index = static_cast<int>(functions.size()) - 1;
501 TranslatedState translated_values(frame);
502 translated_values.Prepare(frame->fp());
503
504 int argument_count = 0;
505 TranslatedFrame* translated_frame =
506 translated_values.GetArgumentsInfoFromJSFrameIndex(
507 inlined_jsframe_index, &argument_count);
508 TranslatedFrame::iterator iter = translated_frame->begin();
509
510 // Skip the function.
511 iter++;
512
513 // Skip the receiver.
514 iter++;
515 argument_count--;
516
517 DirectHandleVector<Object> param_data(isolate, argument_count);
518 bool should_deoptimize = false;
519 for (int i = 0; i < argument_count; i++) {
520 // If we materialize any object, we should deoptimize the frame because we
521 // might alias an object that was eliminated by escape analysis.
522 should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
523 DirectHandle<Object> value = iter->GetValue();
524 param_data[i] = value;
525 iter++;
526 }
527
528 if (should_deoptimize) {
529 translated_values.StoreMaterializedValuesAndDeopt(frame);
530 }
531
532 return param_data;
533 } else {
534 int args_count = frame->GetActualArgumentCount();
535 DirectHandleVector<Object> param_data(isolate, args_count);
536 for (int i = 0; i < args_count; i++) {
537 DirectHandle<Object> val =
538 DirectHandle<Object>(frame->GetParameter(i), isolate);
539 param_data[i] = val;
540 }
541 return param_data;
542 }
543}
544
545template <typename T>
546DirectHandle<JSObject> NewSloppyArguments(Isolate* isolate,
547 DirectHandle<JSFunction> callee,
548 T parameters, int argument_count) {
549 CHECK(!IsDerivedConstructor(callee->shared()->kind()));
550 DCHECK(callee->shared()->has_simple_parameters());
551 DirectHandle<JSObject> result =
552 isolate->factory()->NewArgumentsObject(callee, argument_count);
553
554 // Allocate the elements if needed.
555 int parameter_count =
556 callee->shared()->internal_formal_parameter_count_without_receiver();
557 if (argument_count > 0) {
558 if (parameter_count > 0) {
559 int mapped_count = std::min(argument_count, parameter_count);
560
561 // Store the context and the arguments array at the beginning of the
562 // parameter map.
563 DirectHandle<Context> context(isolate->context(), isolate);
564 DirectHandle<FixedArray> arguments = isolate->factory()->NewFixedArray(
565 argument_count, AllocationType::kYoung);
566
567 DirectHandle<SloppyArgumentsElements> parameter_map =
568 isolate->factory()->NewSloppyArgumentsElements(
569 mapped_count, context, arguments, AllocationType::kYoung);
570
571 result->set_map(isolate,
572 isolate->native_context()->fast_aliased_arguments_map());
573 result->set_elements(*parameter_map);
574
575 // Loop over the actual parameters backwards.
576 int index = argument_count - 1;
577 while (index >= mapped_count) {
578 // These go directly in the arguments array and have no
579 // corresponding slot in the parameter map.
580 arguments->set(index, parameters[index]);
581 --index;
582 }
583
584 DirectHandle<ScopeInfo> scope_info(callee->shared()->scope_info(),
585 isolate);
586
587 // First mark all mappable slots as unmapped and copy the values into the
588 // arguments object.
589 for (int i = 0; i < mapped_count; i++) {
590 arguments->set(i, parameters[i]);
591 parameter_map->set_mapped_entries(
592 i, *isolate->factory()->the_hole_value());
593 }
594
595 // Walk all context slots to find context allocated parameters. Mark each
596 // found parameter as mapped.
597 ReadOnlyRoots roots{isolate};
598 for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
599 if (!scope_info->ContextLocalIsParameter(i)) continue;
600 int parameter = scope_info->ContextLocalParameterNumber(i);
601 if (parameter >= mapped_count) continue;
602 arguments->set_the_hole(roots, parameter);
603 Tagged<Smi> slot = Smi::FromInt(scope_info->ContextHeaderLength() + i);
604 parameter_map->set_mapped_entries(parameter, slot);
605 }
606 } else {
607 // If there is no aliasing, the arguments object elements are not
608 // special in any way.
609 DirectHandle<FixedArray> elements = isolate->factory()->NewFixedArray(
610 argument_count, AllocationType::kYoung);
611 result->set_elements(*elements);
612 for (int i = 0; i < argument_count; ++i) {
613 elements->set(i, parameters[i]);
614 }
615 }
616 }
617 return result;
618}
619
620class HandleArguments {
621 public:
622 // If direct handles are enabled, it is the responsibility of the caller to
623 // ensure that the memory pointed to by `array` is scanned during CSS, e.g.,
624 // it comes from a `DirectHandleVector<Object>`.
625 explicit HandleArguments(base::Vector<const DirectHandle<Object>> array)
626 : array_(array) {}
627 Tagged<Object> operator[](int index) { return *array_[index]; }
628
629 private:
630 base::Vector<const DirectHandle<Object>> array_;
631};
632
633class ParameterArguments {
634 public:
635 explicit ParameterArguments(Address parameters) : parameters_(parameters) {}
636 Tagged<Object> operator[](int index) {
637 return *FullObjectSlot(parameters_ - (index + 1) * kSystemPointerSize);
638 }
639
640 private:
642};
643
644} // namespace
645
646RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
647 HandleScope scope(isolate);
648 DCHECK_EQ(1, args.length());
650 // This generic runtime function can also be used when the caller has been
651 // inlined, we use the slow but accurate {GetCallerArguments}.
652 auto arguments = GetCallerArguments(isolate);
653 HandleArguments argument_getter({arguments.data(), arguments.size()});
654 return *NewSloppyArguments(isolate, callee, argument_getter,
655 static_cast<int>(arguments.size()));
656}
657
658RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
659 HandleScope scope(isolate);
660 DCHECK_EQ(1, args.length());
662 // This generic runtime function can also be used when the caller has been
663 // inlined, we use the slow but accurate {GetCallerArguments}.
664 auto arguments = GetCallerArguments(isolate);
665 int argument_count = static_cast<int>(arguments.size());
667 isolate->factory()->NewArgumentsObject(callee, argument_count);
668 if (argument_count) {
670 isolate->factory()->NewFixedArray(argument_count);
672 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
673 for (int i = 0; i < argument_count; i++) {
674 array->set(i, *arguments[i], mode);
675 }
676 result->set_elements(*array);
677 }
678 return *result;
679}
680
681RUNTIME_FUNCTION(Runtime_NewRestParameter) {
682 HandleScope scope(isolate);
683 DCHECK_EQ(1, args.length());
685 int start_index =
686 callee->shared()->internal_formal_parameter_count_without_receiver();
687 // This generic runtime function can also be used when the caller has been
688 // inlined, we use the slow but accurate {GetCallerArguments}.
689 auto arguments = GetCallerArguments(isolate);
690 int argument_count = static_cast<int>(arguments.size());
691 int num_elements = std::max(0, argument_count - start_index);
692 DirectHandle<JSObject> result = isolate->factory()->NewJSArray(
693 PACKED_ELEMENTS, num_elements, num_elements,
695 if (num_elements == 0) return *result;
696 {
698 Tagged<FixedArray> elements = Cast<FixedArray>(result->elements());
699 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
700 for (int i = 0; i < num_elements; i++) {
701 elements->set(i, *arguments[i + start_index], mode);
702 }
703 }
704 return *result;
705}
706
707RUNTIME_FUNCTION(Runtime_NewClosure) {
708 HandleScope scope(isolate);
709 DCHECK_EQ(2, args.length());
711 DirectHandle<FeedbackCell> feedback_cell = args.at<FeedbackCell>(1);
712 DirectHandle<Context> context(isolate->context(), isolate);
713 return *Factory::JSFunctionBuilder{isolate, shared, context}
714 .set_feedback_cell(feedback_cell)
716 .Build();
717}
718
719RUNTIME_FUNCTION(Runtime_NewClosure_Tenured) {
720 HandleScope scope(isolate);
721 DCHECK_EQ(2, args.length());
723 DirectHandle<FeedbackCell> feedback_cell = args.at<FeedbackCell>(1);
724 DirectHandle<Context> context(isolate->context(), isolate);
725 // The caller ensures that we pretenure closures that are assigned
726 // directly to properties.
727 return *Factory::JSFunctionBuilder{isolate, shared, context}
728 .set_feedback_cell(feedback_cell)
730 .Build();
731}
732
733RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
734 HandleScope scope(isolate);
735 DCHECK_EQ(1, args.length());
736
737 DirectHandle<ScopeInfo> scope_info = args.at<ScopeInfo>(0);
738
739 DirectHandle<Context> outer(isolate->context(), isolate);
740 return *isolate->factory()->NewFunctionContext(outer, scope_info);
741}
742
743// TODO(jgruber): Rename these functions to 'New...Context'.
744RUNTIME_FUNCTION(Runtime_PushWithContext) {
745 HandleScope scope(isolate);
746 DCHECK_EQ(2, args.length());
747 DirectHandle<JSReceiver> extension_object = args.at<JSReceiver>(0);
748 DirectHandle<ScopeInfo> scope_info = args.at<ScopeInfo>(1);
749 DirectHandle<Context> current(isolate->context(), isolate);
750 return *isolate->factory()->NewWithContext(current, scope_info,
751 extension_object);
752}
753
754// TODO(jgruber): Rename these functions to 'New...Context'.
755RUNTIME_FUNCTION(Runtime_PushCatchContext) {
756 HandleScope scope(isolate);
757 DCHECK_EQ(2, args.length());
758 DirectHandle<Object> thrown_object = args.at(0);
759 DirectHandle<ScopeInfo> scope_info = args.at<ScopeInfo>(1);
760 DirectHandle<Context> current(isolate->context(), isolate);
761 return *isolate->factory()->NewCatchContext(current, scope_info,
762 thrown_object);
763}
764
765// TODO(jgruber): Rename these functions to 'New...Context'.
766RUNTIME_FUNCTION(Runtime_PushBlockContext) {
767 HandleScope scope(isolate);
768 DCHECK_EQ(1, args.length());
769 DirectHandle<ScopeInfo> scope_info = args.at<ScopeInfo>(0);
770 DirectHandle<Context> current(isolate->context(), isolate);
771 return *isolate->factory()->NewBlockContext(current, scope_info);
772}
773
774
775RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
776 HandleScope scope(isolate);
777 DCHECK_EQ(1, args.length());
778 Handle<String> name = args.at<String>(0);
779
780 int index;
781 PropertyAttributes attributes;
784 Handle<Context> context(isolate->context(), isolate);
786 context, name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode);
787
788 // If the slot was not found the result is true.
789 if (holder.is_null()) {
790 // In case of JSProxy, an exception might have been thrown.
791 if (isolate->has_exception()) return ReadOnlyRoots(isolate).exception();
792 return ReadOnlyRoots(isolate).true_value();
793 }
794
795 // If the slot was found in a context or in module imports and exports it
796 // should be DONT_DELETE.
797 if (IsContext(*holder) || IsSourceTextModule(*holder)) {
798 return ReadOnlyRoots(isolate).false_value();
799 }
800
801 // The slot was found in a JSReceiver, either a context extension object,
802 // the global object, or the subject of a with. Try to delete it
803 // (respecting DONT_DELETE).
805 Maybe<bool> result = JSReceiver::DeleteProperty(isolate, object, name);
806 MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
807 return isolate->heap()->ToBoolean(result.FromJust());
808}
809
810
811namespace {
812
813MaybeDirectHandle<Object> LoadLookupSlot(
814 Isolate* isolate, Handle<String> name, ShouldThrow should_throw,
815 Handle<Object>* receiver_return = nullptr) {
816 int index;
817 PropertyAttributes attributes;
820 Handle<Context> context(isolate->context(), isolate);
821 Handle<Object> holder = Context::Lookup(context, name, FOLLOW_CHAINS, &index,
822 &attributes, &flag, &mode);
823 if (isolate->has_exception()) return MaybeDirectHandle<Object>();
824
825 if (!holder.is_null() && IsSourceTextModule(*holder)) {
826 Handle<Object> receiver = isolate->factory()->undefined_value();
827 if (receiver_return) *receiver_return = receiver;
829 isolate, Cast<SourceTextModule>(holder), index);
830 }
831 if (index != Context::kNotFound) {
832 DCHECK(IsContext(*holder));
833 DirectHandle<Context> holder_context = Cast<Context>(holder);
834 // If the "property" we were looking for is a local variable, the
835 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
836 Handle<Object> receiver = isolate->factory()->undefined_value();
837 DirectHandle<Object> value =
838 direct_handle(holder_context->get(index), isolate);
839 // Check for uninitialized bindings.
840 if (flag == kNeedsInitialization && IsTheHole(*value, isolate)) {
841 THROW_NEW_ERROR(isolate,
842 NewReferenceError(MessageTemplate::kNotDefined, name));
843 }
844 DCHECK(!IsTheHole(*value, isolate));
845 if (receiver_return) *receiver_return = receiver;
846 if (v8_flags.script_context_mutable_heap_number &&
847 holder_context->IsScriptContext()) {
849 holder_context, index, value, isolate),
850 isolate);
851 }
852 return value;
853 }
854
855 // Otherwise, if the slot was found the holder is a context extension
856 // object, subject of a with, or a global object. We read the named
857 // property from it.
858 if (!holder.is_null()) {
859 // No need to unhole the value here. This is taken care of by the
860 // GetProperty function.
861 DirectHandle<Object> value;
863 isolate, value,
864 Object::GetProperty(isolate, Cast<JSAny>(holder), name));
865 if (receiver_return) {
866 *receiver_return =
867 (IsJSGlobalObject(*holder) || IsJSContextExtensionObject(*holder))
868 ? Cast<Object>(isolate->factory()->undefined_value())
869 : holder;
870 }
871 return value;
872 }
873
874 if (should_throw == kThrowOnError) {
875 // The property doesn't exist - throw exception.
876 THROW_NEW_ERROR(isolate,
877 NewReferenceError(MessageTemplate::kNotDefined, name));
878 }
879
880 // The property doesn't exist - return undefined.
881 if (receiver_return) *receiver_return = isolate->factory()->undefined_value();
882 return isolate->factory()->undefined_value();
883}
884
885} // namespace
886
887
888RUNTIME_FUNCTION(Runtime_LoadLookupSlot) {
889 HandleScope scope(isolate);
890 DCHECK_EQ(1, args.length());
891 Handle<String> name = args.at<String>(0);
893 LoadLookupSlot(isolate, name, kThrowOnError));
894}
895
896
897RUNTIME_FUNCTION(Runtime_LoadLookupSlotInsideTypeof) {
898 HandleScope scope(isolate);
899 DCHECK_EQ(1, args.length());
900 Handle<String> name = args.at<String>(0);
901 RETURN_RESULT_OR_FAILURE(isolate, LoadLookupSlot(isolate, name, kDontThrow));
902}
903
904
905RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) {
906 HandleScope scope(isolate);
907 DCHECK_EQ(1, args.length());
908 Handle<String> name = args.at<String>(0);
912 isolate, value, LoadLookupSlot(isolate, name, kThrowOnError, &receiver),
913 MakePair(ReadOnlyRoots(isolate).exception(), Tagged<Object>()));
914 return MakePair(*value, *receiver);
915}
916
917RUNTIME_FUNCTION(Runtime_LoadLookupSlotForCall_Baseline) {
918 HandleScope scope(isolate);
919 DCHECK_EQ(2, args.length());
920 Handle<String> name = args.at<String>(0);
921 // Output pair is returned into two consecutive stack slots.
922 FullObjectSlot value_ret = args.slot_from_address_at(1, 0);
923 FullObjectSlot receiver_ret = args.slot_from_address_at(1, -1);
926 if (!LoadLookupSlot(isolate, name, kThrowOnError, &receiver)
927 .ToHandle(&value)) {
928 DCHECK((isolate)->has_exception());
929 value_ret.store(ReadOnlyRoots(isolate).exception());
930 receiver_ret.store(Tagged<Object>());
931 return ReadOnlyRoots(isolate).exception();
932 }
933 value_ret.store(*value);
934 receiver_ret.store(*receiver);
935 return ReadOnlyRoots(isolate).undefined_value();
936}
937
938namespace {
939
940MaybeDirectHandle<Object> StoreLookupSlot(
941 Isolate* isolate, Handle<Context> context, Handle<String> name,
942 DirectHandle<Object> value, LanguageMode language_mode,
943 ContextLookupFlags context_lookup_flags = FOLLOW_CHAINS) {
944 int index;
945 PropertyAttributes attributes;
948 bool is_sloppy_function_name;
949 Handle<Object> holder =
950 Context::Lookup(context, name, context_lookup_flags, &index, &attributes,
951 &flag, &mode, &is_sloppy_function_name);
952 if (holder.is_null()) {
953 // In case of JSProxy, an exception might have been thrown.
954 if (isolate->has_exception()) return MaybeDirectHandle<Object>();
955 } else if (IsSourceTextModule(*holder)) {
956 if ((attributes & READ_ONLY) == 0) {
958 value);
959 } else {
960 THROW_NEW_ERROR(isolate,
961 NewTypeError(MessageTemplate::kConstAssign, name));
962 }
963 return value;
964 }
965 // The property was found in a context slot.
966 if (index != Context::kNotFound) {
967 auto holder_context = Cast<Context>(holder);
968 if (flag == kNeedsInitialization &&
969 IsTheHole(holder_context->get(index), isolate)) {
970 THROW_NEW_ERROR(isolate,
971 NewReferenceError(MessageTemplate::kNotDefined, name));
972 }
973 if ((attributes & READ_ONLY) == 0) {
974 if ((v8_flags.script_context_mutable_heap_number ||
975 v8_flags.const_tracking_let) &&
976 holder_context->IsScriptContext()) {
978 value, isolate);
979 } else {
980 Cast<Context>(holder)->set(index, *value);
981 }
982 } else if (!is_sloppy_function_name || is_strict(language_mode)) {
983 THROW_NEW_ERROR(isolate,
984 NewTypeError(MessageTemplate::kConstAssign, name));
985 }
986 return value;
987 }
988
989 // Slow case: The property is not in a context slot. It is either in a
990 // context extension object, a property of the subject of a with, or a
991 // property of the global object.
992 DirectHandle<JSReceiver> object;
993 if (attributes != ABSENT) {
994 // The property exists on the holder.
995 object = Cast<JSReceiver>(holder);
996 } else if (is_strict(language_mode)) {
997 // If absent in strict mode: throw.
998 THROW_NEW_ERROR(isolate,
999 NewReferenceError(MessageTemplate::kNotDefined, name));
1000 } else {
1001 // If absent in sloppy mode: add the property to the global object.
1002 object = direct_handle(context->global_object(), isolate);
1003 }
1004
1005 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
1006 Object::SetProperty(isolate, object, name, value));
1007 return value;
1008}
1009
1010} // namespace
1011
1012
1013RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) {
1014 HandleScope scope(isolate);
1015 DCHECK_EQ(2, args.length());
1016 Handle<String> name = args.at<String>(0);
1017 DirectHandle<Object> value = args.at(1);
1018 Handle<Context> context(isolate->context(), isolate);
1020 isolate,
1021 StoreLookupSlot(isolate, context, name, value, LanguageMode::kSloppy));
1022}
1023
1024RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) {
1025 HandleScope scope(isolate);
1026 DCHECK_EQ(2, args.length());
1027 Handle<String> name = args.at<String>(0);
1028 DirectHandle<Object> value = args.at(1);
1029 Handle<Context> context(isolate->context(), isolate);
1031 isolate,
1032 StoreLookupSlot(isolate, context, name, value, LanguageMode::kStrict));
1033}
1034
1035// Store into a dynamic declaration context for sloppy-mode block-scoped
1036// function hoisting which leaks out of an eval.
1037RUNTIME_FUNCTION(Runtime_StoreLookupSlot_SloppyHoisting) {
1038 HandleScope scope(isolate);
1039 DCHECK_EQ(2, args.length());
1040 Handle<String> name = args.at<String>(0);
1041 DirectHandle<Object> value = args.at(1);
1042 const ContextLookupFlags lookup_flags =
1044 Handle<Context> declaration_context(isolate->context()->declaration_context(),
1045 isolate);
1047 isolate, StoreLookupSlot(isolate, declaration_context, name, value,
1048 LanguageMode::kSloppy, lookup_flags));
1049}
1050
1051RUNTIME_FUNCTION(Runtime_StoreGlobalNoHoleCheckForReplLetOrConst) {
1052 HandleScope scope(isolate);
1053 DCHECK_EQ(2, args.length());
1054 DirectHandle<String> name = args.at<String>(0);
1055 DirectHandle<Object> value = args.at(1);
1056
1057 DirectHandle<Context> native_context = isolate->native_context();
1058 DirectHandle<ScriptContextTable> script_contexts(
1059 native_context->script_context_table(), isolate);
1060
1061 VariableLookupResult lookup_result;
1062 bool found = script_contexts->Lookup(name, &lookup_result);
1063 CHECK(found);
1064 DirectHandle<Context> script_context(
1065 script_contexts->get(lookup_result.context_index), isolate);
1066 // We need to initialize the side data also for variables declared with
1067 // VariableMode::kConst. This is because such variables can be accessed
1068 // by functions using the LdaContextSlot bytecode, and such accesses are not
1069 // regarded as "immutable" when optimizing.
1070 if (v8_flags.script_context_mutable_heap_number ||
1071 v8_flags.const_tracking_let) {
1073 script_context, lookup_result.slot_index, value, isolate);
1074 } else {
1075 script_context->set(lookup_result.slot_index, *value);
1076 }
1077 return *value;
1078}
1079
1080} // namespace internal
1081} // namespace v8
int16_t parameter_count
Definition builtins.cc:67
static Handle< Object > Lookup(Handle< Context > context, Handle< String > name, ContextLookupFlags flags, int *index, PropertyAttributes *attributes, InitializationFlag *init_flag, VariableMode *variable_mode, bool *is_sloppy_function_name=nullptr)
Definition contexts.cc:236
static DirectHandle< Object > LoadScriptContextElement(DirectHandle< Context > script_context, int index, DirectHandle< Object > new_value, Isolate *isolate)
Definition contexts.cc:578
static void StoreScriptContextAndUpdateSlotProperty(DirectHandle< Context > script_context, int index, DirectHandle< Object > new_value, Isolate *isolate)
Definition contexts.cc:586
static const int kNotFound
Definition contexts.h:698
static void DeoptimizeDependencyGroups(Isolate *isolate, ObjectT object, DependencyGroups groups)
V8_INLINE bool is_null() const
Definition handles.h:693
JSFunctionBuilder & set_feedback_cell(DirectHandle< FeedbackCell > v)
Definition factory.h:1124
JSFunctionBuilder & set_allocation_type(AllocationType v)
Definition factory.h:1120
V8_WARN_UNUSED_RESULT Handle< JSFunction > Build()
Definition factory.cc:4732
void store(Tagged< Object > value) const
Definition slots-inl.h:54
static void InitializeJSDisposableStackBase(Isolate *isolate, DirectHandle< JSDisposableStackBase > stack)
Definition objects.cc:6384
static void HandleErrorInDisposal(Isolate *isolate, DirectHandle< JSDisposableStackBase > disposable_stack, DirectHandle< Object > current_error, DirectHandle< Object > current_error_message)
static MaybeDirectHandle< Object > DisposeResources(Isolate *isolate, DirectHandle< JSDisposableStackBase > disposable_stack, DisposableStackResourcesType resources_type)
static void Add(Isolate *isolate, DirectHandle< JSDisposableStackBase > disposable_stack, DirectHandle< Object > value, DirectHandle< Object > method, DisposeMethodCallType type, DisposeMethodHint hint)
static MaybeDirectHandle< Object > CheckValueAndGetDisposeMethod(Isolate *isolate, DirectHandle< JSAny > value, DisposeMethodHint hint)
static V8_WARN_UNUSED_RESULT HandleType< Object >::MaybeType DefineOwnPropertyIgnoreAttributes(LookupIterator *it, HandleType< T > value, PropertyAttributes attributes, AccessorInfoHandling handling=DONT_FORCE_FIELD, EnforceDefineSemantics semantics=EnforceDefineSemantics::kSet)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > V8_EXPORT_PRIVATE SetOwnPropertyIgnoreAttributes(DirectHandle< JSObject > object, DirectHandle< Name > name, DirectHandle< Object > value, PropertyAttributes attributes)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > DeleteProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name, LanguageMode language_mode=LanguageMode::kSloppy)
static V8_WARN_UNUSED_RESULT Maybe< PropertyAttributes > GetPropertyAttributes(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT Maybe< bool > SetProperty(LookupIterator *it, DirectHandle< Object > value, StoreOrigin store_origin, Maybe< ShouldThrow > should_throw=Nothing< ShouldThrow >())
Definition objects.cc:2439
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it, bool is_global_reference=false)
Definition objects.cc:1248
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static void StoreVariable(DirectHandle< SourceTextModule > module, int cell_index, DirectHandle< Object > value)
static Handle< Object > LoadVariable(Isolate *isolate, DirectHandle< SourceTextModule > module, int cell_index)
LineAndColumn current
#define RUNTIME_FUNCTION_RETURN_PAIR(Name)
Definition arguments.h:166
#define RUNTIME_FUNCTION(Name)
Definition arguments.h:162
#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:284
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:291
#define THROW_NEW_ERROR(isolate, call)
Definition isolate.h:307
#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
Definition isolate.h:276
#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)
Definition isolate.h:294
#define RETURN_FAILURE_ON_EXCEPTION(isolate, call)
Definition isolate.h:368
#define FOR_WITH_HANDLE_SCOPE(isolate, loop_var_type, init, loop_var, limit_check, increment, body)
Definition isolate.h:457
#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
Isolate * isolate
TNode< Context > context
TNode< Object > receiver
SharedFunctionInfoRef shared
ZoneVector< RpoNumber > & result
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
@ kNeedsInitialization
Definition globals.h:2225
bool IsLexicalVariableMode(VariableMode mode)
Definition globals.h:2155
Tagged(T object) -> Tagged< T >
bool IsDerivedConstructor(FunctionKind kind)
static ObjectPair MakePair(Tagged< Object > x, Tagged< Object > y)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often force marking at random points between and force scavenge at random points between and reclaim otherwise unreachable unmodified wrapper objects when possible less compaction in non memory reducing mode use high priority threads for concurrent Marking Test mode only flag It allows an unit test to select evacuation candidates use incremental marking for CppHeap cppheap_concurrent_marking c value for membalancer A special constant to balance between memory and space tradeoff The smaller the more memory it uses enable use of SSE4 instructions if available enable use of AVX VNNI instructions if available enable use of POPCNT instruction if available force all emitted branches to be in long mode(MIPS/PPC only)") DEFINE_BOOL(partial_constant_pool
bool IsNullOrUndefined(Tagged< Object > obj, Isolate *isolate)
constexpr int kSystemPointerSize
Definition globals.h:410
bool is_strict(LanguageMode language_mode)
Definition globals.h:777
V8_EXPORT_PRIVATE FlagValues v8_flags
return value
Definition map-inl.h:893
@ DONT_FOLLOW_CHAINS
Definition contexts.h:33
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
Maybe< T > Nothing()
Definition v8-maybe.h:112
Maybe< T > Just(const T &t)
Definition v8-maybe.h:117
base::Vector< const DirectHandle< Object > > array_
#define CHECK(condition)
Definition logging.h:124
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
Symbol method
Node ** parameters_