v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
js-function.cc
Go to the documentation of this file.
1// Copyright 2020 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
6
7#include <optional>
8
11#include "src/common/globals.h"
16#include "src/heap/heap-inl.h"
17#include "src/ic/ic.h"
22
23// Has to be the last include (doesn't have include guards):
25
26namespace v8::internal {
27
29 const CodeKind kind = code(isolate)->kind();
30 if (!CodeKindIsJSFunction(kind)) return {};
32 code(isolate)->marked_for_deoptimization()) {
33 return {};
34 }
36}
37
40
41 if ((result & CodeKindFlag::INTERPRETED_FUNCTION) == 0) {
42 // The SharedFunctionInfo could have attached bytecode.
43 if (shared()->HasBytecodeArray()) {
44 result |= CodeKindFlag::INTERPRETED_FUNCTION;
45 }
46 }
47
48 if ((result & CodeKindFlag::BASELINE) == 0) {
49 // The SharedFunctionInfo could have attached baseline code.
50 if (shared()->HasBaselineCode()) {
51 result |= CodeKindFlag::BASELINE;
52 }
53 }
54
55#ifndef V8_ENABLE_LEAPTIERING
56 // Check the optimized code cache.
57 if (has_feedback_vector() && feedback_vector()->has_optimized_code() &&
58 !feedback_vector()
59 ->optimized_code(isolate)
60 ->marked_for_deoptimization()) {
61 Tagged<Code> code = feedback_vector()->optimized_code(isolate);
63 result |= CodeKindToCodeKindFlag(code->kind());
64 }
65#endif // !V8_ENABLE_LEAPTIERING
66
68 return result;
69}
70
71void JSFunction::TraceOptimizationStatus(const char* format, ...) {
72 if (!v8_flags.trace_opt_status) return;
73 Isolate* const isolate = GetIsolate();
74 PrintF("[optimization status (");
75 {
76 va_list arguments;
77 va_start(arguments, format);
78 base::OS::VPrint(format, arguments);
79 va_end(arguments);
80 }
81 PrintF(")");
82 if (strlen(DebugNameCStr().get()) == 0) {
83 PrintF(" (anonymous %p)", reinterpret_cast<void*>(ptr()));
84 } else {
85 PrintF(" %s", DebugNameCStr().get());
86 }
87 if (!has_feedback_vector()) {
88 PrintF(" !feedback]\n");
89 return;
90 }
91
92 PrintF(" %s", CodeKindToString(GetActiveTier(isolate).value()));
93 if (IsMaglevRequested(isolate)) {
94 PrintF(" ^M");
95
96 } else if (IsTurbofanRequested(isolate)) {
97 PrintF(" ^TF");
98 }
99 Tagged<FeedbackVector> feedback = feedback_vector();
100 Tagged<FeedbackMetadata> metadata = feedback->metadata();
101 for (int i = 0; i < metadata->slot_count(); i++) {
102 FeedbackSlot slot(i);
103 if (metadata->GetKind(slot) == FeedbackSlotKind::kJumpLoop) {
104 Tagged<MaybeObject> value = feedback->Get(slot);
105 if (value.IsCleared()) {
106 PrintF(" .");
107 } else {
108 Tagged<Code> code =
109 Tagged<CodeWrapper>::cast(value.GetHeapObjectAssumeWeak())
110 ->code(isolate);
111 PrintF(" %i:", code->osr_offset().ToInt());
112 if (code->kind() == CodeKind::MAGLEV) {
113 PrintF("m");
114 } else {
115 DCHECK_EQ(CodeKind::TURBOFAN_JS, code->kind());
116 PrintF("t");
117 }
118 }
119 }
120 }
121 PrintF("]\n");
122}
123
128
134
136 IsolateForSandbox isolate, CodeKind kind, CodeKinds filter_mask) const {
137 const int kind_as_int_flag = static_cast<int>(CodeKindToCodeKindFlag(kind));
138 DCHECK(base::bits::IsPowerOfTwo(kind_as_int_flag));
139 // Smear right - any higher present bit means we have a higher tier available.
140 const int mask = kind_as_int_flag | (kind_as_int_flag - 1);
141 const CodeKinds masked_available_kinds =
142 GetAvailableCodeKinds(isolate) & filter_mask;
143 return (masked_available_kinds & static_cast<CodeKinds>(~mask)) != 0;
144}
145
150
156
162
163namespace {
164
165// Returns false if no highest tier exists (i.e. the function is not compiled),
166// otherwise returns true and sets highest_tier.
167V8_WARN_UNUSED_RESULT bool HighestTierOf(CodeKinds kinds,
168 CodeKind* highest_tier) {
169 DCHECK_EQ((kinds & ~kJSFunctionCodeKindsMask), 0);
170 // Higher tiers > lower tiers.
171 static_assert(CodeKind::TURBOFAN_JS > CodeKind::INTERPRETED_FUNCTION);
172 if (kinds == 0) return false;
173 const int highest_tier_log2 =
174 31 - base::bits::CountLeadingZeros(static_cast<uint32_t>(kinds));
175 DCHECK(CodeKindIsJSFunction(static_cast<CodeKind>(highest_tier_log2)));
176 *highest_tier = static_cast<CodeKind>(highest_tier_log2);
177 return true;
178}
179
180} // namespace
181
182std::optional<CodeKind> JSFunction::GetActiveTier(
183 IsolateForSandbox isolate) const {
184#if V8_ENABLE_WEBASSEMBLY
185 // Asm/Wasm functions are currently not supported. For simplicity, this
186 // includes invalid asm.js functions whose code hasn't yet been updated to
187 // CompileLazy but is still the InstantiateAsmJs builtin.
188 if (shared()->HasAsmWasmData() ||
189 code(isolate)->builtin_id() == Builtin::kInstantiateAsmJs) {
190 return {};
191 }
192#endif // V8_ENABLE_WEBASSEMBLY
193
194 CodeKind highest_tier;
195 if (!HighestTierOf(GetAvailableCodeKinds(isolate), &highest_tier)) return {};
196
197#ifdef DEBUG
198 CHECK(highest_tier == CodeKind::TURBOFAN_JS ||
199 highest_tier == CodeKind::BASELINE ||
200 highest_tier == CodeKind::MAGLEV ||
201 highest_tier == CodeKind::INTERPRETED_FUNCTION);
202
203 if (highest_tier == CodeKind::INTERPRETED_FUNCTION) {
204 CHECK(code(isolate)->is_interpreter_trampoline_builtin() ||
206 code(isolate)->marked_for_deoptimization()) ||
207 (code(isolate)->builtin_id() == Builtin::kCompileLazy &&
208 shared()->HasBytecodeArray() && !shared()->HasBaselineCode()));
209 }
210#endif // DEBUG
211
212 return highest_tier;
213}
214
216 return GetActiveTier(isolate) == CodeKind::INTERPRETED_FUNCTION;
217}
218
220 return GetActiveTier(isolate) == CodeKind::BASELINE;
221}
222
224 return GetActiveTier(isolate) == CodeKind::MAGLEV;
225}
226
228 return GetActiveTier(isolate) == CodeKind::TURBOFAN_JS;
229}
230
232 // Essentially, what we are asking here is, has this function been compiled
233 // from JS code? We can currently tell only indirectly, by looking at
234 // available code kinds. If any JS code kind exists, we can discard.
235 //
236 // Attached optimized code that is marked for deoptimization will not show up
237 // in the list of available code kinds, thus we must check for it manually.
238 //
239 // Note that when the function has not yet been compiled we also return
240 // false; that's fine, since nothing must be discarded in that case.
241 if (CodeKindIsOptimizedJSFunction(code(isolate)->kind())) return true;
243 return (result & kJSFunctionCodeKindsMask) != 0;
244}
245
246namespace {
247
248#ifndef V8_ENABLE_LEAPTIERING
249constexpr TieringState TieringStateFor(CodeKind target_kind,
250 ConcurrencyMode mode) {
251 DCHECK(target_kind == CodeKind::MAGLEV ||
252 target_kind == CodeKind::TURBOFAN_JS);
253 return target_kind == CodeKind::MAGLEV
254 ? (IsConcurrent(mode) ? TieringState::kRequestMaglev_Concurrent
255 : TieringState::kRequestMaglev_Synchronous)
256 : (IsConcurrent(mode)
257 ? TieringState::kRequestTurbofan_Concurrent
258 : TieringState::kRequestTurbofan_Synchronous);
259}
260#endif // !V8_ENABLE_LEAPTIERING
261
262} // namespace
263
265 ConcurrencyMode mode) {
266 if (!isolate->concurrent_recompilation_enabled() ||
267 isolate->bootstrapper()->IsActive()) {
269 }
270
272 DCHECK(!is_compiled(isolate) || ActiveTierIsIgnition(isolate) ||
273 ActiveTierIsBaseline(isolate) || ActiveTierIsMaglev(isolate));
274 DCHECK(!ActiveTierIsTurbofan(isolate));
275 DCHECK(shared()->HasBytecodeArray());
276 DCHECK(shared()->allows_lazy_compilation() ||
277 !shared()->optimization_disabled());
278
279 if (IsConcurrent(mode)) {
280 if (tiering_in_progress()) {
281 if (v8_flags.trace_concurrent_recompilation) {
282 PrintF(" ** Not marking ");
283 ShortPrint(*this);
284 PrintF(" -- already in optimization queue.\n");
285 }
286 return;
287 }
288 if (v8_flags.trace_concurrent_recompilation) {
289 PrintF(" ** Marking ");
290 ShortPrint(*this);
291 PrintF(" for concurrent %s recompilation.\n",
292 CodeKindToString(target_kind));
293 }
294 }
295
296#ifdef V8_ENABLE_LEAPTIERING
297 JSDispatchTable* jdt = IsolateGroup::current()->js_dispatch_table();
298 switch (target_kind) {
299 case CodeKind::MAGLEV:
300 switch (mode) {
302 jdt->SetTieringRequest(dispatch_handle(),
303 TieringBuiltin::kStartMaglevOptimizeJob,
304 isolate);
305 break;
307 jdt->SetTieringRequest(dispatch_handle(),
308 TieringBuiltin::kOptimizeMaglevEager, isolate);
309 break;
310 }
311 break;
312 case CodeKind::TURBOFAN_JS:
313 switch (mode) {
315 jdt->SetTieringRequest(dispatch_handle(),
316 TieringBuiltin::kStartTurbofanOptimizeJob,
317 isolate);
318 break;
320 jdt->SetTieringRequest(dispatch_handle(),
321 TieringBuiltin::kOptimizeTurbofanEager,
322 isolate);
323 break;
324 }
325 break;
326 default:
327 UNREACHABLE();
328 }
329#else
330 set_tiering_state(isolate, TieringStateFor(target_kind, mode));
331#endif // V8_ENABLE_LEAPTIERING
332}
333
336 std::optional<CodeKind> override_active_tier) {
337 int32_t current = raw_feedback_cell()->interrupt_budget();
338 int32_t new_budget =
339 TieringManager::InterruptBudgetFor(isolate, *this, override_active_tier);
340 switch (kind) {
342 new_budget = std::max(current, new_budget);
343 break;
345 new_budget = std::min(current, new_budget);
346 break;
348 break;
349 }
350 raw_feedback_cell()->set_interrupt_budget(new_budget);
351}
352
353// static
355 Isolate* isolate,
358 int arg_count) {
359 // Setup the "length" property based on the "length" of the {target}.
360 // If the targets length is the default JSFunction accessor, we can keep the
361 // accessor that's installed by default on the
362 // JSBoundFunction/JSWrappedFunction. It lazily computes the value from the
363 // underlying internal length.
364 DirectHandle<AccessorInfo> function_length_accessor =
365 isolate->factory()->function_length_accessor();
366 LookupIterator length_lookup(isolate, target,
367 isolate->factory()->length_string(), target,
369 if (!IsJSFunction(*target) ||
370 length_lookup.state() != LookupIterator::ACCESSOR ||
371 !length_lookup.GetAccessors().is_identical_to(function_length_accessor)) {
373 Maybe<PropertyAttributes> attributes =
374 JSReceiver::GetPropertyAttributes(&length_lookup);
375 if (attributes.IsNothing()) return Nothing<bool>();
376 if (attributes.FromJust() != ABSENT) {
377 DirectHandle<Object> target_length;
378 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_length,
379 Object::GetProperty(&length_lookup),
380 Nothing<bool>());
381 if (IsNumber(*target_length)) {
382 length = isolate->factory()->NewNumber(std::max(
383 0.0,
384 DoubleToInteger(Object::NumberValue(*target_length)) - arg_count));
385 }
386 }
387 LookupIterator it(isolate, function, isolate->factory()->length_string(),
388 function);
392 &it, length, it.property_attributes()),
393 Nothing<bool>());
394 }
395
396 // Setup the "name" property based on the "name" of the {target}.
397 // If the target's name is the default JSFunction accessor, we can keep the
398 // accessor that's installed by default on the
399 // JSBoundFunction/JSWrappedFunction. It lazily computes the value from the
400 // underlying internal name.
401 DirectHandle<AccessorInfo> function_name_accessor =
402 isolate->factory()->function_name_accessor();
403 LookupIterator name_lookup(isolate, target, isolate->factory()->name_string(),
404 target);
405 if (!IsJSFunction(*target) ||
406 name_lookup.state() != LookupIterator::ACCESSOR ||
407 !name_lookup.GetAccessors().is_identical_to(function_name_accessor) ||
408 (name_lookup.IsFound() && !name_lookup.HolderIsReceiver())) {
409 DirectHandle<Object> target_name;
410 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_name,
411 Object::GetProperty(&name_lookup),
412 Nothing<bool>());
414 if (IsString(*target_name)) {
416 isolate, name,
417 Name::ToFunctionName(isolate, Cast<String>(target_name)),
418 Nothing<bool>());
419 if (!prefix.is_null()) {
421 isolate, name, isolate->factory()->NewConsString(prefix, name),
422 Nothing<bool>());
423 }
424 } else if (prefix.is_null()) {
425 name = isolate->factory()->empty_string();
426 } else {
427 name = prefix;
428 }
429 LookupIterator it(isolate, function, isolate->factory()->name_string());
433 &it, name, it.property_attributes()),
434 Nothing<bool>());
435 }
436
437 return Just(true);
438}
439
440// static
442 Isolate* isolate, DirectHandle<JSBoundFunction> function) {
443 Handle<String> prefix = isolate->factory()->bound__string();
444 Handle<String> target_name = prefix;
445 Factory* factory = isolate->factory();
446 // Concatenate the "bound " up to the last non-bound target.
447 while (IsJSBoundFunction(function->bound_target_function())) {
448 ASSIGN_RETURN_ON_EXCEPTION(isolate, target_name,
449 factory->NewConsString(prefix, target_name));
450 function = direct_handle(
451 Cast<JSBoundFunction>(function->bound_target_function()), isolate);
452 }
453 if (IsJSWrappedFunction(function->bound_target_function())) {
455 Cast<JSWrappedFunction>(function->bound_target_function()), isolate);
457 ASSIGN_RETURN_ON_EXCEPTION(isolate, name,
458 JSWrappedFunction::GetName(isolate, target));
459 return factory->NewConsString(target_name, name);
460 }
461 if (IsJSFunction(function->bound_target_function())) {
463 Cast<JSFunction>(function->bound_target_function()), isolate);
464 Handle<String> name = JSFunction::GetName(isolate, target);
465 return factory->NewConsString(target_name, name);
466 }
467 // This will omit the proper target name for bound JSProxies.
468 return target_name;
469}
470
471// static
474 int nof_bound_arguments = function->bound_arguments()->length();
475 while (IsJSBoundFunction(function->bound_target_function())) {
476 function = direct_handle(
477 Cast<JSBoundFunction>(function->bound_target_function()), isolate);
478 // Make sure we never overflow {nof_bound_arguments}, the number of
479 // arguments of a function is strictly limited by the max length of an
480 // JSAarray, Smi::kMaxValue is thus a reasonably good overestimate.
481 int length = function->bound_arguments()->length();
482 if (V8_LIKELY(Smi::kMaxValue - nof_bound_arguments > length)) {
483 nof_bound_arguments += length;
484 } else {
485 nof_bound_arguments = Smi::kMaxValue;
486 }
487 }
488 if (IsJSWrappedFunction(function->bound_target_function())) {
490 Cast<JSWrappedFunction>(function->bound_target_function()), isolate);
491 int target_length = 0;
493 isolate, target_length, JSWrappedFunction::GetLength(isolate, target),
494 Nothing<int>());
495 int length = std::max(0, target_length - nof_bound_arguments);
496 return Just(length);
497 }
498 // All non JSFunction targets get a direct property and don't use this
499 // accessor.
501 Cast<JSFunction>(function->bound_target_function()), isolate);
502 int target_length = target->length();
503
504 int length = std::max(0, target_length - nof_bound_arguments);
505 return Just(length);
506}
507
508// static
511 Isolate* const isolate = function->GetIsolate();
512 return isolate->factory()->function_native_code_string();
513}
514
515// static
517 Isolate* isolate, DirectHandle<JSWrappedFunction> function) {
519 Factory* factory = isolate->factory();
520 Handle<String> target_name = factory->empty_string();
521 DirectHandle<JSReceiver> target(function->wrapped_target_function(), isolate);
522 if (IsJSBoundFunction(*target)) {
524 isolate, direct_handle(
525 Cast<JSBoundFunction>(function->wrapped_target_function()),
526 isolate));
527 } else if (IsJSFunction(*target)) {
528 return JSFunction::GetName(
529 isolate,
530 direct_handle(Cast<JSFunction>(function->wrapped_target_function()),
531 isolate));
532 }
533 // This will omit the proper target name for bound JSProxies.
534 return target_name;
535}
536
537// static
539 Isolate* isolate, DirectHandle<JSWrappedFunction> function) {
540 STACK_CHECK(isolate, Nothing<int>());
541 DirectHandle<JSReceiver> target(function->wrapped_target_function(), isolate);
542 if (IsJSBoundFunction(*target)) {
544 isolate, direct_handle(
545 Cast<JSBoundFunction>(function->wrapped_target_function()),
546 isolate));
547 }
548 // All non JSFunction targets get a direct property and don't use this
549 // accessor.
550 return Just(Cast<JSFunction>(target)->length());
551}
552
553// static
556 Isolate* const isolate = function->GetIsolate();
557 return isolate->factory()->function_native_code_string();
558}
559
560// static
562 Isolate* isolate, DirectHandle<NativeContext> creation_context,
564 // The value must be a callable according to the specification.
565 DCHECK(IsCallable(*value));
566 // The intermediate wrapped functions are not user-visible. And calling a
567 // wrapped function won't cause a side effect in the creation realm.
568 // Unwrap here to avoid nested unwrapping at the call site.
569 if (IsJSWrappedFunction(*value)) {
570 auto target_wrapped = Cast<JSWrappedFunction>(value);
571 value = direct_handle(target_wrapped->wrapped_target_function(), isolate);
572 }
573
574 // 1. Let internalSlotsList be the internal slots listed in Table 2, plus
575 // [[Prototype]] and [[Extensible]].
576 // 2. Let wrapped be ! MakeBasicObject(internalSlotsList).
577 // 3. Set wrapped.[[Prototype]] to
578 // callerRealm.[[Intrinsics]].[[%Function.prototype%]].
579 // 4. Set wrapped.[[Call]] as described in 2.1.
580 // 5. Set wrapped.[[WrappedTargetFunction]] to Target.
581 // 6. Set wrapped.[[Realm]] to callerRealm.
583 isolate->factory()->NewJSWrappedFunction(creation_context, value);
584
585 // 7. Let result be CopyNameAndLength(wrapped, Target, "wrapped").
586 Maybe<bool> is_abrupt =
588 isolate, wrapped, value, DirectHandle<String>(), 0);
589
590 // 8. If result is an Abrupt Completion, throw a TypeError exception.
591 if (is_abrupt.IsNothing()) {
592 DCHECK(isolate->has_exception());
593 DirectHandle<Object> exception(isolate->exception(), isolate);
594 isolate->clear_exception();
595
596 // The TypeError thrown is created with creation Realm's TypeError
597 // constructor instead of the executing Realm's.
598 DirectHandle<JSFunction> type_error_function(
599 creation_context->type_error_function(), isolate);
600 DirectHandle<String> string =
601 Object::NoSideEffectsToString(isolate, exception);
603 isolate,
604 NewError(type_error_function, MessageTemplate::kCannotWrap, string),
605 {});
606 }
607 DCHECK(is_abrupt.FromJust());
608
609 // 9. Return wrapped.
610 return wrapped;
611}
612
613// static
615 DirectHandle<JSFunction> function) {
616 if (function->shared()->name_should_print_as_anonymous()) {
617 return isolate->factory()->anonymous_string();
618 }
619 return handle(function->shared()->Name(), isolate);
620}
621
622// static
624 DirectHandle<JSFunction> function) {
625 Isolate* const isolate = function->GetIsolate();
626 DCHECK(function->shared()->is_compiled());
627 DCHECK(function->shared()->HasFeedbackMetadata());
628#if V8_ENABLE_WEBASSEMBLY
629 if (function->shared()->HasAsmWasmData()) return;
630#endif // V8_ENABLE_WEBASSEMBLY
631
632 DirectHandle<SharedFunctionInfo> shared(function->shared(), isolate);
633 DCHECK(shared->HasBytecodeArray());
635 (function->has_closure_feedback_cell_array() ||
636 function->has_feedback_vector());
637
639 return;
640 }
641
642 // Many closure cell is used as a way to specify that there is no
643 // feedback cell for this function and a new feedback cell has to be
644 // allocated for this function. For ex: for eval functions, we have to create
645 // a feedback cell and cache it along with the code. It is safe to use
646 // many_closure_cell to indicate this because in regular cases, it should
647 // already have a feedback_vector / feedback cell array allocated.
648 const bool allocate_new_feedback_cell =
649 function->raw_feedback_cell() ==
650 *isolate->factory()->many_closures_cell();
651
652 DirectHandle<ClosureFeedbackCellArray> feedback_cell_array =
653 ClosureFeedbackCellArray::New(isolate, shared);
654 if (allocate_new_feedback_cell) {
655 DirectHandle<FeedbackCell> feedback_cell =
656 isolate->factory()->NewOneClosureCell(feedback_cell_array);
657#ifdef V8_ENABLE_LEAPTIERING
658 // This is a rare case where we copy the dispatch entry from a JSFunction
659 // to its FeedbackCell instead of the other way around.
660 // TODO(42204201): investigate whether this can be avoided so that we only
661 // ever copy a dispatch handle from a FeedbackCell to a JSFunction. That
662 // would probably require refactoring the way JSFunctions are built so that
663 // we always allocate a FeedbackCell up front (if needed).
664 DCHECK_NE(function->dispatch_handle(), kNullJSDispatchHandle);
665 // The feedback cell should never contain context specialized code.
666 DCHECK(!function->code(isolate)->is_context_specialized());
667 feedback_cell->set_dispatch_handle(function->dispatch_handle());
668#endif // V8_ENABLE_LEAPTIERING
669 function->set_raw_feedback_cell(*feedback_cell, kReleaseStore);
670 } else {
671 function->raw_feedback_cell()->set_value(*feedback_cell_array,
673 }
674 // Initialize the interrupt budget when initializing the feedback cell with
675 // the closure feedback cell for the first time, whether the feedback cell
676 // itself is new or not.
677 function->SetInterruptBudget(isolate, BudgetModification::kReset);
678}
679
680// static
683 IsCompiledScope* compiled_scope) {
684 CHECK(compiled_scope->is_compiled());
685 DCHECK(function->shared()->HasFeedbackMetadata());
686 if (function->has_feedback_vector()) return;
687#if V8_ENABLE_WEBASSEMBLY
688 if (function->shared()->HasAsmWasmData()) return;
689#endif // V8_ENABLE_WEBASSEMBLY
690
691 CreateAndAttachFeedbackVector(isolate, function, compiled_scope);
692}
693
694// static
696 Isolate* isolate, DirectHandle<JSFunction> function,
697 IsCompiledScope* compiled_scope) {
698 CHECK(compiled_scope->is_compiled());
699 DCHECK(function->shared()->HasFeedbackMetadata());
700 DCHECK(!function->has_feedback_vector());
701#if V8_ENABLE_WEBASSEMBLY
702 DCHECK(!function->shared()->HasAsmWasmData());
703#endif // V8_ENABLE_WEBASSEMBLY
704
705 DirectHandle<SharedFunctionInfo> shared(function->shared(), isolate);
706 DCHECK(function->shared()->HasBytecodeArray());
707
710 function->closure_feedback_cell_array(), isolate);
712 isolate, shared, closure_feedback_cell_array,
713 direct_handle(function->raw_feedback_cell(isolate), isolate),
714 compiled_scope);
715 USE(feedback_vector);
716 // EnsureClosureFeedbackCellArray should handle the special case where we need
717 // to allocate a new feedback cell. Please look at comment in that function
718 // for more details.
719 DCHECK(function->raw_feedback_cell() !=
720 *isolate->factory()->many_closures_cell());
721 DCHECK_EQ(function->raw_feedback_cell()->value(), *feedback_vector);
722 function->SetInterruptBudget(isolate, BudgetModification::kRaise);
723
724#ifndef V8_ENABLE_LEAPTIERING
725 DCHECK_EQ(v8_flags.log_function_events,
726 feedback_vector->log_next_execution());
727#endif
728
729 if (v8_flags.profile_guided_optimization &&
730 v8_flags.profile_guided_optimization_for_empty_feedback_vector &&
731 function->feedback_vector()->length() == 0) {
732 if (function->shared()->cached_tiering_decision() ==
734 function->RequestOptimization(isolate, CodeKind::MAGLEV,
736 } else if (function->shared()->cached_tiering_decision() ==
738 function->RequestOptimization(isolate, CodeKind::TURBOFAN_JS,
740 }
741 }
742}
743
744// static
746 DirectHandle<JSFunction> function, IsCompiledScope* is_compiled_scope,
747 bool reset_budget_for_feedback_allocation) {
748 Isolate* const isolate = function->GetIsolate();
749#if V8_ENABLE_WEBASSEMBLY
750 // The following checks ensure that the feedback vectors are compatible with
751 // the feedback metadata. For Asm / Wasm functions we never allocate / use
752 // feedback vectors, so a mismatch between the metadata and feedback vector is
753 // harmless. The checks could fail for functions that has has_asm_wasm_broken
754 // set at runtime (for ex: failed instantiation).
755 if (function->shared()->HasAsmWasmData()) return;
756#endif // V8_ENABLE_WEBASSEMBLY
757
758 if (function->has_feedback_vector()) {
759 CHECK_EQ(function->feedback_vector()->length(),
760 function->feedback_vector()->metadata()->slot_count());
761 return;
762 }
763
765 function->has_closure_feedback_cell_array();
767 CHECK_EQ(
768 function->closure_feedback_cell_array()->length(),
769 function->shared()->feedback_metadata()->create_closure_slot_count());
770 }
771
772 const bool needs_feedback_vector =
773 !v8_flags.lazy_feedback_allocation || v8_flags.always_turbofan ||
774 // We also need a feedback vector for certain log events, collecting type
775 // profile and more precise code coverage.
776 v8_flags.log_function_events ||
777 !isolate->is_best_effort_code_coverage() ||
778 function->shared()->cached_tiering_decision() !=
780
781 if (needs_feedback_vector) {
782 CreateAndAttachFeedbackVector(isolate, function, is_compiled_scope);
784 // Initialize the interrupt budget to the feedback vector allocation budget
785 // after a bytecode flush. We retain the closure feedback cell array on
786 // bytecode flush, so reset_budget_for_feedback_allocation is used to reset
787 // the budget in this case.
788 if (reset_budget_for_feedback_allocation) {
789 function->SetInterruptBudget(isolate, BudgetModification::kReset);
790 }
791 } else {
793 }
794#ifdef V8_ENABLE_SPARKPLUG
795 // TODO(jgruber): Unduplicate these conditions from tiering-manager.cc.
796 if (function->shared()->cached_tiering_decision() !=
798 CanCompileWithBaseline(isolate, function->shared()) &&
799 function->ActiveTierIsIgnition(isolate)) {
800 if (v8_flags.baseline_batch_compilation) {
801 isolate->baseline_batch_compiler()->EnqueueFunction(function);
802 } else {
803 IsCompiledScope is_compiled_inner_scope(
804 function->shared()->is_compiled_scope(isolate));
806 &is_compiled_inner_scope);
807 }
808 }
809#endif // V8_ENABLE_SPARKPLUG
810}
811
812namespace {
813
814void SetInstancePrototype(Isolate* isolate, DirectHandle<JSFunction> function,
816 // Now some logic for the maps of the objects that are created by using this
817 // function as a constructor.
818 if (function->has_initial_map()) {
819 // If the function has allocated the initial map replace it with a
820 // copy containing the new prototype. Also complete any in-object
821 // slack tracking that is in progress at this point because it is
822 // still tracking the old copy.
823 function->CompleteInobjectSlackTrackingIfActive();
824
825 DirectHandle<Map> initial_map(function->initial_map(), isolate);
826
827 if (!isolate->bootstrapper()->IsActive() &&
828 initial_map->instance_type() == JS_OBJECT_TYPE) {
829 // Put the value in the initial map field until an initial map is needed.
830 // At that point, a new initial map is created and the prototype is put
831 // into the initial map where it belongs.
832 function->set_prototype_or_initial_map(*value, kReleaseStore);
834 // Optimize as prototype to detach it from its transition tree.
836 }
837 } else {
838 DirectHandle<Map> new_map =
839 Map::Copy(isolate, initial_map, "SetInstancePrototype");
840 JSFunction::SetInitialMap(isolate, function, new_map, value);
841 DCHECK_IMPLIES(!isolate->bootstrapper()->IsActive(),
842 *function != function->native_context()->array_function());
843 }
844
845 // Deoptimize all code that embeds the previous initial map.
847 isolate, *initial_map, DependentCode::kInitialMapChangedGroup);
848 } else {
849 // Put the value in the initial map field until an initial map is
850 // needed. At that point, a new initial map is created and the
851 // prototype is put into the initial map where it belongs.
852 function->set_prototype_or_initial_map(*value, kReleaseStore);
854 // Optimize as prototype to detach it from its transition tree.
856 }
857 }
858}
859
860} // anonymous namespace
861
863 DirectHandle<Object> value) {
864 DCHECK(IsConstructor(*function) ||
865 IsGeneratorFunction(function->shared()->kind()));
866 Isolate* isolate = function->GetIsolate();
867 DirectHandle<JSReceiver> construct_prototype;
868
869 // If the value is not a JSReceiver, store the value in the map's
870 // constructor field so it can be accessed. Also, set the prototype
871 // used for constructing objects to the original object prototype.
872 // See ECMA-262 13.2.2.
873 if (!IsJSReceiver(*value)) {
874 // Copy the map so this does not affect unrelated functions.
875 // Remove map transitions because they point to maps with a
876 // different prototype.
878 isolate, direct_handle(function->map(), isolate), "SetPrototype");
879
880 // Create a new {constructor, non-instance_prototype} tuple and store it
881 // in Map::constructor field.
882 DirectHandle<Object> constructor(new_map->GetConstructor(), isolate);
883 DirectHandle<Tuple2> non_instance_prototype_constructor_tuple =
884 isolate->factory()->NewTuple2(constructor, value, AllocationType::kOld);
885
886 new_map->set_has_non_instance_prototype(true);
887 new_map->SetConstructor(*non_instance_prototype_constructor_tuple);
888
889 JSObject::MigrateToMap(isolate, function, new_map);
890
891 FunctionKind kind = function->shared()->kind();
892 DirectHandle<Context> native_context(function->native_context(), isolate);
893
894 construct_prototype = direct_handle(
897 ? native_context->initial_async_generator_prototype()
898 : native_context->initial_generator_prototype()
899 : native_context->initial_object_prototype(),
900 isolate);
901 } else {
902 construct_prototype = Cast<JSReceiver>(value);
903 function->map()->set_has_non_instance_prototype(false);
904 }
905
906 SetInstancePrototype(isolate, function, construct_prototype);
907}
908
912 DirectHandle<JSPrototype> prototype) {
913 SetInitialMap(isolate, function, map, prototype, function);
914}
915
920 DirectHandle<JSFunction> constructor) {
921 if (map->prototype() != *prototype) {
922 Map::SetPrototype(isolate, map, prototype);
923 }
924 map->SetConstructor(*constructor);
925 function->set_prototype_or_initial_map(*map, kReleaseStore);
926 if (v8_flags.log_maps) {
927 LOG(isolate,
928 MapEvent("InitialMap", {}, map, "",
930 isolate, direct_handle(function->shared(), isolate))));
931 }
932}
933
935 DCHECK(function->has_prototype_slot());
936 DCHECK(IsConstructor(*function) ||
937 IsResumableFunction(function->shared()->kind()));
938 if (function->has_initial_map()) return;
939 Isolate* isolate = function->GetIsolate();
940
941 int expected_nof_properties =
942 CalculateExpectedNofProperties(isolate, function);
943
944 // {CalculateExpectedNofProperties} can have had the side effect of creating
945 // the initial map (e.g. it could have triggered an optimized compilation
946 // whose dependency installation reentered {EnsureHasInitialMap}).
947 if (function->has_initial_map()) return;
948
949 // Create a new map with the size and number of in-object properties suggested
950 // by the function.
951 InstanceType instance_type;
952 if (IsResumableFunction(function->shared()->kind())) {
953 instance_type = IsAsyncGeneratorFunction(function->shared()->kind())
954 ? JS_ASYNC_GENERATOR_OBJECT_TYPE
955 : JS_GENERATOR_OBJECT_TYPE;
956 } else {
957 instance_type = JS_OBJECT_TYPE;
958 }
959
960 int instance_size;
961 int inobject_properties;
962 CalculateInstanceSizeHelper(instance_type, false, 0, expected_nof_properties,
963 &instance_size, &inobject_properties);
964
965 DirectHandle<NativeContext> creation_context(function->native_context(),
966 isolate);
967 DirectHandle<Map> map = isolate->factory()->NewContextfulMap(
968 creation_context, instance_type, instance_size,
969 TERMINAL_FAST_ELEMENTS_KIND, inobject_properties);
970
971 // Fetch or allocate prototype.
973 if (function->has_instance_prototype()) {
974 prototype = direct_handle(function->instance_prototype(), isolate);
975 map->set_prototype(*prototype);
976 } else {
977 prototype = isolate->factory()->NewFunctionPrototype(function);
978 Map::SetPrototype(isolate, map, prototype);
979 }
980 DCHECK(map->has_fast_object_elements());
981
982 // Finally link initial map and constructor function.
983 // This is a CHECK since the prototype could be Null according to the type
984 // system.
985 // TODO(leszeks): Figure out if this CHECK is needed.
986 CHECK(IsJSReceiver(*prototype));
987 JSFunction::SetInitialMap(isolate, function, map, prototype);
988 map->StartInobjectSlackTracking();
989}
990
991namespace {
992
993#ifdef DEBUG
994bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
995 switch (instance_type) {
996 case JS_API_OBJECT_TYPE:
997 case JS_ARRAY_BUFFER_TYPE:
998 case JS_ARRAY_ITERATOR_PROTOTYPE_TYPE:
999 case JS_ARRAY_TYPE:
1000 case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
1001 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1002 case JS_DATA_VIEW_TYPE:
1003 case JS_RAB_GSAB_DATA_VIEW_TYPE:
1004 case JS_DATE_TYPE:
1005 case JS_GENERATOR_OBJECT_TYPE:
1006 case JS_FUNCTION_TYPE:
1007 case JS_CLASS_CONSTRUCTOR_TYPE:
1008 case JS_PROMISE_CONSTRUCTOR_TYPE:
1009 case JS_REG_EXP_CONSTRUCTOR_TYPE:
1010 case JS_ARRAY_CONSTRUCTOR_TYPE:
1011 case JS_ASYNC_DISPOSABLE_STACK_TYPE:
1012 case JS_SYNC_DISPOSABLE_STACK_TYPE:
1013#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
1014 case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
1016#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
1017 case JS_ITERATOR_PROTOTYPE_TYPE:
1018 case JS_MAP_ITERATOR_PROTOTYPE_TYPE:
1019 case JS_OBJECT_PROTOTYPE_TYPE:
1020 case JS_PROMISE_PROTOTYPE_TYPE:
1021 case JS_REG_EXP_PROTOTYPE_TYPE:
1022 case JS_SET_ITERATOR_PROTOTYPE_TYPE:
1023 case JS_SET_PROTOTYPE_TYPE:
1024 case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
1025 case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
1026#ifdef V8_INTL_SUPPORT
1027 case JS_COLLATOR_TYPE:
1028 case JS_DATE_TIME_FORMAT_TYPE:
1029 case JS_DISPLAY_NAMES_TYPE:
1030 case JS_DURATION_FORMAT_TYPE:
1031 case JS_LIST_FORMAT_TYPE:
1032 case JS_LOCALE_TYPE:
1033 case JS_NUMBER_FORMAT_TYPE:
1034 case JS_PLURAL_RULES_TYPE:
1035 case JS_RELATIVE_TIME_FORMAT_TYPE:
1036 case JS_SEGMENT_ITERATOR_TYPE:
1037 case JS_SEGMENTER_TYPE:
1038 case JS_SEGMENTS_TYPE:
1039 case JS_V8_BREAK_ITERATOR_TYPE:
1040#endif
1041 case JS_ASYNC_FUNCTION_OBJECT_TYPE:
1042 case JS_ASYNC_GENERATOR_OBJECT_TYPE:
1043 case JS_MAP_TYPE:
1044 case JS_MESSAGE_OBJECT_TYPE:
1045 case JS_OBJECT_TYPE:
1046 case JS_ERROR_TYPE:
1047 case JS_FINALIZATION_REGISTRY_TYPE:
1048 case JS_ARGUMENTS_OBJECT_TYPE:
1049 case JS_PROMISE_TYPE:
1050 case JS_REG_EXP_TYPE:
1051 case JS_SET_TYPE:
1052 case JS_SHADOW_REALM_TYPE:
1053 case JS_SPECIAL_API_OBJECT_TYPE:
1054 case JS_TYPED_ARRAY_TYPE:
1055 case JS_PRIMITIVE_WRAPPER_TYPE:
1056 case JS_TEMPORAL_CALENDAR_TYPE:
1057 case JS_TEMPORAL_DURATION_TYPE:
1058 case JS_TEMPORAL_INSTANT_TYPE:
1059 case JS_TEMPORAL_PLAIN_DATE_TYPE:
1060 case JS_TEMPORAL_PLAIN_DATE_TIME_TYPE:
1061 case JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE:
1062 case JS_TEMPORAL_PLAIN_TIME_TYPE:
1063 case JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE:
1064 case JS_TEMPORAL_TIME_ZONE_TYPE:
1065 case JS_TEMPORAL_ZONED_DATE_TIME_TYPE:
1066 case JS_WEAK_MAP_TYPE:
1067 case JS_WEAK_REF_TYPE:
1068 case JS_WEAK_SET_TYPE:
1069#if V8_ENABLE_WEBASSEMBLY
1070 case WASM_GLOBAL_OBJECT_TYPE:
1071 case WASM_INSTANCE_OBJECT_TYPE:
1072 case WASM_MEMORY_OBJECT_TYPE:
1073 case WASM_MODULE_OBJECT_TYPE:
1074 case WASM_TABLE_OBJECT_TYPE:
1075 case WASM_VALUE_OBJECT_TYPE:
1076#endif // V8_ENABLE_WEBASSEMBLY
1077 return true;
1078
1079 case BIGINT_TYPE:
1080 case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
1081 case BYTECODE_ARRAY_TYPE:
1082 case BYTE_ARRAY_TYPE:
1083 case CELL_TYPE:
1084 case INSTRUCTION_STREAM_TYPE:
1085 case FILLER_TYPE:
1086 case FIXED_ARRAY_TYPE:
1087 case SCRIPT_CONTEXT_TABLE_TYPE:
1088 case FIXED_DOUBLE_ARRAY_TYPE:
1089 case FEEDBACK_METADATA_TYPE:
1090 case FOREIGN_TYPE:
1091 case FREE_SPACE_TYPE:
1092 case HASH_TABLE_TYPE:
1093 case ORDERED_HASH_MAP_TYPE:
1094 case ORDERED_HASH_SET_TYPE:
1095 case ORDERED_NAME_DICTIONARY_TYPE:
1096 case NAME_DICTIONARY_TYPE:
1097 case GLOBAL_DICTIONARY_TYPE:
1098 case NUMBER_DICTIONARY_TYPE:
1099 case SIMPLE_NUMBER_DICTIONARY_TYPE:
1100 case HEAP_NUMBER_TYPE:
1101 case JS_BOUND_FUNCTION_TYPE:
1102 case JS_GLOBAL_OBJECT_TYPE:
1103 case JS_GLOBAL_PROXY_TYPE:
1104 case JS_PROXY_TYPE:
1105 case JS_WRAPPED_FUNCTION_TYPE:
1106 case MAP_TYPE:
1107 case ODDBALL_TYPE:
1108 case PROPERTY_CELL_TYPE:
1109 case CONTEXT_SIDE_PROPERTY_CELL_TYPE:
1110 case SHARED_FUNCTION_INFO_TYPE:
1111 case SYMBOL_TYPE:
1112 case ALLOCATION_SITE_TYPE:
1113
1114#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1115 case FIXED_##TYPE##_ARRAY_TYPE:
1116#undef TYPED_ARRAY_CASE
1117
1118#define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
1120#undef MAKE_STRUCT_CASE
1121 // We must not end up here for these instance types at all.
1122 UNREACHABLE();
1123
1124 default:
1125 if (InstanceTypeChecker::IsJSApiObject(instance_type)) return true;
1126 return false;
1127 }
1128}
1129#endif // DEBUG
1130
1131bool FastInitializeDerivedMap(Isolate* isolate,
1132 DirectHandle<JSFunction> new_target,
1133 DirectHandle<JSFunction> constructor,
1134 DirectHandle<Map> constructor_initial_map) {
1135 // Use the default intrinsic prototype instead.
1136 if (!new_target->has_prototype_slot()) return false;
1137 // Check that |function|'s initial map still in sync with the |constructor|,
1138 // otherwise we must create a new initial map for |function|.
1139 if (new_target->has_initial_map() &&
1140 new_target->initial_map()->GetConstructor() == *constructor) {
1141 DCHECK(IsJSReceiver(new_target->instance_prototype()));
1142 return true;
1143 }
1144 InstanceType instance_type = constructor_initial_map->instance_type();
1145 DCHECK(CanSubclassHaveInobjectProperties(instance_type));
1146 // Create a new map with the size and number of in-object properties
1147 // suggested by |function|.
1148
1149 // Link initial map and constructor function if the new.target is actually a
1150 // subclass constructor.
1151 if (!IsDerivedConstructor(new_target->shared()->kind())) return false;
1152
1153 int instance_size;
1154 int in_object_properties;
1155 int embedder_fields =
1156 JSObject::GetEmbedderFieldCount(*constructor_initial_map);
1157 // Constructor expects certain number of in-object properties to be in the
1158 // object. However, CalculateExpectedNofProperties() may return smaller value
1159 // if 1) the constructor is not in the prototype chain of new_target, or
1160 // 2) the prototype chain is modified during iteration, or 3) compilation
1161 // failure occur during prototype chain iteration.
1162 // So we take the maximum of two values.
1163 int expected_nof_properties = std::max(
1164 static_cast<int>(constructor->shared()->expected_nof_properties()),
1167 instance_type, constructor_initial_map->has_prototype_slot(),
1168 embedder_fields, expected_nof_properties, &instance_size,
1169 &in_object_properties);
1170
1171 int pre_allocated = constructor_initial_map->GetInObjectProperties() -
1172 constructor_initial_map->UnusedPropertyFields();
1173 CHECK_LE(constructor_initial_map->UsedInstanceSize(), instance_size);
1174 int unused_property_fields = in_object_properties - pre_allocated;
1175 DirectHandle<Map> map =
1176 Map::CopyInitialMap(isolate, constructor_initial_map, instance_size,
1177 in_object_properties, unused_property_fields);
1178 map->set_new_target_is_base(false);
1179 DirectHandle<JSPrototype> prototype(new_target->instance_prototype(),
1180 isolate);
1181 JSFunction::SetInitialMap(isolate, new_target, map, prototype, constructor);
1182 DCHECK(IsJSReceiver(new_target->instance_prototype()));
1183 map->set_construction_counter(Map::kNoSlackTracking);
1184 map->StartInobjectSlackTracking();
1185 return true;
1186}
1187
1188} // namespace
1189
1190// static
1192 Isolate* isolate, DirectHandle<JSFunction> constructor,
1194 EnsureHasInitialMap(constructor);
1195
1196 DirectHandle<Map> constructor_initial_map(constructor->initial_map(),
1197 isolate);
1198 if (*new_target == *constructor) {
1199 return indirect_handle(constructor_initial_map, isolate);
1200 }
1201
1202 DirectHandle<Map> result_map;
1203 // Fast case, new.target is a subclass of constructor. The map is cacheable
1204 // (and may already have been cached). new.target.prototype is guaranteed to
1205 // be a JSReceiver.
1206 InstanceType new_target_instance_type = new_target->map()->instance_type();
1207 if (InstanceTypeChecker::IsJSFunction(new_target_instance_type)) {
1209 if (FastInitializeDerivedMap(isolate, function, constructor,
1210 constructor_initial_map)) {
1211 return handle(function->initial_map(), isolate);
1212 }
1213 }
1214
1215 // Slow path, new.target is either a proxy object or can't cache the map.
1216 // new.target.prototype is not guaranteed to be a JSReceiver, and may need to
1217 // fall back to the intrinsicDefaultProto.
1219 if (InstanceTypeChecker::IsJSFunction(new_target_instance_type) &&
1222 // Make sure the new.target.prototype is cached.
1223 EnsureHasInitialMap(function);
1224 prototype = direct_handle(function->prototype(), isolate);
1225 } else {
1226 // The new.target is a constructor but it's not a JSFunction with
1227 // a prototype slot, so get the prototype property.
1228 DirectHandle<String> prototype_string =
1229 isolate->factory()->prototype_string();
1231 isolate, prototype,
1232 JSReceiver::GetProperty(isolate, new_target, prototype_string));
1233 // The above prototype lookup might change the constructor and its
1234 // prototype, hence we have to reload the initial map.
1235 EnsureHasInitialMap(constructor);
1236 constructor_initial_map =
1237 direct_handle(constructor->initial_map(), isolate);
1238 }
1239
1240 // If prototype is not a JSReceiver, fetch the intrinsicDefaultProto from the
1241 // correct realm. Rather than directly fetching the .prototype, we fetch the
1242 // constructor that points to the .prototype. This relies on
1243 // constructor.prototype being FROZEN for those constructors.
1244 if (!IsJSReceiver(*prototype)) {
1249 isolate, constructor,
1250 isolate->factory()->native_context_index_symbol());
1251 int index = IsSmi(*maybe_index) ? Smi::ToInt(*maybe_index)
1252 : Context::OBJECT_FUNCTION_INDEX;
1253 DirectHandle<JSFunction> realm_constructor(
1254 Cast<JSFunction>(native_context->get(index)), isolate);
1255 prototype = direct_handle(realm_constructor->prototype(), isolate);
1256 }
1257 DCHECK_EQ(constructor_initial_map->constructor_or_back_pointer(),
1258 *constructor);
1259 return Map::GetDerivedMap(isolate, constructor_initial_map,
1260 Cast<JSReceiver>(prototype));
1261}
1262
1263namespace {
1264
1265// Assert that the computations in TypedArrayElementsKindToConstructorIndex and
1266// TypedArrayElementsKindToRabGsabCtorIndex are sound.
1267#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
1268 static_assert(Context::TYPE##_ARRAY_FUN_INDEX == \
1269 Context::FIRST_FIXED_TYPED_ARRAY_FUN_INDEX + \
1270 ElementsKind::TYPE##_ELEMENTS - \
1271 ElementsKind::FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND); \
1272 static_assert(Context::RAB_GSAB_##TYPE##_ARRAY_MAP_INDEX == \
1273 Context::FIRST_RAB_GSAB_TYPED_ARRAY_MAP_INDEX + \
1274 ElementsKind::TYPE##_ELEMENTS - \
1275 ElementsKind::FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
1276
1278#undef TYPED_ARRAY_CASE
1279
1280int TypedArrayElementsKindToConstructorIndex(ElementsKind elements_kind) {
1281 return Context::FIRST_FIXED_TYPED_ARRAY_FUN_INDEX + elements_kind -
1283}
1284
1285int TypedArrayElementsKindToRabGsabCtorIndex(ElementsKind elements_kind) {
1286 return Context::FIRST_RAB_GSAB_TYPED_ARRAY_MAP_INDEX + elements_kind -
1288}
1289
1290} // namespace
1291
1293 Isolate* isolate, DirectHandle<JSFunction> constructor,
1295 MaybeDirectHandle<Map> maybe_map =
1296 GetDerivedMap(isolate, constructor, new_target);
1298 if (!maybe_map.ToHandle(&map)) return {};
1299 {
1300 DisallowHeapAllocation no_alloc;
1301 Tagged<NativeContext> context = isolate->context()->native_context();
1302 int ctor_index =
1303 TypedArrayElementsKindToConstructorIndex(map->elements_kind());
1304 if (*new_target == context->get(ctor_index)) {
1305 ctor_index =
1306 TypedArrayElementsKindToRabGsabCtorIndex(map->elements_kind());
1307 return direct_handle(Cast<Map>(context->get(ctor_index)), isolate);
1308 }
1309 }
1310
1311 // This only happens when subclassing TypedArrays. Create a new map with the
1312 // corresponding RAB / GSAB ElementsKind. Note: the map is not cached and
1313 // reused -> every array gets a unique map, making ICs slow.
1314 DirectHandle<Map> rab_gsab_map = Map::Copy(isolate, map, "RAB / GSAB");
1315 rab_gsab_map->set_elements_kind(
1316 GetCorrespondingRabGsabElementsKind(map->elements_kind()));
1317 return rab_gsab_map;
1318}
1319
1322 DirectHandle<Context> context(isolate->context()->native_context(), isolate);
1323 DirectHandle<JSFunction> constructor(context->data_view_fun(), isolate);
1324 MaybeDirectHandle<Map> maybe_map =
1325 GetDerivedMap(isolate, constructor, new_target);
1327 if (!maybe_map.ToHandle(&map)) return {};
1328 if (*map == constructor->initial_map()) {
1329 return direct_handle(Cast<Map>(context->js_rab_gsab_data_view_map()),
1330 isolate);
1331 }
1332
1333 // This only happens when subclassing DataViews. Create a new map with the
1334 // JS_RAB_GSAB_DATA_VIEW instance type. Note: the map is not cached and
1335 // reused -> every data view gets a unique map, making ICs slow.
1336 DirectHandle<Map> rab_gsab_map = Map::Copy(isolate, map, "RAB / GSAB");
1337 rab_gsab_map->set_instance_type(JS_RAB_GSAB_DATA_VIEW_TYPE);
1338 return rab_gsab_map;
1339}
1340
1342 CHECK(has_initial_map());
1343 if (initial_map()->IsInobjectSlackTrackingInProgress()) {
1344 int slack = initial_map()->ComputeMinObjectSlack(isolate);
1345 return initial_map()->InstanceSizeFromSlack(slack);
1346 }
1347 return initial_map()->instance_size();
1348}
1349
1350std::unique_ptr<char[]> JSFunction::DebugNameCStr() {
1351 return shared()->DebugNameCStr();
1352}
1353
1354void JSFunction::PrintName(FILE* out) {
1355 PrintF(out, "%s", DebugNameCStr().get());
1356}
1357
1358namespace {
1359
1360bool UseFastFunctionNameLookup(Isolate* isolate, Tagged<Map> map) {
1361 DCHECK(IsJSFunctionMap(map));
1362 if (map->NumberOfOwnDescriptors() <
1364 return false;
1365 }
1366 DCHECK(!map->is_dictionary_map());
1368 ReadOnlyRoots roots(isolate);
1369 auto descriptors = map->instance_descriptors(isolate);
1370 InternalIndex kNameIndex{JSFunction::kNameDescriptorIndex};
1371 if (descriptors->GetKey(kNameIndex) != roots.name_string() ||
1372 !descriptors->GetValue(kNameIndex)
1373 .GetHeapObjectIfStrong(isolate, &value)) {
1374 return false;
1375 }
1376 return IsAccessorInfo(value);
1377}
1378
1379} // namespace
1380
1382 DirectHandle<JSFunction> function) {
1383 // Below we use the same fast-path that we already established for
1384 // Function.prototype.bind(), where we avoid a slow "name" property
1385 // lookup if the DescriptorArray for the |function| still has the
1386 // "name" property at the original spot and that property is still
1387 // implemented via an AccessorInfo (which effectively means that
1388 // it must be the FunctionNameGetter).
1389 Isolate* isolate = function->GetIsolate();
1390 if (!UseFastFunctionNameLookup(isolate, function->map())) {
1391 // Normally there should be an else case for the fast-path check
1392 // above, which should invoke JSFunction::GetName(), since that's
1393 // what the FunctionNameGetter does, however GetDataProperty() has
1394 // never invoked accessors and thus always returned undefined for
1395 // JSFunction where the "name" property is untouched, so we retain
1396 // that exact behavior and go with SharedFunctionInfo::DebugName()
1397 // in case of the fast-path.
1399 GetDataProperty(isolate, function, isolate->factory()->name_string());
1400 if (IsString(*name)) return Cast<String>(name);
1401 }
1403 isolate, direct_handle(function->shared(), isolate));
1404}
1405
1408 Isolate* isolate = function->GetIsolate();
1409 DirectHandle<String> function_name;
1410 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, function_name,
1411 Name::ToFunctionName(isolate, name), false);
1412 if (prefix->length() > 0) {
1413 IncrementalStringBuilder builder(isolate);
1414 builder.AppendString(prefix);
1415 builder.AppendCharacter(' ');
1416 builder.AppendString(function_name);
1417 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, function_name, builder.Finish(),
1418 false);
1419 }
1421 isolate,
1423 function, isolate->factory()->name_string(), function_name,
1424 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)),
1425 false);
1426 return true;
1427}
1428
1429namespace {
1430
1431DirectHandle<String> NativeCodeFunctionSourceString(
1432 Isolate* isolate, DirectHandle<SharedFunctionInfo> shared_info) {
1433 IncrementalStringBuilder builder(isolate);
1434 builder.AppendCStringLiteral("function ");
1435 builder.AppendString(direct_handle(shared_info->Name(), isolate));
1436 builder.AppendCStringLiteral("() { [native code] }");
1437 return builder.Finish().ToHandleChecked();
1438}
1439
1440} // namespace
1441
1442// static
1444 Isolate* const isolate = function->GetIsolate();
1445 DirectHandle<SharedFunctionInfo> shared_info(function->shared(), isolate);
1446
1447 // Check if {function} should hide its source code.
1448 if (!shared_info->IsUserJavaScript()) {
1449 return NativeCodeFunctionSourceString(isolate, shared_info);
1450 }
1451
1452 if (IsClassConstructor(shared_info->kind())) {
1453 // Check if we should print {function} as a class.
1454 DirectHandle<Object> maybe_class_positions = JSReceiver::GetDataProperty(
1455 isolate, function, isolate->factory()->class_positions_symbol());
1456 if (IsClassPositions(*maybe_class_positions)) {
1457 Tagged<ClassPositions> class_positions =
1458 Cast<ClassPositions>(*maybe_class_positions);
1459 int start_position = class_positions->start();
1460 int end_position = class_positions->end();
1461 Handle<String> script_source(
1462 Cast<String>(Cast<Script>(shared_info->script())->source()), isolate);
1463 return isolate->factory()->NewSubString(script_source, start_position,
1464 end_position);
1465 }
1466 }
1467
1468 // Check if we have source code for the {function}.
1469 if (!shared_info->HasSourceCode()) {
1470 return NativeCodeFunctionSourceString(isolate, shared_info);
1471 }
1472
1473 // If this function was compiled from asm.js, use the recorded offset
1474 // information.
1475#if V8_ENABLE_WEBASSEMBLY
1476 if (shared_info->HasWasmExportedFunctionData()) {
1478 shared_info->wasm_exported_function_data(), isolate);
1479 const wasm::WasmModule* module = function_data->instance_data()->module();
1480 if (is_asmjs_module(module)) {
1481 std::pair<int, int> offsets =
1482 module->asm_js_offset_information->GetFunctionOffsets(
1483 declared_function_index(module, function_data->function_index()));
1485 Cast<String>(Cast<Script>(shared_info->script())->source()), isolate);
1486 return isolate->factory()->NewSubString(source, offsets.first,
1487 offsets.second);
1488 }
1489 }
1490#endif // V8_ENABLE_WEBASSEMBLY
1491
1492 if (shared_info->function_token_position() == kNoSourcePosition) {
1493 // If the function token position isn't valid, return [native code] to
1494 // ensure calling eval on the returned source code throws rather than
1495 // giving inconsistent call behaviour.
1496 isolate->CountUsage(
1498 return NativeCodeFunctionSourceString(isolate, shared_info);
1499 }
1500 return Cast<String>(
1501 SharedFunctionInfo::GetSourceCodeHarmony(isolate, shared_info));
1502}
1503
1504// static
1506 Isolate* isolate, DirectHandle<JSFunction> function) {
1507 int expected_nof_properties = 0;
1508 for (PrototypeIterator iter(isolate, function, kStartAtReceiver);
1509 !iter.IsAtEnd(); iter.Advance()) {
1510 DirectHandle<JSReceiver> current =
1512 if (!IsJSFunction(*current)) break;
1514 // The super constructor should be compiled for the number of expected
1515 // properties to be available.
1516 DirectHandle<SharedFunctionInfo> shared(func->shared(), isolate);
1517 IsCompiledScope is_compiled_scope(shared->is_compiled_scope(isolate));
1518 if (is_compiled_scope.is_compiled() ||
1520 &is_compiled_scope)) {
1521 DCHECK(shared->is_compiled());
1522 int count = shared->expected_nof_properties();
1523 // Check that the estimate is sensible.
1524 if (expected_nof_properties <= JSObject::kMaxInObjectProperties - count) {
1525 expected_nof_properties += count;
1526 } else {
1528 }
1529 } else {
1530 // In case there was a compilation error proceed iterating in case there
1531 // will be a builtin function in the prototype chain that requires
1532 // certain number of in-object properties.
1533 continue;
1534 }
1535 }
1536 // Inobject slack tracking will reclaim redundant inobject space
1537 // later, so we can afford to adjust the estimate generously,
1538 // meaning we over-allocate by at least 8 slots in the beginning.
1539 if (expected_nof_properties > 0) {
1540 expected_nof_properties += 8;
1541 if (expected_nof_properties > JSObject::kMaxInObjectProperties) {
1542 expected_nof_properties = JSObject::kMaxInObjectProperties;
1543 }
1544 }
1545 return expected_nof_properties;
1546}
1547
1548// static
1550 bool has_prototype_slot,
1551 int requested_embedder_fields,
1552 int requested_in_object_properties,
1553 int* instance_size,
1554 int* in_object_properties) {
1555 DCHECK_LE(static_cast<unsigned>(requested_embedder_fields),
1557 int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot);
1558 requested_embedder_fields *= kEmbedderDataSlotSizeInTaggedSlots;
1559
1560 int max_nof_fields =
1563 CHECK_LE(static_cast<unsigned>(requested_embedder_fields),
1564 static_cast<unsigned>(max_nof_fields));
1565 *in_object_properties = std::min(requested_in_object_properties,
1566 max_nof_fields - requested_embedder_fields);
1567 *instance_size =
1568 header_size +
1569 ((requested_embedder_fields + *in_object_properties) << kTaggedSizeLog2);
1570 CHECK_EQ(*in_object_properties,
1571 ((*instance_size - header_size) >> kTaggedSizeLog2) -
1572 requested_embedder_fields);
1573 CHECK_LE(static_cast<unsigned>(*instance_size),
1574 static_cast<unsigned>(JSObject::kMaxInstanceSize));
1575}
1576
1578 Isolate* isolate = GetIsolate();
1579 ResetIfCodeFlushed(isolate);
1580 if (has_feedback_vector()) {
1581 Tagged<FeedbackVector> vector = feedback_vector();
1582 if (vector->ClearAllSlotsForTesting(isolate)) {
1584 "ClearAllTypeFeedbackInfoForTesting");
1585 }
1586 }
1587}
1588
1589} // namespace v8::internal
1590
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype)
Builtins::Kind kind
Definition builtins.cc:40
@ kFunctionTokenOffsetTooLongForToString
Definition v8-isolate.h:518
V8_INLINE T FromJust() const &
Definition v8-maybe.h:64
V8_INLINE bool IsNothing() const
Definition v8-maybe.h:35
static V8_EXPORT_PRIVATE DirectHandle< ClosureFeedbackCellArray > New(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared, AllocationType allocation=AllocationType::kYoung)
static bool CompileBaseline(Isolate *isolate, DirectHandle< JSFunction > function, ClearExceptionFlag flag, IsCompiledScope *is_compiled_scope)
Definition compiler.cc:3132
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 const int FIRST_FIXED_TYPED_ARRAY_FUN_INDEX
Definition contexts.h:573
static const int FIRST_RAB_GSAB_TYPED_ARRAY_MAP_INDEX
Definition contexts.h:574
static void DeoptimizeDependencyGroups(Isolate *isolate, ObjectT object, DependencyGroups groups)
V8_INLINE bool is_null() const
Definition handles.h:693
V8_WARN_UNUSED_RESULT HandleType< String >::MaybeType NewConsString(HandleType< String > left, HandleType< String > right, AllocationType allocation=AllocationType::kYoung)
static FeedbackSlot Invalid()
Definition utils.h:648
static V8_EXPORT_PRIVATE Handle< FeedbackVector > New(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared, DirectHandle< ClosureFeedbackCellArray > closure_feedback_cell_array, DirectHandle< FeedbackCell > parent_feedback_cell, IsCompiledScope *is_compiled_scope)
static void OnFeedbackChanged(Isolate *isolate, Tagged< FeedbackVector > vector, FeedbackSlot slot, const char *reason)
Definition ic.cc:312
MaybeDirectHandle< String > Finish()
V8_INLINE void AppendCharacter(uint8_t c)
V8_INLINE void AppendString(std::string_view str)
static IsolateGroup * current()
v8::internal::Factory * factory()
Definition isolate.h:1527
static MaybeHandle< String > GetName(Isolate *isolate, DirectHandle< JSBoundFunction > function)
static Maybe< int > GetLength(Isolate *isolate, DirectHandle< JSBoundFunction > function)
static DirectHandle< String > ToString(DirectHandle< JSBoundFunction > function)
static Maybe< bool > CopyNameAndLength(Isolate *isolate, DirectHandle< JSFunctionOrBoundFunctionOrWrappedFunction > function, DirectHandle< JSReceiver > target, DirectHandle< String > prefix, int arg_count)
std::unique_ptr< char[]> DebugNameCStr()
static void CalculateInstanceSizeHelper(InstanceType instance_type, bool has_prototype_slot, int requested_embedder_fields, int requested_in_object_properties, int *instance_size, int *in_object_properties)
Tagged< Context > context()
void RequestOptimization(Isolate *isolate, CodeKind target_kind, ConcurrencyMode mode=ConcurrencyMode::kConcurrent)
bool HasAvailableHigherTierCodeThan(IsolateForSandbox isolate, CodeKind kind) const
static void SetPrototype(DirectHandle< JSFunction > function, DirectHandle< Object > value)
int ComputeInstanceSizeWithMinSlack(Isolate *isolate)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Map > GetDerivedRabGsabDataViewMap(Isolate *isolate, DirectHandle< JSReceiver > new_target)
static V8_WARN_UNUSED_RESULT bool SetName(DirectHandle< JSFunction > function, DirectHandle< Name > name, DirectHandle< String > prefix)
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_WARN_UNUSED_RESULT int CalculateExpectedNofProperties(Isolate *isolate, DirectHandle< JSFunction > function)
bool IsMaglevRequested(Isolate *isolate) const
static Handle< String > GetName(Isolate *isolate, DirectHandle< JSFunction > function)
bool HasAvailableCodeKind(IsolateForSandbox isolate, CodeKind kind) const
bool HasAvailableHigherTierCodeThanWithFilter(IsolateForSandbox isolate, CodeKind kind, CodeKinds filter_mask) const
void set_tiering_state(IsolateForSandbox isolate, TieringState state)
CodeKinds GetAttachedCodeKinds(IsolateForSandbox isolate) const
bool HasAvailableOptimizedCode(IsolateForSandbox isolate) const
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Map > GetDerivedRabGsabTypedArrayMap(Isolate *isolate, DirectHandle< JSFunction > constructor, DirectHandle< JSReceiver > new_target)
bool has_closure_feedback_cell_array() const
bool ActiveTierIsMaglev(IsolateForSandbox isolate) const
static V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT MaybeHandle< Map > GetDerivedMap(Isolate *isolate, DirectHandle< JSFunction > constructor, DirectHandle< JSReceiver > new_target)
static DirectHandle< String > GetDebugName(DirectHandle< JSFunction > function)
static const int kMinDescriptorsForFastBindAndWrap
bool HasAttachedCodeKind(IsolateForSandbox isolate, CodeKind kind) const
bool is_compiled(IsolateForSandbox isolate) const
static void InitializeFeedbackCell(DirectHandle< JSFunction > function, IsCompiledScope *compiled_scope, bool reset_budget_for_feedback_allocation)
static V8_EXPORT_PRIVATE void EnsureHasInitialMap(DirectHandle< JSFunction > function)
bool IsTurbofanRequested(Isolate *isolate) const
bool ActiveTierIsBaseline(IsolateForSandbox isolate) const
static void EnsureClosureFeedbackCellArray(DirectHandle< JSFunction > function)
static DirectHandle< String > ToString(DirectHandle< JSFunction > function)
Tagged< ClosureFeedbackCellArray > closure_feedback_cell_array() const
CodeKinds GetAvailableCodeKinds(IsolateForSandbox isolate) const
Tagged< NativeContext > native_context()
V8_EXPORT_PRIVATE bool HasAttachedOptimizedCode(IsolateForSandbox isolate) const
void SetInterruptBudget(Isolate *isolate, BudgetModification kind, std::optional< CodeKind > override_active_tier={})
static void SetInitialMap(Isolate *isolate, DirectHandle< JSFunction > function, DirectHandle< Map > map, DirectHandle< JSPrototype > prototype)
bool ActiveTierIsTurbofan(IsolateForSandbox isolate) const
static void CreateAndAttachFeedbackVector(Isolate *isolate, DirectHandle< JSFunction > function, IsCompiledScope *compiled_scope)
std::optional< CodeKind > GetActiveTier(IsolateForSandbox isolate) const
void ResetIfCodeFlushed(Isolate *isolate, std::optional< std::function< void(Tagged< HeapObject > object, ObjectSlot slot, Tagged< HeapObject > target)> > gc_notify_updated_slot=std::nullopt)
bool CanDiscardCompiled(IsolateForSandbox isolate) const
V8_EXPORT_PRIVATE bool ActiveTierIsIgnition(IsolateForSandbox isolate) const
void PrintName(FILE *out=stdout)
static const int kMaxInObjectProperties
Definition js-objects.h:959
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)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > DefinePropertyOrElementIgnoreAttributes(DirectHandle< JSObject > object, DirectHandle< Name > name, DirectHandle< Object > value, PropertyAttributes attributes=NONE)
static void OptimizeAsPrototype(DirectHandle< JSObject > object, bool enable_setup_mode=true)
int GetEmbedderFieldCount() const
static const int kMaxInstanceSize
Definition js-objects.h:945
static const int kMaxEmbedderFields
Definition js-objects.h:965
static V8_EXPORT_PRIVATE void MigrateToMap(Isolate *isolate, DirectHandle< JSObject > object, DirectHandle< Map > new_map, int expected_additional_properties=0)
static V8_EXPORT_PRIVATE int GetHeaderSize(InstanceType instance_type, bool function_has_prototype_slot=false)
static MaybeDirectHandle< NativeContext > GetFunctionRealm(DirectHandle< JSReceiver > receiver)
static Handle< Object > GetDataProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
static V8_WARN_UNUSED_RESULT Maybe< PropertyAttributes > GetPropertyAttributes(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(Isolate *isolate, DirectHandle< JSReceiver > receiver, const char *key)
static DirectHandle< String > ToString(DirectHandle< JSWrappedFunction > function)
static Maybe< int > GetLength(Isolate *isolate, DirectHandle< JSWrappedFunction > function)
static MaybeDirectHandle< Object > Create(Isolate *isolate, DirectHandle< NativeContext > creation_context, DirectHandle< JSReceiver > value)
static MaybeHandle< String > GetName(Isolate *isolate, DirectHandle< JSWrappedFunction > function)
DirectHandle< Object > GetAccessors() const
Definition lookup.cc:1064
bool HolderIsReceiver() const
Definition lookup.cc:908
static const int kNoSlackTracking
Definition map.h:349
static Handle< Map > Copy(Isolate *isolate, DirectHandle< Map > map, const char *reason, TransitionKindFlag kind=SPECIAL_TRANSITION)
Definition map.cc:1811
static V8_EXPORT_PRIVATE void SetPrototype(Isolate *isolate, DirectHandle< Map > map, DirectHandle< JSPrototype > prototype, bool enable_prototype_setup_mode=true)
Definition map.cc:2467
static Handle< Map > GetDerivedMap(Isolate *isolate, DirectHandle< Map > from, DirectHandle< JSReceiver > prototype)
Definition map.cc:934
static Handle< Map > CopyInitialMap(Isolate *isolate, DirectHandle< Map > map)
Definition map-inl.h:1008
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToFunctionName(Isolate *isolate, DirectHandle< Name > name)
Definition objects.cc:4049
static V8_EXPORT_PRIVATE DirectHandle< String > NoSideEffectsToString(Isolate *isolate, DirectHandle< Object > input)
Definition objects.cc:687
static double NumberValue(Tagged< Number > obj)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it, bool is_global_reference=false)
Definition objects.cc:1248
Tagged< T > GetCurrent() const
Definition prototype.h:52
static Handle< Object > GetSourceCodeHarmony(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared)
static Handle< String > DebugName(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared)
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static constexpr Tagged< Smi > zero()
Definition smi.h:99
static constexpr int kMaxValue
Definition smi.h:101
static int InterruptBudgetFor(Isolate *isolate, Tagged< JSFunction > function, std::optional< CodeKind > override_active_tier={})
Handle< Code > code
uint32_t count
#define TYPED_ARRAYS(V)
#define THROW_NEW_ERROR_RETURN_VALUE(isolate, call, value)
Definition isolate.h:300
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:291
#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
Definition isolate.h:276
#define STACK_CHECK(isolate, result_value)
Definition isolate.h:3067
#define RETURN_ON_EXCEPTION_VALUE(isolate, call, value)
Definition isolate.h:340
#define MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
Definition isolate.h:440
DirectHandle< Object > new_target
Definition execution.cc:75
TNode< Object > target
SharedFunctionInfoRef shared
std::map< const std::string, const std::string > map
ZoneVector< RpoNumber > & result
#define LOG(isolate, Call)
Definition log.h:78
uint32_t const mask
InstructionOperand source
constexpr unsigned CountLeadingZeros(T value)
Definition bits.h:100
constexpr bool IsPowerOfTwo(T value)
Definition bits.h:187
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
constexpr bool CodeKindIsOptimizedJSFunction(CodeKind kind)
Definition code-kind.h:66
constexpr int kNoSourcePosition
Definition globals.h:850
bool IsClassConstructor(FunctionKind kind)
bool IsNumber(Tagged< Object > obj)
void PrintF(const char *format,...)
Definition utils.cc:39
const char * CodeKindToString(CodeKind kind)
Definition code-kind.cc:10
Tagged(T object) -> Tagged< T >
bool IsGeneratorFunction(FunctionKind kind)
bool IsDerivedConstructor(FunctionKind kind)
double DoubleToInteger(double x)
ElementsKind GetCorrespondingRabGsabElementsKind(ElementsKind typed_array_kind)
bool IsResumableFunction(FunctionKind kind)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
V8_INLINE IndirectHandle< T > indirect_handle(DirectHandle< T > handle)
Definition handles.h:757
kInterpreterTrampolineOffset Tagged< HeapObject >
bool IsAsyncFunction(FunctionKind kind)
@ FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND
@ TERMINAL_FAST_ELEMENTS_KIND
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
constexpr int kTaggedSizeLog2
Definition globals.h:543
constexpr int kEmbedderDataSlotSizeInTaggedSlots
Definition globals.h:666
constexpr CodeKindFlag CodeKindToCodeKindFlag(CodeKind kind)
Definition code-kind.h:135
bool IsAsyncGeneratorFunction(FunctionKind kind)
constexpr JSDispatchHandle kNullJSDispatchHandle(0)
void ShortPrint(Tagged< Object > obj, FILE *out)
Definition objects.cc:1865
bool IsJSObjectThatCanBeTrackedAsPrototype(Tagged< Object > obj)
Definition objects-inl.h:96
static constexpr CodeKinds kOptimizedJSFunctionCodeKindsMask
Definition code-kind.h:148
static constexpr CodeKinds kJSFunctionCodeKindsMask
Definition code-kind.h:145
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr bool CodeKindIsJSFunction(CodeKind kind)
Definition code-kind.h:72
return value
Definition map-inl.h:893
constexpr bool IsConcurrent(ConcurrencyMode mode)
Definition globals.h:2599
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset prototype
Definition map-inl.h:69
bool CanCompileWithBaseline(Isolate *isolate, Tagged< SharedFunctionInfo > shared)
Definition baseline.cc:82
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
static constexpr ReleaseStoreTag kReleaseStore
Definition globals.h:2910
Maybe< T > Nothing()
Definition v8-maybe.h:112
Maybe< T > Just(const T &t)
Definition v8-maybe.h:117
#define STRUCT_LIST(V)
#define MAKE_STRUCT_CASE(TYPE, Name, name)
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define CHECK(condition)
Definition logging.h:124
#define CHECK_LE(lhs, rhs)
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#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 TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype)
#define V8_LIKELY(condition)
Definition v8config.h:661
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671