11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/builtins/builtins-constructor-gen.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/ast/ast.h"
81cb0ef41Sopenharmony_ci#include "src/builtins/builtins-call-gen.h"
91cb0ef41Sopenharmony_ci#include "src/builtins/builtins-constructor.h"
101cb0ef41Sopenharmony_ci#include "src/builtins/builtins-utils-gen.h"
111cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h"
131cb0ef41Sopenharmony_ci#include "src/codegen/code-stub-assembler.h"
141cb0ef41Sopenharmony_ci#include "src/codegen/interface-descriptors.h"
151cb0ef41Sopenharmony_ci#include "src/codegen/macro-assembler.h"
161cb0ef41Sopenharmony_ci#include "src/common/globals.h"
171cb0ef41Sopenharmony_ci#include "src/logging/counters.h"
181cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_cinamespace v8 {
211cb0ef41Sopenharmony_cinamespace internal {
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_civoid Builtins::Generate_ConstructVarargs(MacroAssembler* masm) {
241cb0ef41Sopenharmony_ci  Generate_CallOrConstructVarargs(masm,
251cb0ef41Sopenharmony_ci                                  BUILTIN_CODE(masm->isolate(), Construct));
261cb0ef41Sopenharmony_ci}
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_civoid Builtins::Generate_ConstructForwardVarargs(MacroAssembler* masm) {
291cb0ef41Sopenharmony_ci  Generate_CallOrConstructForwardVarargs(
301cb0ef41Sopenharmony_ci      masm, CallOrConstructMode::kConstruct,
311cb0ef41Sopenharmony_ci      BUILTIN_CODE(masm->isolate(), Construct));
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_civoid Builtins::Generate_ConstructFunctionForwardVarargs(MacroAssembler* masm) {
351cb0ef41Sopenharmony_ci  Generate_CallOrConstructForwardVarargs(
361cb0ef41Sopenharmony_ci      masm, CallOrConstructMode::kConstruct,
371cb0ef41Sopenharmony_ci      BUILTIN_CODE(masm->isolate(), ConstructFunction));
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ciTF_BUILTIN(Construct_Baseline, CallOrConstructBuiltinsAssembler) {
411cb0ef41Sopenharmony_ci  auto target = Parameter<Object>(Descriptor::kTarget);
421cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
431cb0ef41Sopenharmony_ci  auto argc = UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
441cb0ef41Sopenharmony_ci  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  BuildConstruct(
471cb0ef41Sopenharmony_ci      target, new_target, argc, [=] { return LoadContextFromBaseline(); },
481cb0ef41Sopenharmony_ci      [=] { return LoadFeedbackVectorFromBaseline(); }, slot,
491cb0ef41Sopenharmony_ci      UpdateFeedbackMode::kGuaranteedFeedback);
501cb0ef41Sopenharmony_ci}
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ciTF_BUILTIN(Construct_WithFeedback, CallOrConstructBuiltinsAssembler) {
531cb0ef41Sopenharmony_ci  auto target = Parameter<Object>(Descriptor::kTarget);
541cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
551cb0ef41Sopenharmony_ci  auto argc = UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
561cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
571cb0ef41Sopenharmony_ci  auto feedback_vector = Parameter<FeedbackVector>(Descriptor::kFeedbackVector);
581cb0ef41Sopenharmony_ci  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  BuildConstruct(
611cb0ef41Sopenharmony_ci      target, new_target, argc, [=] { return context; },
621cb0ef41Sopenharmony_ci      [=] { return feedback_vector; }, slot,
631cb0ef41Sopenharmony_ci      UpdateFeedbackMode::kOptionalFeedback);
641cb0ef41Sopenharmony_ci}
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_civoid CallOrConstructBuiltinsAssembler::BuildConstruct(
671cb0ef41Sopenharmony_ci    TNode<Object> target, TNode<Object> new_target, TNode<Int32T> argc,
681cb0ef41Sopenharmony_ci    const LazyNode<Context>& context,
691cb0ef41Sopenharmony_ci    const LazyNode<HeapObject>& feedback_vector, TNode<UintPtrT> slot,
701cb0ef41Sopenharmony_ci    UpdateFeedbackMode mode) {
711cb0ef41Sopenharmony_ci  TVARIABLE(AllocationSite, allocation_site);
721cb0ef41Sopenharmony_ci  Label if_construct_generic(this), if_construct_array(this);
731cb0ef41Sopenharmony_ci  TNode<Context> eager_context = context();
741cb0ef41Sopenharmony_ci  CollectConstructFeedback(eager_context, target, new_target, feedback_vector(),
751cb0ef41Sopenharmony_ci                           slot, mode, &if_construct_generic,
761cb0ef41Sopenharmony_ci                           &if_construct_array, &allocation_site);
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  BIND(&if_construct_generic);
791cb0ef41Sopenharmony_ci  TailCallBuiltin(Builtin::kConstruct, eager_context, target, new_target, argc);
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  BIND(&if_construct_array);
821cb0ef41Sopenharmony_ci  TailCallBuiltin(Builtin::kArrayConstructorImpl, eager_context, target,
831cb0ef41Sopenharmony_ci                  new_target, argc, allocation_site.value());
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ciTF_BUILTIN(ConstructWithArrayLike, CallOrConstructBuiltinsAssembler) {
871cb0ef41Sopenharmony_ci  auto target = Parameter<Object>(Descriptor::kTarget);
881cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
891cb0ef41Sopenharmony_ci  auto arguments_list = Parameter<Object>(Descriptor::kArgumentsList);
901cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
911cb0ef41Sopenharmony_ci  CallOrConstructWithArrayLike(target, new_target, arguments_list, context);
921cb0ef41Sopenharmony_ci}
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ciTF_BUILTIN(ConstructWithArrayLike_WithFeedback,
951cb0ef41Sopenharmony_ci           CallOrConstructBuiltinsAssembler) {
961cb0ef41Sopenharmony_ci  auto target = Parameter<Object>(Descriptor::kTarget);
971cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
981cb0ef41Sopenharmony_ci  auto arguments_list = Parameter<Object>(Descriptor::kArgumentsList);
991cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
1001cb0ef41Sopenharmony_ci  auto feedback_vector = Parameter<FeedbackVector>(Descriptor::kFeedbackVector);
1011cb0ef41Sopenharmony_ci  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  TVARIABLE(AllocationSite, allocation_site);
1041cb0ef41Sopenharmony_ci  Label if_construct_generic(this), if_construct_array(this);
1051cb0ef41Sopenharmony_ci  CollectConstructFeedback(context, target, new_target, feedback_vector, slot,
1061cb0ef41Sopenharmony_ci                           UpdateFeedbackMode::kOptionalFeedback,
1071cb0ef41Sopenharmony_ci                           &if_construct_generic, &if_construct_array,
1081cb0ef41Sopenharmony_ci                           &allocation_site);
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  BIND(&if_construct_array);
1111cb0ef41Sopenharmony_ci  Goto(&if_construct_generic);  // Not implemented.
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  BIND(&if_construct_generic);
1141cb0ef41Sopenharmony_ci  CallOrConstructWithArrayLike(target, new_target, arguments_list, context);
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ciTF_BUILTIN(ConstructWithSpread, CallOrConstructBuiltinsAssembler) {
1181cb0ef41Sopenharmony_ci  auto target = Parameter<Object>(Descriptor::kTarget);
1191cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
1201cb0ef41Sopenharmony_ci  auto spread = Parameter<Object>(Descriptor::kSpread);
1211cb0ef41Sopenharmony_ci  auto args_count =
1221cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
1231cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
1241cb0ef41Sopenharmony_ci  CallOrConstructWithSpread(target, new_target, spread, args_count, context);
1251cb0ef41Sopenharmony_ci}
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ciTF_BUILTIN(ConstructWithSpread_Baseline, CallOrConstructBuiltinsAssembler) {
1281cb0ef41Sopenharmony_ci  auto target = Parameter<Object>(Descriptor::kTarget);
1291cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
1301cb0ef41Sopenharmony_ci  auto spread = Parameter<Object>(Descriptor::kSpread);
1311cb0ef41Sopenharmony_ci  auto args_count =
1321cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
1331cb0ef41Sopenharmony_ci  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
1341cb0ef41Sopenharmony_ci  return BuildConstructWithSpread(
1351cb0ef41Sopenharmony_ci      target, new_target, spread, args_count,
1361cb0ef41Sopenharmony_ci      [=] { return LoadContextFromBaseline(); },
1371cb0ef41Sopenharmony_ci      [=] { return LoadFeedbackVectorFromBaseline(); }, slot,
1381cb0ef41Sopenharmony_ci      UpdateFeedbackMode::kGuaranteedFeedback);
1391cb0ef41Sopenharmony_ci}
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ciTF_BUILTIN(ConstructWithSpread_WithFeedback, CallOrConstructBuiltinsAssembler) {
1421cb0ef41Sopenharmony_ci  auto target = Parameter<Object>(Descriptor::kTarget);
1431cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
1441cb0ef41Sopenharmony_ci  auto spread = Parameter<Object>(Descriptor::kSpread);
1451cb0ef41Sopenharmony_ci  auto args_count =
1461cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
1471cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
1481cb0ef41Sopenharmony_ci  auto feedback_vector = Parameter<HeapObject>(Descriptor::kFeedbackVector);
1491cb0ef41Sopenharmony_ci  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  return BuildConstructWithSpread(
1521cb0ef41Sopenharmony_ci      target, new_target, spread, args_count, [=] { return context; },
1531cb0ef41Sopenharmony_ci      [=] { return feedback_vector; }, slot,
1541cb0ef41Sopenharmony_ci      UpdateFeedbackMode::kGuaranteedFeedback);
1551cb0ef41Sopenharmony_ci}
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_civoid CallOrConstructBuiltinsAssembler::BuildConstructWithSpread(
1581cb0ef41Sopenharmony_ci    TNode<Object> target, TNode<Object> new_target, TNode<Object> spread,
1591cb0ef41Sopenharmony_ci    TNode<Int32T> argc, const LazyNode<Context>& context,
1601cb0ef41Sopenharmony_ci    const LazyNode<HeapObject>& feedback_vector, TNode<UintPtrT> slot,
1611cb0ef41Sopenharmony_ci    UpdateFeedbackMode mode) {
1621cb0ef41Sopenharmony_ci  TVARIABLE(AllocationSite, allocation_site);
1631cb0ef41Sopenharmony_ci  Label if_construct_generic(this), if_construct_array(this);
1641cb0ef41Sopenharmony_ci  TNode<Context> eager_context = context();
1651cb0ef41Sopenharmony_ci  CollectConstructFeedback(eager_context, target, new_target, feedback_vector(),
1661cb0ef41Sopenharmony_ci                           slot, UpdateFeedbackMode::kGuaranteedFeedback,
1671cb0ef41Sopenharmony_ci                           &if_construct_generic, &if_construct_array,
1681cb0ef41Sopenharmony_ci                           &allocation_site);
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  BIND(&if_construct_array);
1711cb0ef41Sopenharmony_ci  Goto(&if_construct_generic);  // Not implemented.
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci  BIND(&if_construct_generic);
1741cb0ef41Sopenharmony_ci  CallOrConstructWithSpread(target, new_target, spread, argc, eager_context);
1751cb0ef41Sopenharmony_ci}
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ciTF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) {
1781cb0ef41Sopenharmony_ci  auto shared_function_info =
1791cb0ef41Sopenharmony_ci      Parameter<SharedFunctionInfo>(Descriptor::kSharedFunctionInfo);
1801cb0ef41Sopenharmony_ci  auto feedback_cell = Parameter<FeedbackCell>(Descriptor::kFeedbackCell);
1811cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  IncrementCounter(isolate()->counters()->fast_new_closure_total(), 1);
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  // Bump the closure counter encoded the {feedback_cell}s map.
1861cb0ef41Sopenharmony_ci  {
1871cb0ef41Sopenharmony_ci    const TNode<Map> feedback_cell_map = LoadMap(feedback_cell);
1881cb0ef41Sopenharmony_ci    Label no_closures(this), one_closure(this), cell_done(this);
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci    GotoIf(IsNoClosuresCellMap(feedback_cell_map), &no_closures);
1911cb0ef41Sopenharmony_ci    GotoIf(IsOneClosureCellMap(feedback_cell_map), &one_closure);
1921cb0ef41Sopenharmony_ci    CSA_DCHECK(this, IsManyClosuresCellMap(feedback_cell_map),
1931cb0ef41Sopenharmony_ci               feedback_cell_map, feedback_cell);
1941cb0ef41Sopenharmony_ci    Goto(&cell_done);
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci    BIND(&no_closures);
1971cb0ef41Sopenharmony_ci    StoreMapNoWriteBarrier(feedback_cell, RootIndex::kOneClosureCellMap);
1981cb0ef41Sopenharmony_ci    Goto(&cell_done);
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci    BIND(&one_closure);
2011cb0ef41Sopenharmony_ci    StoreMapNoWriteBarrier(feedback_cell, RootIndex::kManyClosuresCellMap);
2021cb0ef41Sopenharmony_ci    Goto(&cell_done);
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci    BIND(&cell_done);
2051cb0ef41Sopenharmony_ci  }
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci  // The calculation of |function_map_index| must be in sync with
2081cb0ef41Sopenharmony_ci  // SharedFunctionInfo::function_map_index().
2091cb0ef41Sopenharmony_ci  TNode<Uint32T> flags = LoadObjectField<Uint32T>(
2101cb0ef41Sopenharmony_ci      shared_function_info, SharedFunctionInfo::kFlagsOffset);
2111cb0ef41Sopenharmony_ci  const TNode<IntPtrT> function_map_index = Signed(IntPtrAdd(
2121cb0ef41Sopenharmony_ci      DecodeWordFromWord32<SharedFunctionInfo::FunctionMapIndexBits>(flags),
2131cb0ef41Sopenharmony_ci      IntPtrConstant(Context::FIRST_FUNCTION_MAP_INDEX)));
2141cb0ef41Sopenharmony_ci  CSA_DCHECK(this, UintPtrLessThanOrEqual(
2151cb0ef41Sopenharmony_ci                       function_map_index,
2161cb0ef41Sopenharmony_ci                       IntPtrConstant(Context::LAST_FUNCTION_MAP_INDEX)));
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci  // Get the function map in the current native context and set that
2191cb0ef41Sopenharmony_ci  // as the map of the allocated object.
2201cb0ef41Sopenharmony_ci  const TNode<NativeContext> native_context = LoadNativeContext(context);
2211cb0ef41Sopenharmony_ci  const TNode<Map> function_map =
2221cb0ef41Sopenharmony_ci      CAST(LoadContextElement(native_context, function_map_index));
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ci  // Create a new closure from the given function info in new space
2251cb0ef41Sopenharmony_ci  TNode<IntPtrT> instance_size_in_bytes =
2261cb0ef41Sopenharmony_ci      TimesTaggedSize(LoadMapInstanceSizeInWords(function_map));
2271cb0ef41Sopenharmony_ci  TNode<HeapObject> result = Allocate(instance_size_in_bytes);
2281cb0ef41Sopenharmony_ci  StoreMapNoWriteBarrier(result, function_map);
2291cb0ef41Sopenharmony_ci  InitializeJSObjectBodyNoSlackTracking(result, function_map,
2301cb0ef41Sopenharmony_ci                                        instance_size_in_bytes,
2311cb0ef41Sopenharmony_ci                                        JSFunction::kSizeWithoutPrototype);
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ci  // Initialize the rest of the function.
2341cb0ef41Sopenharmony_ci  StoreObjectFieldRoot(result, JSObject::kPropertiesOrHashOffset,
2351cb0ef41Sopenharmony_ci                       RootIndex::kEmptyFixedArray);
2361cb0ef41Sopenharmony_ci  StoreObjectFieldRoot(result, JSObject::kElementsOffset,
2371cb0ef41Sopenharmony_ci                       RootIndex::kEmptyFixedArray);
2381cb0ef41Sopenharmony_ci  {
2391cb0ef41Sopenharmony_ci    // Set function prototype if necessary.
2401cb0ef41Sopenharmony_ci    Label done(this), init_prototype(this);
2411cb0ef41Sopenharmony_ci    Branch(IsFunctionWithPrototypeSlotMap(function_map), &init_prototype,
2421cb0ef41Sopenharmony_ci           &done);
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci    BIND(&init_prototype);
2451cb0ef41Sopenharmony_ci    StoreObjectFieldRoot(result, JSFunction::kPrototypeOrInitialMapOffset,
2461cb0ef41Sopenharmony_ci                         RootIndex::kTheHoleValue);
2471cb0ef41Sopenharmony_ci    Goto(&done);
2481cb0ef41Sopenharmony_ci    BIND(&done);
2491cb0ef41Sopenharmony_ci  }
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kTaggedSize);
2521cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSFunction::kFeedbackCellOffset,
2531cb0ef41Sopenharmony_ci                                 feedback_cell);
2541cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSFunction::kSharedFunctionInfoOffset,
2551cb0ef41Sopenharmony_ci                                 shared_function_info);
2561cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSFunction::kContextOffset, context);
2571cb0ef41Sopenharmony_ci  TNode<CodeT> lazy_builtin =
2581cb0ef41Sopenharmony_ci      HeapConstant(BUILTIN_CODE(isolate(), CompileLazy));
2591cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(result, JSFunction::kCodeOffset, lazy_builtin);
2601cb0ef41Sopenharmony_ci  Return(result);
2611cb0ef41Sopenharmony_ci}
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ciTF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
2641cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
2651cb0ef41Sopenharmony_ci  auto target = Parameter<JSFunction>(Descriptor::kTarget);
2661cb0ef41Sopenharmony_ci  auto new_target = Parameter<JSReceiver>(Descriptor::kNewTarget);
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci  Label call_runtime(this);
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  TNode<JSObject> result =
2711cb0ef41Sopenharmony_ci      FastNewObject(context, target, new_target, &call_runtime);
2721cb0ef41Sopenharmony_ci  Return(result);
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci  BIND(&call_runtime);
2751cb0ef41Sopenharmony_ci  TailCallRuntime(Runtime::kNewObject, context, target, new_target);
2761cb0ef41Sopenharmony_ci}
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ciTNode<JSObject> ConstructorBuiltinsAssembler::FastNewObject(
2791cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<JSFunction> target,
2801cb0ef41Sopenharmony_ci    TNode<JSReceiver> new_target) {
2811cb0ef41Sopenharmony_ci  TVARIABLE(JSObject, var_obj);
2821cb0ef41Sopenharmony_ci  Label call_runtime(this), end(this);
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci  var_obj = FastNewObject(context, target, new_target, &call_runtime);
2851cb0ef41Sopenharmony_ci  Goto(&end);
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ci  BIND(&call_runtime);
2881cb0ef41Sopenharmony_ci  var_obj = CAST(CallRuntime(Runtime::kNewObject, context, target, new_target));
2891cb0ef41Sopenharmony_ci  Goto(&end);
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci  BIND(&end);
2921cb0ef41Sopenharmony_ci  return var_obj.value();
2931cb0ef41Sopenharmony_ci}
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ciTNode<JSObject> ConstructorBuiltinsAssembler::FastNewObject(
2961cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<JSFunction> target,
2971cb0ef41Sopenharmony_ci    TNode<JSReceiver> new_target, Label* call_runtime) {
2981cb0ef41Sopenharmony_ci  // Verify that the new target is a JSFunction.
2991cb0ef41Sopenharmony_ci  Label end(this);
3001cb0ef41Sopenharmony_ci  TNode<JSFunction> new_target_func =
3011cb0ef41Sopenharmony_ci      HeapObjectToJSFunctionWithPrototypeSlot(new_target, call_runtime);
3021cb0ef41Sopenharmony_ci  // Fast path.
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  // Load the initial map and verify that it's in fact a map.
3051cb0ef41Sopenharmony_ci  TNode<Object> initial_map_or_proto =
3061cb0ef41Sopenharmony_ci      LoadJSFunctionPrototypeOrInitialMap(new_target_func);
3071cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(initial_map_or_proto), call_runtime);
3081cb0ef41Sopenharmony_ci  GotoIf(DoesntHaveInstanceType(CAST(initial_map_or_proto), MAP_TYPE),
3091cb0ef41Sopenharmony_ci         call_runtime);
3101cb0ef41Sopenharmony_ci  TNode<Map> initial_map = CAST(initial_map_or_proto);
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci  // Fall back to runtime if the target differs from the new target's
3131cb0ef41Sopenharmony_ci  // initial map constructor.
3141cb0ef41Sopenharmony_ci  TNode<Object> new_target_constructor = LoadObjectField(
3151cb0ef41Sopenharmony_ci      initial_map, Map::kConstructorOrBackPointerOrNativeContextOffset);
3161cb0ef41Sopenharmony_ci  GotoIf(TaggedNotEqual(target, new_target_constructor), call_runtime);
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci  TVARIABLE(HeapObject, properties);
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci  Label instantiate_map(this), allocate_properties(this);
3211cb0ef41Sopenharmony_ci  GotoIf(IsDictionaryMap(initial_map), &allocate_properties);
3221cb0ef41Sopenharmony_ci  {
3231cb0ef41Sopenharmony_ci    properties = EmptyFixedArrayConstant();
3241cb0ef41Sopenharmony_ci    Goto(&instantiate_map);
3251cb0ef41Sopenharmony_ci  }
3261cb0ef41Sopenharmony_ci  BIND(&allocate_properties);
3271cb0ef41Sopenharmony_ci  {
3281cb0ef41Sopenharmony_ci    if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
3291cb0ef41Sopenharmony_ci      properties =
3301cb0ef41Sopenharmony_ci          AllocateSwissNameDictionary(SwissNameDictionary::kInitialCapacity);
3311cb0ef41Sopenharmony_ci    } else {
3321cb0ef41Sopenharmony_ci      properties = AllocateNameDictionary(NameDictionary::kInitialCapacity);
3331cb0ef41Sopenharmony_ci    }
3341cb0ef41Sopenharmony_ci    Goto(&instantiate_map);
3351cb0ef41Sopenharmony_ci  }
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  BIND(&instantiate_map);
3381cb0ef41Sopenharmony_ci  return AllocateJSObjectFromMap(initial_map, properties.value(), base::nullopt,
3391cb0ef41Sopenharmony_ci                                 AllocationFlag::kNone, kWithSlackTracking);
3401cb0ef41Sopenharmony_ci}
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ciTNode<Context> ConstructorBuiltinsAssembler::FastNewFunctionContext(
3431cb0ef41Sopenharmony_ci    TNode<ScopeInfo> scope_info, TNode<Uint32T> slots, TNode<Context> context,
3441cb0ef41Sopenharmony_ci    ScopeType scope_type) {
3451cb0ef41Sopenharmony_ci  TNode<IntPtrT> slots_intptr = Signed(ChangeUint32ToWord(slots));
3461cb0ef41Sopenharmony_ci  TNode<IntPtrT> size = ElementOffsetFromIndex(slots_intptr, PACKED_ELEMENTS,
3471cb0ef41Sopenharmony_ci                                               Context::kTodoHeaderSize);
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci  // Create a new closure from the given function info in new space
3501cb0ef41Sopenharmony_ci  TNode<Context> function_context =
3511cb0ef41Sopenharmony_ci      UncheckedCast<Context>(AllocateInNewSpace(size));
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci  TNode<NativeContext> native_context = LoadNativeContext(context);
3541cb0ef41Sopenharmony_ci  Context::Field index;
3551cb0ef41Sopenharmony_ci  switch (scope_type) {
3561cb0ef41Sopenharmony_ci    case EVAL_SCOPE:
3571cb0ef41Sopenharmony_ci      index = Context::EVAL_CONTEXT_MAP_INDEX;
3581cb0ef41Sopenharmony_ci      break;
3591cb0ef41Sopenharmony_ci    case FUNCTION_SCOPE:
3601cb0ef41Sopenharmony_ci      index = Context::FUNCTION_CONTEXT_MAP_INDEX;
3611cb0ef41Sopenharmony_ci      break;
3621cb0ef41Sopenharmony_ci    default:
3631cb0ef41Sopenharmony_ci      UNREACHABLE();
3641cb0ef41Sopenharmony_ci  }
3651cb0ef41Sopenharmony_ci  TNode<Map> map = CAST(LoadContextElement(native_context, index));
3661cb0ef41Sopenharmony_ci  // Set up the header.
3671cb0ef41Sopenharmony_ci  StoreMapNoWriteBarrier(function_context, map);
3681cb0ef41Sopenharmony_ci  TNode<IntPtrT> min_context_slots = IntPtrConstant(Context::MIN_CONTEXT_SLOTS);
3691cb0ef41Sopenharmony_ci  // TODO(ishell): for now, length also includes MIN_CONTEXT_SLOTS.
3701cb0ef41Sopenharmony_ci  TNode<IntPtrT> length = IntPtrAdd(slots_intptr, min_context_slots);
3711cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(function_context, Context::kLengthOffset,
3721cb0ef41Sopenharmony_ci                                 SmiTag(length));
3731cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(function_context, Context::kScopeInfoOffset,
3741cb0ef41Sopenharmony_ci                                 scope_info);
3751cb0ef41Sopenharmony_ci  StoreObjectFieldNoWriteBarrier(function_context, Context::kPreviousOffset,
3761cb0ef41Sopenharmony_ci                                 context);
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci  // Initialize the varrest of the slots to undefined.
3791cb0ef41Sopenharmony_ci  TNode<Oddball> undefined = UndefinedConstant();
3801cb0ef41Sopenharmony_ci  TNode<IntPtrT> start_offset = IntPtrConstant(Context::kTodoHeaderSize);
3811cb0ef41Sopenharmony_ci  CodeStubAssembler::VariableList vars(0, zone());
3821cb0ef41Sopenharmony_ci  BuildFastLoop<IntPtrT>(
3831cb0ef41Sopenharmony_ci      vars, start_offset, size,
3841cb0ef41Sopenharmony_ci      [=](TNode<IntPtrT> offset) {
3851cb0ef41Sopenharmony_ci        StoreObjectFieldNoWriteBarrier(function_context, offset, undefined);
3861cb0ef41Sopenharmony_ci      },
3871cb0ef41Sopenharmony_ci      kTaggedSize, IndexAdvanceMode::kPost);
3881cb0ef41Sopenharmony_ci  return function_context;
3891cb0ef41Sopenharmony_ci}
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ciTNode<JSRegExp> ConstructorBuiltinsAssembler::CreateRegExpLiteral(
3921cb0ef41Sopenharmony_ci    TNode<HeapObject> maybe_feedback_vector, TNode<TaggedIndex> slot,
3931cb0ef41Sopenharmony_ci    TNode<Object> pattern, TNode<Smi> flags, TNode<Context> context) {
3941cb0ef41Sopenharmony_ci  Label call_runtime(this, Label::kDeferred), end(this);
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ci  GotoIf(IsUndefined(maybe_feedback_vector), &call_runtime);
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci  TVARIABLE(JSRegExp, result);
3991cb0ef41Sopenharmony_ci  TNode<FeedbackVector> feedback_vector = CAST(maybe_feedback_vector);
4001cb0ef41Sopenharmony_ci  TNode<Object> literal_site =
4011cb0ef41Sopenharmony_ci      CAST(LoadFeedbackVectorSlot(feedback_vector, slot));
4021cb0ef41Sopenharmony_ci  GotoIfNot(HasBoilerplate(literal_site), &call_runtime);
4031cb0ef41Sopenharmony_ci  {
4041cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSRegExp::kDataOffset == JSObject::kHeaderSize);
4051cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSRegExp::kSourceOffset ==
4061cb0ef41Sopenharmony_ci                  JSRegExp::kDataOffset + kTaggedSize);
4071cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSRegExp::kFlagsOffset ==
4081cb0ef41Sopenharmony_ci                  JSRegExp::kSourceOffset + kTaggedSize);
4091cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSRegExp::kHeaderSize ==
4101cb0ef41Sopenharmony_ci                  JSRegExp::kFlagsOffset + kTaggedSize);
4111cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSRegExp::kLastIndexOffset == JSRegExp::kHeaderSize);
4121cb0ef41Sopenharmony_ci    DCHECK_EQ(JSRegExp::Size(), JSRegExp::kLastIndexOffset + kTaggedSize);
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_ci    TNode<RegExpBoilerplateDescription> boilerplate = CAST(literal_site);
4151cb0ef41Sopenharmony_ci    TNode<HeapObject> new_object = Allocate(JSRegExp::Size());
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ci    // Initialize Object fields.
4181cb0ef41Sopenharmony_ci    TNode<JSFunction> regexp_function = CAST(LoadContextElement(
4191cb0ef41Sopenharmony_ci        LoadNativeContext(context), Context::REGEXP_FUNCTION_INDEX));
4201cb0ef41Sopenharmony_ci    TNode<Map> initial_map = CAST(LoadObjectField(
4211cb0ef41Sopenharmony_ci        regexp_function, JSFunction::kPrototypeOrInitialMapOffset));
4221cb0ef41Sopenharmony_ci    StoreMapNoWriteBarrier(new_object, initial_map);
4231cb0ef41Sopenharmony_ci    // Initialize JSReceiver fields.
4241cb0ef41Sopenharmony_ci    StoreObjectFieldRoot(new_object, JSReceiver::kPropertiesOrHashOffset,
4251cb0ef41Sopenharmony_ci                         RootIndex::kEmptyFixedArray);
4261cb0ef41Sopenharmony_ci    // Initialize JSObject fields.
4271cb0ef41Sopenharmony_ci    StoreObjectFieldRoot(new_object, JSObject::kElementsOffset,
4281cb0ef41Sopenharmony_ci                         RootIndex::kEmptyFixedArray);
4291cb0ef41Sopenharmony_ci    // Initialize JSRegExp fields.
4301cb0ef41Sopenharmony_ci    StoreObjectFieldNoWriteBarrier(
4311cb0ef41Sopenharmony_ci        new_object, JSRegExp::kDataOffset,
4321cb0ef41Sopenharmony_ci        LoadObjectField(boilerplate,
4331cb0ef41Sopenharmony_ci                        RegExpBoilerplateDescription::kDataOffset));
4341cb0ef41Sopenharmony_ci    StoreObjectFieldNoWriteBarrier(
4351cb0ef41Sopenharmony_ci        new_object, JSRegExp::kSourceOffset,
4361cb0ef41Sopenharmony_ci        LoadObjectField(boilerplate,
4371cb0ef41Sopenharmony_ci                        RegExpBoilerplateDescription::kSourceOffset));
4381cb0ef41Sopenharmony_ci    StoreObjectFieldNoWriteBarrier(
4391cb0ef41Sopenharmony_ci        new_object, JSRegExp::kFlagsOffset,
4401cb0ef41Sopenharmony_ci        LoadObjectField(boilerplate,
4411cb0ef41Sopenharmony_ci                        RegExpBoilerplateDescription::kFlagsOffset));
4421cb0ef41Sopenharmony_ci    StoreObjectFieldNoWriteBarrier(
4431cb0ef41Sopenharmony_ci        new_object, JSRegExp::kLastIndexOffset,
4441cb0ef41Sopenharmony_ci        SmiConstant(JSRegExp::kInitialLastIndexValue));
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci    result = CAST(new_object);
4471cb0ef41Sopenharmony_ci    Goto(&end);
4481cb0ef41Sopenharmony_ci  }
4491cb0ef41Sopenharmony_ci
4501cb0ef41Sopenharmony_ci  BIND(&call_runtime);
4511cb0ef41Sopenharmony_ci  {
4521cb0ef41Sopenharmony_ci    result = CAST(CallRuntime(Runtime::kCreateRegExpLiteral, context,
4531cb0ef41Sopenharmony_ci                              maybe_feedback_vector, slot, pattern, flags));
4541cb0ef41Sopenharmony_ci    Goto(&end);
4551cb0ef41Sopenharmony_ci  }
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci  BIND(&end);
4581cb0ef41Sopenharmony_ci  return result.value();
4591cb0ef41Sopenharmony_ci}
4601cb0ef41Sopenharmony_ci
4611cb0ef41Sopenharmony_ciTNode<JSArray> ConstructorBuiltinsAssembler::CreateShallowArrayLiteral(
4621cb0ef41Sopenharmony_ci    TNode<FeedbackVector> feedback_vector, TNode<TaggedIndex> slot,
4631cb0ef41Sopenharmony_ci    TNode<Context> context, AllocationSiteMode allocation_site_mode,
4641cb0ef41Sopenharmony_ci    Label* call_runtime) {
4651cb0ef41Sopenharmony_ci  Label zero_capacity(this), cow_elements(this), fast_elements(this),
4661cb0ef41Sopenharmony_ci      return_result(this);
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_ci  TNode<Object> maybe_allocation_site =
4691cb0ef41Sopenharmony_ci      CAST(LoadFeedbackVectorSlot(feedback_vector, slot));
4701cb0ef41Sopenharmony_ci  GotoIfNot(HasBoilerplate(maybe_allocation_site), call_runtime);
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ci  TNode<AllocationSite> allocation_site = CAST(maybe_allocation_site);
4731cb0ef41Sopenharmony_ci  TNode<JSArray> boilerplate = CAST(LoadBoilerplate(allocation_site));
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci  if (allocation_site_mode == TRACK_ALLOCATION_SITE &&
4761cb0ef41Sopenharmony_ci      V8_ALLOCATION_SITE_TRACKING_BOOL) {
4771cb0ef41Sopenharmony_ci    return CloneFastJSArray(context, boilerplate, allocation_site);
4781cb0ef41Sopenharmony_ci  } else {
4791cb0ef41Sopenharmony_ci    return CloneFastJSArray(context, boilerplate);
4801cb0ef41Sopenharmony_ci  }
4811cb0ef41Sopenharmony_ci}
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ciTNode<JSArray> ConstructorBuiltinsAssembler::CreateEmptyArrayLiteral(
4841cb0ef41Sopenharmony_ci    TNode<FeedbackVector> feedback_vector, TNode<TaggedIndex> slot,
4851cb0ef41Sopenharmony_ci    TNode<Context> context) {
4861cb0ef41Sopenharmony_ci  // Array literals always have a valid AllocationSite to properly track
4871cb0ef41Sopenharmony_ci  // elements transitions.
4881cb0ef41Sopenharmony_ci  TNode<Object> maybe_allocation_site =
4891cb0ef41Sopenharmony_ci      CAST(LoadFeedbackVectorSlot(feedback_vector, slot));
4901cb0ef41Sopenharmony_ci  TVARIABLE(AllocationSite, allocation_site);
4911cb0ef41Sopenharmony_ci
4921cb0ef41Sopenharmony_ci  Label create_empty_array(this),
4931cb0ef41Sopenharmony_ci      initialize_allocation_site(this, Label::kDeferred), done(this);
4941cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(maybe_allocation_site), &initialize_allocation_site);
4951cb0ef41Sopenharmony_ci  {
4961cb0ef41Sopenharmony_ci    allocation_site = CAST(maybe_allocation_site);
4971cb0ef41Sopenharmony_ci    Goto(&create_empty_array);
4981cb0ef41Sopenharmony_ci  }
4991cb0ef41Sopenharmony_ci  // TODO(cbruni): create the AllocationSite in CSA.
5001cb0ef41Sopenharmony_ci  BIND(&initialize_allocation_site);
5011cb0ef41Sopenharmony_ci  {
5021cb0ef41Sopenharmony_ci    allocation_site = CreateAllocationSiteInFeedbackVector(
5031cb0ef41Sopenharmony_ci        feedback_vector,
5041cb0ef41Sopenharmony_ci        // TODO(v8:10047): pass slot as TaggedIndex here
5051cb0ef41Sopenharmony_ci        Unsigned(TaggedIndexToIntPtr(slot)));
5061cb0ef41Sopenharmony_ci    Goto(&create_empty_array);
5071cb0ef41Sopenharmony_ci  }
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci  BIND(&create_empty_array);
5101cb0ef41Sopenharmony_ci  TNode<Int32T> kind = LoadElementsKind(allocation_site.value());
5111cb0ef41Sopenharmony_ci  TNode<NativeContext> native_context = LoadNativeContext(context);
5121cb0ef41Sopenharmony_ci  Comment("LoadJSArrayElementsMap");
5131cb0ef41Sopenharmony_ci  TNode<Map> array_map = LoadJSArrayElementsMap(kind, native_context);
5141cb0ef41Sopenharmony_ci  TNode<IntPtrT> zero_intptr = IntPtrConstant(0);
5151cb0ef41Sopenharmony_ci  TNode<Smi> zero = SmiConstant(0);
5161cb0ef41Sopenharmony_ci  Comment("Allocate JSArray");
5171cb0ef41Sopenharmony_ci  base::Optional<TNode<AllocationSite>> site =
5181cb0ef41Sopenharmony_ci      V8_ALLOCATION_SITE_TRACKING_BOOL
5191cb0ef41Sopenharmony_ci          ? base::make_optional(allocation_site.value())
5201cb0ef41Sopenharmony_ci          : base::nullopt;
5211cb0ef41Sopenharmony_ci  TNode<JSArray> result = AllocateJSArray(GetInitialFastElementsKind(),
5221cb0ef41Sopenharmony_ci                                          array_map, zero_intptr, zero, site);
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci  Goto(&done);
5251cb0ef41Sopenharmony_ci  BIND(&done);
5261cb0ef41Sopenharmony_ci
5271cb0ef41Sopenharmony_ci  return result;
5281cb0ef41Sopenharmony_ci}
5291cb0ef41Sopenharmony_ci
5301cb0ef41Sopenharmony_ciTNode<HeapObject> ConstructorBuiltinsAssembler::CreateShallowObjectLiteral(
5311cb0ef41Sopenharmony_ci    TNode<FeedbackVector> feedback_vector, TNode<TaggedIndex> slot,
5321cb0ef41Sopenharmony_ci    Label* call_runtime) {
5331cb0ef41Sopenharmony_ci  TNode<Object> maybe_allocation_site =
5341cb0ef41Sopenharmony_ci      CAST(LoadFeedbackVectorSlot(feedback_vector, slot));
5351cb0ef41Sopenharmony_ci  GotoIfNot(HasBoilerplate(maybe_allocation_site), call_runtime);
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ci  TNode<AllocationSite> allocation_site = CAST(maybe_allocation_site);
5381cb0ef41Sopenharmony_ci  TNode<JSObject> boilerplate = LoadBoilerplate(allocation_site);
5391cb0ef41Sopenharmony_ci  TNode<Map> boilerplate_map = LoadMap(boilerplate);
5401cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsJSObjectMap(boilerplate_map));
5411cb0ef41Sopenharmony_ci
5421cb0ef41Sopenharmony_ci  TVARIABLE(HeapObject, var_properties);
5431cb0ef41Sopenharmony_ci  {
5441cb0ef41Sopenharmony_ci    TNode<Uint32T> bit_field_3 = LoadMapBitField3(boilerplate_map);
5451cb0ef41Sopenharmony_ci    GotoIf(IsSetWord32<Map::Bits3::IsDeprecatedBit>(bit_field_3), call_runtime);
5461cb0ef41Sopenharmony_ci    // Directly copy over the property store for dict-mode boilerplates.
5471cb0ef41Sopenharmony_ci    Label if_dictionary(this), if_fast(this), done(this);
5481cb0ef41Sopenharmony_ci    Branch(IsSetWord32<Map::Bits3::IsDictionaryMapBit>(bit_field_3),
5491cb0ef41Sopenharmony_ci           &if_dictionary, &if_fast);
5501cb0ef41Sopenharmony_ci    BIND(&if_dictionary);
5511cb0ef41Sopenharmony_ci    {
5521cb0ef41Sopenharmony_ci      Comment("Copy dictionary properties");
5531cb0ef41Sopenharmony_ci      if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
5541cb0ef41Sopenharmony_ci        var_properties =
5551cb0ef41Sopenharmony_ci            CopySwissNameDictionary(CAST(LoadSlowProperties(boilerplate)));
5561cb0ef41Sopenharmony_ci      } else {
5571cb0ef41Sopenharmony_ci        var_properties = CopyNameDictionary(
5581cb0ef41Sopenharmony_ci            CAST(LoadSlowProperties(boilerplate)), call_runtime);
5591cb0ef41Sopenharmony_ci      }
5601cb0ef41Sopenharmony_ci      // Slow objects have no in-object properties.
5611cb0ef41Sopenharmony_ci      Goto(&done);
5621cb0ef41Sopenharmony_ci    }
5631cb0ef41Sopenharmony_ci    BIND(&if_fast);
5641cb0ef41Sopenharmony_ci    {
5651cb0ef41Sopenharmony_ci      // TODO(cbruni): support copying out-of-object properties.
5661cb0ef41Sopenharmony_ci      TNode<HeapObject> boilerplate_properties =
5671cb0ef41Sopenharmony_ci          LoadFastProperties(boilerplate);
5681cb0ef41Sopenharmony_ci      GotoIfNot(IsEmptyFixedArray(boilerplate_properties), call_runtime);
5691cb0ef41Sopenharmony_ci      var_properties = EmptyFixedArrayConstant();
5701cb0ef41Sopenharmony_ci      Goto(&done);
5711cb0ef41Sopenharmony_ci    }
5721cb0ef41Sopenharmony_ci    BIND(&done);
5731cb0ef41Sopenharmony_ci  }
5741cb0ef41Sopenharmony_ci
5751cb0ef41Sopenharmony_ci  TVARIABLE(FixedArrayBase, var_elements);
5761cb0ef41Sopenharmony_ci  {
5771cb0ef41Sopenharmony_ci    // Copy the elements backing store, assuming that it's flat.
5781cb0ef41Sopenharmony_ci    Label if_empty_fixed_array(this), if_copy_elements(this), done(this);
5791cb0ef41Sopenharmony_ci    TNode<FixedArrayBase> boilerplate_elements = LoadElements(boilerplate);
5801cb0ef41Sopenharmony_ci    Branch(IsEmptyFixedArray(boilerplate_elements), &if_empty_fixed_array,
5811cb0ef41Sopenharmony_ci           &if_copy_elements);
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci    BIND(&if_empty_fixed_array);
5841cb0ef41Sopenharmony_ci    var_elements = boilerplate_elements;
5851cb0ef41Sopenharmony_ci    Goto(&done);
5861cb0ef41Sopenharmony_ci
5871cb0ef41Sopenharmony_ci    BIND(&if_copy_elements);
5881cb0ef41Sopenharmony_ci    CSA_DCHECK(this, Word32BinaryNot(
5891cb0ef41Sopenharmony_ci                         IsFixedCOWArrayMap(LoadMap(boilerplate_elements))));
5901cb0ef41Sopenharmony_ci    auto flags = ExtractFixedArrayFlag::kAllFixedArrays;
5911cb0ef41Sopenharmony_ci    var_elements = CloneFixedArray(boilerplate_elements, flags);
5921cb0ef41Sopenharmony_ci    Goto(&done);
5931cb0ef41Sopenharmony_ci    BIND(&done);
5941cb0ef41Sopenharmony_ci  }
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci  // Ensure new-space allocation for a fresh JSObject so we can skip write
5971cb0ef41Sopenharmony_ci  // barriers when copying all object fields.
5981cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSObject::kMaxInstanceSize < kMaxRegularHeapObjectSize);
5991cb0ef41Sopenharmony_ci  TNode<IntPtrT> instance_size =
6001cb0ef41Sopenharmony_ci      TimesTaggedSize(LoadMapInstanceSizeInWords(boilerplate_map));
6011cb0ef41Sopenharmony_ci  TNode<IntPtrT> allocation_size = instance_size;
6021cb0ef41Sopenharmony_ci  bool needs_allocation_memento = FLAG_allocation_site_pretenuring;
6031cb0ef41Sopenharmony_ci  if (needs_allocation_memento) {
6041cb0ef41Sopenharmony_ci    DCHECK(V8_ALLOCATION_SITE_TRACKING_BOOL);
6051cb0ef41Sopenharmony_ci    // Prepare for inner-allocating the AllocationMemento.
6061cb0ef41Sopenharmony_ci    allocation_size =
6071cb0ef41Sopenharmony_ci        IntPtrAdd(instance_size, IntPtrConstant(AllocationMemento::kSize));
6081cb0ef41Sopenharmony_ci  }
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci  TNode<HeapObject> copy =
6111cb0ef41Sopenharmony_ci      UncheckedCast<HeapObject>(AllocateInNewSpace(allocation_size));
6121cb0ef41Sopenharmony_ci  {
6131cb0ef41Sopenharmony_ci    Comment("Initialize Literal Copy");
6141cb0ef41Sopenharmony_ci    // Initialize Object fields.
6151cb0ef41Sopenharmony_ci    StoreMapNoWriteBarrier(copy, boilerplate_map);
6161cb0ef41Sopenharmony_ci    StoreObjectFieldNoWriteBarrier(copy, JSObject::kPropertiesOrHashOffset,
6171cb0ef41Sopenharmony_ci                                   var_properties.value());
6181cb0ef41Sopenharmony_ci    StoreObjectFieldNoWriteBarrier(copy, JSObject::kElementsOffset,
6191cb0ef41Sopenharmony_ci                                   var_elements.value());
6201cb0ef41Sopenharmony_ci  }
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci  // Initialize the AllocationMemento before potential GCs due to heap number
6231cb0ef41Sopenharmony_ci  // allocation when copying the in-object properties.
6241cb0ef41Sopenharmony_ci  if (needs_allocation_memento) {
6251cb0ef41Sopenharmony_ci    InitializeAllocationMemento(copy, instance_size, allocation_site);
6261cb0ef41Sopenharmony_ci  }
6271cb0ef41Sopenharmony_ci
6281cb0ef41Sopenharmony_ci  {
6291cb0ef41Sopenharmony_ci    // Copy over in-object properties.
6301cb0ef41Sopenharmony_ci    Label continue_with_write_barrier(this), done_init(this);
6311cb0ef41Sopenharmony_ci    TVARIABLE(IntPtrT, offset, IntPtrConstant(JSObject::kHeaderSize));
6321cb0ef41Sopenharmony_ci    {
6331cb0ef41Sopenharmony_ci      Comment("Copy in-object properties fast");
6341cb0ef41Sopenharmony_ci      Label continue_fast(this, &offset);
6351cb0ef41Sopenharmony_ci      Branch(IntPtrEqual(offset.value(), instance_size), &done_init,
6361cb0ef41Sopenharmony_ci             &continue_fast);
6371cb0ef41Sopenharmony_ci      BIND(&continue_fast);
6381cb0ef41Sopenharmony_ci      TNode<Object> field = LoadObjectField(boilerplate, offset.value());
6391cb0ef41Sopenharmony_ci      Label store_field(this);
6401cb0ef41Sopenharmony_ci      GotoIf(TaggedIsSmi(field), &store_field);
6411cb0ef41Sopenharmony_ci      // TODO(leszeks): Read the field descriptor to decide if this heap
6421cb0ef41Sopenharmony_ci      // number is mutable or not.
6431cb0ef41Sopenharmony_ci      GotoIf(IsHeapNumber(CAST(field)), &continue_with_write_barrier);
6441cb0ef41Sopenharmony_ci      Goto(&store_field);
6451cb0ef41Sopenharmony_ci      BIND(&store_field);
6461cb0ef41Sopenharmony_ci      StoreObjectFieldNoWriteBarrier(copy, offset.value(), field);
6471cb0ef41Sopenharmony_ci      offset = IntPtrAdd(offset.value(), IntPtrConstant(kTaggedSize));
6481cb0ef41Sopenharmony_ci      Branch(WordNotEqual(offset.value(), instance_size), &continue_fast,
6491cb0ef41Sopenharmony_ci             &done_init);
6501cb0ef41Sopenharmony_ci    }
6511cb0ef41Sopenharmony_ci
6521cb0ef41Sopenharmony_ci    // Continue initializing the literal after seeing the first sub-object
6531cb0ef41Sopenharmony_ci    // potentially causing allocation. In this case we prepare the new literal
6541cb0ef41Sopenharmony_ci    // by copying all pending fields over from the boilerplate and emit full
6551cb0ef41Sopenharmony_ci    // write barriers from here on.
6561cb0ef41Sopenharmony_ci    BIND(&continue_with_write_barrier);
6571cb0ef41Sopenharmony_ci    {
6581cb0ef41Sopenharmony_ci      Comment("Copy in-object properties slow");
6591cb0ef41Sopenharmony_ci      BuildFastLoop<IntPtrT>(
6601cb0ef41Sopenharmony_ci          offset.value(), instance_size,
6611cb0ef41Sopenharmony_ci          [=](TNode<IntPtrT> offset) {
6621cb0ef41Sopenharmony_ci            // TODO(ishell): value decompression is not necessary here.
6631cb0ef41Sopenharmony_ci            TNode<Object> field = LoadObjectField(boilerplate, offset);
6641cb0ef41Sopenharmony_ci            StoreObjectFieldNoWriteBarrier(copy, offset, field);
6651cb0ef41Sopenharmony_ci          },
6661cb0ef41Sopenharmony_ci          kTaggedSize, IndexAdvanceMode::kPost);
6671cb0ef41Sopenharmony_ci      CopyMutableHeapNumbersInObject(copy, offset.value(), instance_size);
6681cb0ef41Sopenharmony_ci      Goto(&done_init);
6691cb0ef41Sopenharmony_ci    }
6701cb0ef41Sopenharmony_ci    BIND(&done_init);
6711cb0ef41Sopenharmony_ci  }
6721cb0ef41Sopenharmony_ci  return copy;
6731cb0ef41Sopenharmony_ci}
6741cb0ef41Sopenharmony_ci
6751cb0ef41Sopenharmony_ci// Used by the CreateEmptyObjectLiteral bytecode and the Object constructor.
6761cb0ef41Sopenharmony_ciTNode<JSObject> ConstructorBuiltinsAssembler::CreateEmptyObjectLiteral(
6771cb0ef41Sopenharmony_ci    TNode<Context> context) {
6781cb0ef41Sopenharmony_ci  TNode<NativeContext> native_context = LoadNativeContext(context);
6791cb0ef41Sopenharmony_ci  TNode<Map> map = LoadObjectFunctionInitialMap(native_context);
6801cb0ef41Sopenharmony_ci  // Ensure that slack tracking is disabled for the map.
6811cb0ef41Sopenharmony_ci  STATIC_ASSERT(Map::kNoSlackTracking == 0);
6821cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsClearWord32<Map::Bits3::ConstructionCounterBits>(
6831cb0ef41Sopenharmony_ci                       LoadMapBitField3(map)));
6841cb0ef41Sopenharmony_ci  TNode<FixedArray> empty_fixed_array = EmptyFixedArrayConstant();
6851cb0ef41Sopenharmony_ci  TNode<JSObject> result =
6861cb0ef41Sopenharmony_ci      AllocateJSObjectFromMap(map, empty_fixed_array, empty_fixed_array);
6871cb0ef41Sopenharmony_ci  return result;
6881cb0ef41Sopenharmony_ci}
6891cb0ef41Sopenharmony_ci
6901cb0ef41Sopenharmony_civoid ConstructorBuiltinsAssembler::CopyMutableHeapNumbersInObject(
6911cb0ef41Sopenharmony_ci    TNode<HeapObject> copy, TNode<IntPtrT> start_offset,
6921cb0ef41Sopenharmony_ci    TNode<IntPtrT> end_offset) {
6931cb0ef41Sopenharmony_ci  // Iterate over all object properties of a freshly copied object and
6941cb0ef41Sopenharmony_ci  // duplicate mutable heap numbers.
6951cb0ef41Sopenharmony_ci  Comment("Copy mutable HeapNumber values");
6961cb0ef41Sopenharmony_ci  BuildFastLoop<IntPtrT>(
6971cb0ef41Sopenharmony_ci      start_offset, end_offset,
6981cb0ef41Sopenharmony_ci      [=](TNode<IntPtrT> offset) {
6991cb0ef41Sopenharmony_ci        TNode<Object> field = LoadObjectField(copy, offset);
7001cb0ef41Sopenharmony_ci        Label copy_heap_number(this, Label::kDeferred), continue_loop(this);
7011cb0ef41Sopenharmony_ci        // We only have to clone complex field values.
7021cb0ef41Sopenharmony_ci        GotoIf(TaggedIsSmi(field), &continue_loop);
7031cb0ef41Sopenharmony_ci        // TODO(leszeks): Read the field descriptor to decide if this heap
7041cb0ef41Sopenharmony_ci        // number is mutable or not.
7051cb0ef41Sopenharmony_ci        Branch(IsHeapNumber(CAST(field)), &copy_heap_number, &continue_loop);
7061cb0ef41Sopenharmony_ci        BIND(&copy_heap_number);
7071cb0ef41Sopenharmony_ci        {
7081cb0ef41Sopenharmony_ci          TNode<Float64T> double_value = LoadHeapNumberValue(CAST(field));
7091cb0ef41Sopenharmony_ci          TNode<HeapNumber> heap_number =
7101cb0ef41Sopenharmony_ci              AllocateHeapNumberWithValue(double_value);
7111cb0ef41Sopenharmony_ci          StoreObjectField(copy, offset, heap_number);
7121cb0ef41Sopenharmony_ci          Goto(&continue_loop);
7131cb0ef41Sopenharmony_ci        }
7141cb0ef41Sopenharmony_ci        BIND(&continue_loop);
7151cb0ef41Sopenharmony_ci      },
7161cb0ef41Sopenharmony_ci      kTaggedSize, IndexAdvanceMode::kPost);
7171cb0ef41Sopenharmony_ci}
7181cb0ef41Sopenharmony_ci
7191cb0ef41Sopenharmony_ci}  // namespace internal
7201cb0ef41Sopenharmony_ci}  // namespace v8
721