26void Builtins::Generate_ConstructVarargs(MacroAssembler* masm) {
30void Builtins::Generate_ConstructForwardVarargs(MacroAssembler* masm) {
35void Builtins::Generate_ConstructFunctionForwardVarargs(MacroAssembler* masm) {
37 Builtin::kConstructFunction);
41void Builtins::Generate_InterpreterForwardAllArgsThenConstruct(
42 MacroAssembler* masm) {
48void Builtins::Generate_ConstructForwardAllArgs(MacroAssembler* masm) {
54 auto target = Parameter<JSAny>(Descriptor::kTarget);
55 auto new_target = Parameter<JSAny>(Descriptor::kNewTarget);
56 auto argc = UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
57 auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
60 target,
new_target, argc, [=,
this] {
return LoadContextFromBaseline(); },
61 [=,
this] {
return LoadFeedbackVectorFromBaseline(); }, slot,
66 auto target = Parameter<JSAny>(Descriptor::kTarget);
67 auto new_target = Parameter<JSAny>(Descriptor::kNewTarget);
68 auto argc = UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
69 auto context = Parameter<Context>(Descriptor::kContext);
70 auto feedback_vector = Parameter<FeedbackVector>(Descriptor::kFeedbackVector);
71 auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
75 [=] {
return feedback_vector; }, slot,
85 Label if_construct_generic(
this), if_construct_array(
this);
88 CollectConstructFeedback(eager_context, target,
new_target, feedback_vector(),
90 &if_construct_generic, &if_construct_array,
93 BIND(&if_construct_generic);
96 BIND(&if_construct_array);
102 auto target = Parameter<JSAny>(Descriptor::kTarget);
103 auto new_target = Parameter<JSAny>(Descriptor::kNewTarget);
104 auto arguments_list = Parameter<Object>(Descriptor::kArgumentsList);
105 auto context = Parameter<Context>(Descriptor::kContext);
106 CallOrConstructWithArrayLike(target,
new_target, arguments_list, context);
110 auto target = Parameter<JSAny>(Descriptor::kTarget);
111 auto new_target = Parameter<JSAny>(Descriptor::kNewTarget);
112 auto spread = Parameter<JSAny>(Descriptor::kSpread);
114 UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
115 auto context = Parameter<Context>(Descriptor::kContext);
116 CallOrConstructWithSpread(target,
new_target, spread, args_count, context);
120 auto target = Parameter<JSAny>(Descriptor::kTarget);
121 auto new_target = Parameter<JSAny>(Descriptor::kNewTarget);
122 auto spread = Parameter<JSAny>(Descriptor::kSpread);
124 UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
125 auto slot = UncheckedParameter<TaggedIndex>(Descriptor::kSlot);
126 return BuildConstructWithSpread(
128 [=,
this] {
return LoadContextFromBaseline(); },
129 [=,
this] {
return LoadFeedbackVectorFromBaseline(); }, slot,
134 auto target = Parameter<JSAny>(Descriptor::kTarget);
135 auto new_target = Parameter<JSAny>(Descriptor::kNewTarget);
136 auto spread = Parameter<JSAny>(Descriptor::kSpread);
138 UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
139 auto context = Parameter<Context>(Descriptor::kContext);
140 auto feedback_vector = Parameter<FeedbackVector>(Descriptor::kVector);
141 auto slot = UncheckedParameter<TaggedIndex>(Descriptor::kSlot);
143 return BuildConstructWithSpread(
145 [=] {
return feedback_vector; }, slot,
155 Label if_construct_generic(
this), if_construct_array(
this);
157 CollectConstructFeedback(eager_context, target,
new_target, feedback_vector(),
159 &if_construct_generic, &if_construct_array,
162 BIND(&if_construct_array);
163 Goto(&if_construct_generic);
165 BIND(&if_construct_generic);
170 auto target = Parameter<JSAny>(Descriptor::kTarget);
171 auto new_target = Parameter<JSAny>(Descriptor::kNewTarget);
172 auto slot = UncheckedParameter<TaggedIndex>(Descriptor::kSlot);
174 return BuildConstructForwardAllArgs(
175 target,
new_target, [=,
this] {
return LoadContextFromBaseline(); },
176 [=,
this] {
return LoadFeedbackVectorFromBaseline(); }, slot);
181 auto target = Parameter<JSAny>(Descriptor::kTarget);
182 auto new_target = Parameter<JSAny>(Descriptor::kNewTarget);
183 auto slot = UncheckedParameter<TaggedIndex>(Descriptor::kSlot);
184 auto feedback_vector = Parameter<FeedbackVector>(Descriptor::kVector);
185 auto context = Parameter<Context>(Descriptor::kContext);
187 return BuildConstructForwardAllArgs(
189 [=] {
return feedback_vector; }, slot);
200 Label construct(
this);
201 CollectConstructFeedback(eager_context, target,
new_target, feedback_vector(),
203 &construct, &construct, &allocation_site);
206 TailCallBuiltin(Builtin::kConstructForwardAllArgs, eager_context, target,
211 auto shared_function_info =
212 Parameter<SharedFunctionInfo>(Descriptor::kSharedFunctionInfo);
213 auto feedback_cell = Parameter<FeedbackCell>(Descriptor::kFeedbackCell);
214 auto context = Parameter<Context>(Descriptor::kContext);
218 const TNode<Map> feedback_cell_map = LoadMap(feedback_cell);
219 Label no_closures(
this), one_closure(
this), cell_done(
this);
221 GotoIf(IsNoClosuresCellMap(feedback_cell_map), &no_closures);
222 GotoIf(IsOneClosureCellMap(feedback_cell_map), &one_closure);
223 CSA_DCHECK(
this, IsManyClosuresCellMap(feedback_cell_map),
224 feedback_cell_map, feedback_cell);
228 StoreMapNoWriteBarrier(feedback_cell, RootIndex::kOneClosureCellMap);
232#ifdef V8_ENABLE_LEAPTIERING
240 TailCallRuntime(Runtime::kNewClosure, context, shared_function_info,
243 StoreMapNoWriteBarrier(feedback_cell, RootIndex::kManyClosuresCellMap);
253 shared_function_info, SharedFunctionInfo::kFlagsOffset);
255 DecodeWordFromWord32<SharedFunctionInfo::FunctionMapIndexBits>(flags),
269 TimesTaggedSize(LoadMapInstanceSizeInWords(function_map));
271 StoreMapNoWriteBarrier(
result, function_map);
272 InitializeJSObjectBodyNoSlackTracking(
result, function_map,
273 instance_size_in_bytes,
277 StoreObjectFieldRoot(
result, JSObject::kPropertiesOrHashOffset,
278 RootIndex::kEmptyFixedArray);
279 StoreObjectFieldRoot(
result, JSObject::kElementsOffset,
280 RootIndex::kEmptyFixedArray);
283 Label done(
this), init_prototype(
this);
284 Branch(IsFunctionWithPrototypeSlotMap(function_map), &init_prototype,
287 BIND(&init_prototype);
288 StoreObjectFieldRoot(
result, JSFunction::kPrototypeOrInitialMapOffset,
289 RootIndex::kTheHoleValue);
295 StoreObjectFieldNoWriteBarrier(
result, JSFunction::kFeedbackCellOffset,
297 StoreObjectFieldNoWriteBarrier(
result, JSFunction::kSharedFunctionInfoOffset,
298 shared_function_info);
299 StoreObjectFieldNoWriteBarrier(
result, JSFunction::kContextOffset, context);
300#ifdef V8_ENABLE_LEAPTIERING
302 feedback_cell, FeedbackCell::kDispatchHandleOffset);
304 Word32NotEqual(dispatch_handle,
306 StoreObjectFieldNoWriteBarrier(
result, JSFunction::kDispatchHandleOffset,
311 StoreCodePointerField(
result, JSFunction::kCodeOffset, lazy_builtin);
317 auto context = Parameter<Context>(Descriptor::kContext);
318 auto target = Parameter<JSFunction>(Descriptor::kTarget);
319 auto new_target = Parameter<JSReceiver>(Descriptor::kNewTarget);
321 Label call_runtime(
this);
324 FastNewObject(context, target,
new_target, &call_runtime);
328 TailCallRuntime(Runtime::kNewObject, context, target,
new_target);
335 Label call_runtime(
this),
end(
this);
345 return var_obj.value();
359 LoadJSFunctionPrototypeOrInitialMap(new_target_func);
368 initial_map, Map::kConstructorOrBackPointerOrNativeContextOffset);
373 Label instantiate_map(
this), allocate_properties(
this);
376 properties = EmptyFixedArrayConstant();
377 Goto(&instantiate_map);
379 BIND(&allocate_properties);
383 Goto(&instantiate_map);
386 BIND(&instantiate_map);
404 switch (scope_type) {
406 index = Context::EVAL_CONTEXT_MAP_INDEX;
409 index = Context::FUNCTION_CONTEXT_MAP_INDEX;
432 vars, start_offset, size,
437 return function_context;
445 GotoIf(IsUndefined(maybe_feedback_vector), &call_runtime);
453 static_assert(JSRegExp::kDataOffset == JSObject::kHeaderSize);
454 static_assert(JSRegExp::kSourceOffset ==
456 static_assert(JSRegExp::kFlagsOffset ==
458 static_assert(JSRegExp::kHeaderSize ==
470 regexp_function, JSFunction::kPrototypeOrInitialMapOffset));
474 RootIndex::kEmptyFixedArray);
477 RootIndex::kEmptyFixedArray);
480 new_object, JSRegExp::kDataOffset, kRegExpDataIndirectPointerTag,
482 boilerplate, RegExpBoilerplateDescription::kDataOffset,
483 kRegExpDataIndirectPointerTag)));
485 new_object, JSRegExp::kSourceOffset,
487 RegExpBoilerplateDescription::kSourceOffset));
489 new_object, JSRegExp::kFlagsOffset,
491 RegExpBoilerplateDescription::kFlagsOffset));
503 maybe_feedback_vector, slot,
pattern, flags));
514 Label* call_runtime) {
539 Label create_empty_array(
this),
543 allocation_site =
CAST(maybe_allocation_site);
544 Goto(&create_empty_array);
547 BIND(&initialize_allocation_site);
553 Goto(&create_empty_array);
556 BIND(&create_empty_array);
559 Comment(
"LoadJSArrayElementsMap");
564 std::optional<TNode<AllocationSite>> site =
566 ? std::make_optional(allocation_site.value())
569 array_map, zero_intptr, zero, site);
579 Label* call_runtime) {
591 Label* call_runtime,
bool bailout_if_dictionary_properties) {
600 Label if_dictionary(
this), if_fast(
this), done(
this);
602 &if_dictionary, &if_fast);
603 BIND(&if_dictionary);
605 if (bailout_if_dictionary_properties) {
608 Comment(
"Copy dictionary properties");
626 GotoIfNot(IsEmptyFixedArray(boilerplate_properties), call_runtime);
627 var_properties = EmptyFixedArrayConstant();
636 Label if_empty_fixed_array(
this), if_copy_elements(
this), done(
this);
638 Branch(IsEmptyFixedArray(boilerplate_elements), &if_empty_fixed_array,
641 BIND(&if_empty_fixed_array);
642 var_elements = boilerplate_elements;
645 BIND(&if_copy_elements);
647 IsFixedCOWArrayMap(
LoadMap(boilerplate_elements))));
662 bool needs_allocation_memento =
v8_flags.allocation_site_pretenuring;
663 if (needs_allocation_memento) {
666 allocation_size =
IntPtrAdd(aligned_instance_size,
674 Comment(
"Initialize Literal Copy");
678 var_properties.value());
680 var_elements.value());
685 if (needs_allocation_memento) {
691 Label continue_with_write_barrier(
this), done_init(
this);
694 Comment(
"Copy in-object properties fast");
698 BIND(&continue_fast);
700 Label store_field(
this);
704 GotoIf(IsHeapNumber(
CAST(field)), &continue_with_write_barrier);
717 BIND(&continue_with_write_barrier);
719 Comment(
"Copy in-object properties slow");
721 offset.value(), instance_size,
724 TNode<Object> field = LoadObjectField(boilerplate, offset);
725 StoreObjectFieldNoWriteBarrier(copy, offset, field);
756 Comment(
"Copy mutable HeapNumber values");
758 start_offset, end_offset,
766 Branch(IsHeapNumber(
CAST(field)), ©_heap_number, &continue_loop);
767 BIND(©_heap_number);
773 Goto(&continue_loop);
775 BIND(&continue_loop);
#define CSA_DCHECK(csa,...)
#define TF_BUILTIN(Name, AssemblerBase)
#define BUILTIN_CODE(isolate, name)
constexpr UnderlyingType & value() &
static void Generate_CallOrConstructForwardVarargs(MacroAssembler *masm, CallOrConstructMode mode, Builtin target_builtin)
static void Generate_CallOrConstructVarargs(MacroAssembler *masm, Builtin target_builtin)
static void Generate_ConstructForwardAllArgsImpl(MacroAssembler *masm, ForwardWhichFrame which_frame)
void BuildConstructForwardAllArgs(TNode< JSAny > target, TNode< JSAny > new_target, const LazyNode< Context > &context, const LazyNode< Union< Undefined, FeedbackVector > > &feedback_vector, TNode< TaggedIndex > slot)
void BuildConstructWithSpread(TNode< JSAny > target, TNode< JSAny > new_target, TNode< JSAny > spread, TNode< Int32T > argc, const LazyNode< Context > &context, const LazyNode< Union< Undefined, FeedbackVector > > &feedback_vector, TNode< TaggedIndex > slot, UpdateFeedbackMode mode)
void BuildConstruct(TNode< JSAny > target, TNode< JSAny > new_target, TNode< Int32T > argc, const LazyNode< Context > &context, const LazyNode< Union< Undefined, FeedbackVector > > &feedback_vector, TNode< UintPtrT > slot, UpdateFeedbackMode mode)
void CallOrConstructWithSpread(TNode< JSAny > target, std::optional< TNode< Object > > new_target, TNode< JSAny > spread, TNode< Int32T > args_count, TNode< Context > context)
TNode< JSArray > AllocateJSArray(ElementsKind kind, TNode< Map > array_map, TNode< IntPtrT > capacity, TNode< Smi > length, std::optional< TNode< AllocationSite > > allocation_site, AllocationFlags allocation_flags=AllocationFlag::kNone)
TNode< WordT > TimesTaggedSize(TNode< WordT > value)
void InitializeAllocationMemento(TNode< HeapObject > base, TNode< IntPtrT > base_allocation_size, TNode< AllocationSite > allocation_site)
TNode< BoolT > IsJSObjectMap(TNode< Map > map)
TNode< SwissNameDictionary > CopySwissNameDictionary(TNode< SwissNameDictionary > original)
TNode< HeapObject > LoadSlowProperties(TNode< JSReceiver > object)
TNode< HeapObject > AllocateInNewSpace(TNode< IntPtrT > size, AllocationFlags flags=AllocationFlag::kNone)
TNode< TrustedObject > LoadTrustedPointerFromObject(TNode< HeapObject > object, int offset, IndirectPointerTag tag)
TNode< BoolT > DoesntHaveInstanceType(TNode< HeapObject > object, InstanceType type)
TNode< Smi > SmiTag(TNode< IntPtrT > value)
TNode< HeapObject > Allocate(TNode< IntPtrT > size, AllocationFlags flags=AllocationFlag::kNone)
void StoreObjectFieldRoot(TNode< HeapObject > object, int offset, RootIndex root)
TNode< FixedArrayBase > LoadElements(TNode< JSObject > object)
TNode< T > LoadObjectField(TNode< HeapObject > object, int offset)
TNode< BoolT > TaggedNotEqual(TNode< AnyTaggedT > a, TNode< AnyTaggedT > b)
TNode< Uint32T > LoadMapBitField3(TNode< Map > map)
TNode< JSObject > LoadBoilerplate(TNode< AllocationSite > allocation_site)
TNode< BoolT > IsSetWord32(TNode< Word32T > word32)
TNode< HeapObject > LoadFastProperties(TNode< JSReceiver > object, bool skip_empty_check=false)
TNode< Map > LoadJSArrayElementsMap(ElementsKind kind, TNode< NativeContext > native_context)
void BuildFastLoop(const VariableList &vars, TVariable< TIndex > &var_index, TNode< TIndex > start_index, TNode< TIndex > end_index, const FastLoopBody< TIndex > &body, TNode< TIndex > increment, LoopUnrollingMode unrolling_mode, IndexAdvanceMode advance_mode, IndexAdvanceDirection advance_direction)
TNode< Int32T > LoadElementsKind(TNode< HeapObject > object)
TNode< JSArray > CloneFastJSArray(TNode< Context > context, TNode< JSArray > array, std::optional< TNode< AllocationSite > > allocation_site=std::nullopt, HoleConversionMode convert_holes=HoleConversionMode::kDontConvert)
std::function< TNode< T >()> LazyNode
TNode< BoolT > IsClearWord32(TNode< Word32T > word32)
void StoreObjectFieldNoWriteBarrier(TNode< HeapObject > object, TNode< IntPtrT > offset, TNode< T > value)
TNode< IntPtrT > ElementOffsetFromIndex(TNode< TIndex > index, ElementsKind kind, int base_size=0)
TNode< HeapNumber > AllocateHeapNumberWithValue(TNode< Float64T > value)
TNode< JSFunction > HeapObjectToJSFunctionWithPrototypeSlot(TNode< HeapObject > heap_object, Label *fail)
void StoreTrustedPointerField(TNode< HeapObject > object, int offset, IndirectPointerTag tag, TNode< ExposedTrustedObject > value)
TNode< NativeContext > LoadNativeContext(TNode< Context > context)
TNode< BoolT > TaggedIsSmi(TNode< MaybeObject > a)
TNode< Float64T > LoadHeapNumberValue(TNode< HeapObject > object)
TNode< Map > LoadMap(TNode< HeapObject > object)
TNode< BoolT > IsDictionaryMap(TNode< Map > map)
TNode< IntPtrT > TaggedIndexToIntPtr(TNode< TaggedIndex > value)
TNode< JSObject > AllocateJSObjectFromMap(TNode< Map > map, std::optional< TNode< HeapObject > > properties=std::nullopt, std::optional< TNode< FixedArray > > elements=std::nullopt, AllocationFlags flags=AllocationFlag::kNone, SlackTrackingMode slack_tracking_mode=kNoSlackTracking)
TNode< IntPtrT > AlignToAllocationAlignment(TNode< IntPtrT > value)
TNode< PropertyDictionary > AllocatePropertyDictionary(int at_least_space_for)
TNode< NameDictionary > CopyNameDictionary(TNode< NameDictionary > dictionary, Label *large_object_fallback)
void StoreObjectField(TNode< HeapObject > object, int offset, TNode< Smi > value)
TNode< BoolT > HasBoilerplate(TNode< Object > maybe_literal_site)
TNode< IntPtrT > LoadMapInstanceSizeInWords(TNode< Map > map)
TNode< MaybeObject > LoadFeedbackVectorSlot(TNode< FeedbackVector > feedback_vector, TNode< TIndex > slot, int additional_offset=0)
TNode< Map > LoadObjectFunctionInitialMap(TNode< NativeContext > native_context)
TNode< AllocationSite > CreateAllocationSiteInFeedbackVector(TNode< FeedbackVector > feedback_vector, TNode< UintPtrT > slot)
TNode< FixedArrayBase > CloneFixedArray(TNode< FixedArrayBase > source, ExtractFixedArrayFlags flags=ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW)
TNode< TaggedIndex > IntPtrToTaggedIndex(TNode< IntPtrT > value)
void StoreMapNoWriteBarrier(TNode< HeapObject > object, RootIndex map_root_index)
TNode< JSObject > CreateEmptyObjectLiteral(TNode< Context > context)
TNode< JSObject > FastNewObject(TNode< Context > context, TNode< JSFunction > target, TNode< JSReceiver > new_target)
TNode< HeapObject > CreateShallowObjectLiteral(TNode< FeedbackVector > feedback_vector, TNode< TaggedIndex > slot, Label *call_runtime)
TNode< Context > FastNewFunctionContext(TNode< ScopeInfo > scope_info, TNode< Uint32T > slots, TNode< Context > context, ScopeType scope_type)
void CopyMutableHeapNumbersInObject(TNode< HeapObject > copy, TNode< IntPtrT > start_offset, TNode< IntPtrT > instance_size)
TNode< JSArray > CreateShallowArrayLiteral(TNode< FeedbackVector > feedback_vector, TNode< TaggedIndex > slot, TNode< Context > context, AllocationSiteMode allocation_site_mode, Label *call_runtime)
TNode< JSRegExp > CreateRegExpLiteral(TNode< HeapObject > maybe_feedback_vector, TNode< TaggedIndex > slot, TNode< Object > pattern, TNode< Smi > flags, TNode< Context > context)
TNode< JSArray > CreateEmptyArrayLiteral(TNode< FeedbackVector > feedback_vector, TNode< TaggedIndex > slot, TNode< Context > context)
static const int FIRST_FUNCTION_MAP_INDEX
static const int kScopeInfoOffset
static const int kTodoHeaderSize
static const int LAST_FUNCTION_MAP_INDEX
static const int kPreviousOffset
static constexpr int kSizeWithoutPrototype
static const int kMaxInstanceSize
static constexpr int Size()
static constexpr int kLastIndexOffset
static constexpr int kInitialLastIndexValue
static const int kNoSlackTracking
static const int kInitialCapacity
TNode< IntPtrT > IntPtrAdd(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< Int32T > Signed(TNode< Word32T > x)
void Comment(MessageWithSourceLocation message, Args &&... args)
TNode< IntPtrT > IntPtrConstant(intptr_t value)
TNode< UintPtrT > ChangeUint32ToWord(TNode< Word32T > value)
TNode< T > UncheckedCast(Node *value)
void GotoIfNot(TNode< IntegralT > condition, Label *false_label, GotoHint goto_hint=GotoHint::kNone)
TNode< Uint32T > Unsigned(TNode< Word32T > x)
TNode< Smi > SmiConstant(Tagged< Smi > value)
void GotoIf(TNode< IntegralT > condition, Label *true_label, GotoHint goto_hint=GotoHint::kNone)
TNode< BoolT > IntPtrEqual(TNode< WordT > left, TNode< WordT > right)
void TailCallBuiltin(Builtin id, TNode< Object > context, TArgs... args)
TNode< BoolT > WordNotEqual(TNode< WordT > left, TNode< WordT > right)
TNode< T > CallRuntime(Runtime::FunctionId function, TNode< Object > context, TArgs... args)
void Branch(TNode< IntegralT > condition, Label *true_label, Label *false_label, BranchHint branch_hint=BranchHint::kNone)
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
#define ALIGN_TO_ALLOCATION_ALIGNMENT(value)
DirectHandle< Object > new_target
#define V8_ALLOCATION_SITE_TRACKING_BOOL
ZoneVector< RpoNumber > & result
constexpr int kTaggedSize
constexpr int kMaxRegularHeapObjectSize
constexpr JSDispatchHandle kNullJSDispatchHandle(0)
V8_EXPORT_PRIVATE FlagValues v8_flags
ElementsKind GetInitialFastElementsKind()
!IsContextMap !IsContextMap native_context
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)