162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Copyright 2016 the V8 project authors. All rights reserved.
262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// found in the LICENSE file.
462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins-constructor.h"
662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/ast/ast.h"
762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins-utils.h"
862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins.h"
962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/code-factory.h"
1062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/code-stub-assembler.h"
1162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/counters.h"
1262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/interface-descriptors.h"
1362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace v8 {
1662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace internal {
1762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypedef compiler::Node Node;
1962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ConstructorBuiltinsAssembler::EmitFastNewClosure(Node* shared_info,
2162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                       Node* feedback_vector,
2262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                       Node* slot,
2362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                       Node* context) {
2462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef compiler::CodeAssembler::Label Label;
2562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef compiler::CodeAssembler::Variable Variable;
2662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Isolate* isolate = this->isolate();
2862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Factory* factory = isolate->factory();
2962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  IncrementCounter(isolate->counters()->fast_new_closure_total(), 1);
3062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Create a new closure from the given function info in new space
3262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* result = Allocate(JSFunction::kSize);
3362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Calculate the index of the map we should install on the function based on
3562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // the FunctionKind and LanguageMode of the function.
3662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Note: Must be kept in sync with Context::FunctionMapIndex
3762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* compiler_hints =
3862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadObjectField(shared_info, SharedFunctionInfo::kCompilerHintsOffset,
3962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      MachineType::Uint32());
4062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* is_strict = Word32And(
4162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      compiler_hints, Int32Constant(1 << SharedFunctionInfo::kStrictModeBit));
4262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
4362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label if_normal(this), if_generator(this), if_async(this),
4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if_class_constructor(this), if_function_without_prototype(this),
4562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      load_map(this);
4662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable map_index(this, MachineType::PointerRepresentation());
4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
4862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  STATIC_ASSERT(FunctionKind::kNormalFunction == 0);
4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* is_not_normal =
5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Word32And(compiler_hints,
5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                Int32Constant(SharedFunctionInfo::kAllFunctionKindBitsMask));
5262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIfNot(is_not_normal, &if_normal);
5362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* is_generator = Word32And(
5562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      compiler_hints, Int32Constant(FunctionKind::kGeneratorFunction
5662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    << SharedFunctionInfo::kFunctionKindShift));
5762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(is_generator, &if_generator);
5862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* is_async = Word32And(
6062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      compiler_hints, Int32Constant(FunctionKind::kAsyncFunction
6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    << SharedFunctionInfo::kFunctionKindShift));
6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(is_async, &if_async);
6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* is_class_constructor = Word32And(
6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      compiler_hints, Int32Constant(FunctionKind::kClassConstructor
6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    << SharedFunctionInfo::kFunctionKindShift));
6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(is_class_constructor, &if_class_constructor);
6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (FLAG_debug_code) {
7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Function must be a function without a prototype.
7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CSA_ASSERT(
7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        this,
7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Word32And(compiler_hints,
7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  Int32Constant((FunctionKind::kAccessorFunction |
7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 FunctionKind::kArrowFunction |
7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 FunctionKind::kConciseMethod)
7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                << SharedFunctionInfo::kFunctionKindShift)));
7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Goto(&if_function_without_prototype);
8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&if_normal);
8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    map_index.Bind(SelectIntPtrConstant(is_strict,
8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        Context::STRICT_FUNCTION_MAP_INDEX,
8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        Context::SLOPPY_FUNCTION_MAP_INDEX));
8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&load_map);
8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&if_generator);
9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    map_index.Bind(IntPtrConstant(Context::GENERATOR_FUNCTION_MAP_INDEX));
9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&load_map);
9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&if_async);
9662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    map_index.Bind(IntPtrConstant(Context::ASYNC_FUNCTION_MAP_INDEX));
9862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&load_map);
9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
10162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&if_class_constructor);
10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    map_index.Bind(IntPtrConstant(Context::CLASS_FUNCTION_MAP_INDEX));
10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&load_map);
10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&if_function_without_prototype);
10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    map_index.Bind(
11062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrConstant(Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX));
11162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&load_map);
11262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
11362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
11462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&load_map);
11562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
11662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Get the function map in the current native context and set that
11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // as the map of the allocated object.
11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* native_context = LoadNativeContext(context);
11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* map_slot_value =
12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadFixedArrayElement(native_context, map_index.value());
12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreMapNoWriteBarrier(result, map_slot_value);
12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Initialize the rest of the function.
12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* empty_fixed_array = HeapConstant(factory->empty_fixed_array());
12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(result, JSObject::kPropertiesOffset,
12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 empty_fixed_array);
12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(result, JSObject::kElementsOffset,
12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 empty_fixed_array);
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* literals_cell = LoadFixedArrayElement(
13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      feedback_vector, slot, 0, CodeStubAssembler::SMI_PARAMETERS);
13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Bump the closure counter encoded in the cell's map.
13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* cell_map = LoadMap(literals_cell);
13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Label no_closures(this), one_closure(this), cell_done(this);
13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GotoIf(IsNoClosuresCellMap(cell_map), &no_closures);
13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GotoIf(IsOneClosureCellMap(cell_map), &one_closure);
13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CSA_ASSERT(this, IsManyClosuresCellMap(cell_map));
13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&cell_done);
14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Bind(&no_closures);
14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreMapNoWriteBarrier(literals_cell, Heap::kOneClosureCellMapRootIndex);
14362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&cell_done);
14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Bind(&one_closure);
14662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreMapNoWriteBarrier(literals_cell, Heap::kManyClosuresCellMapRootIndex);
14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&cell_done);
14862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Bind(&cell_done);
15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(result, JSFunction::kFeedbackVectorOffset,
15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 literals_cell);
15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(
15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      result, JSFunction::kPrototypeOrInitialMapOffset, TheHoleConstant());
15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(result, JSFunction::kSharedFunctionInfoOffset,
15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 shared_info);
15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(result, JSFunction::kContextOffset, context);
15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<Code> lazy_builtin_handle(
15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      isolate->builtins()->builtin(Builtins::kCompileLazy));
16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* lazy_builtin = HeapConstant(lazy_builtin_handle);
16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* lazy_builtin_entry =
16262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      IntPtrAdd(BitcastTaggedToWord(lazy_builtin),
16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                IntPtrConstant(Code::kHeaderSize - kHeapObjectTag));
16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(result, JSFunction::kCodeEntryOffset,
16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 lazy_builtin_entry,
16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 MachineType::PointerRepresentation());
16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(result, JSFunction::kNextFunctionLinkOffset,
16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 UndefinedConstant());
16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return result;
17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
17362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) {
17462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* shared = Parameter(FastNewClosureDescriptor::kSharedFunctionInfo);
17562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(FastNewClosureDescriptor::kContext);
17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* vector = Parameter(FastNewClosureDescriptor::kVector);
17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* slot = Parameter(FastNewClosureDescriptor::kSlot);
17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(EmitFastNewClosure(shared, vector, slot, context));
17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef FastNewObjectDescriptor Descriptor;
18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(Descriptor::kContext);
18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* target = Parameter(Descriptor::kTarget);
18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* new_target = Parameter(Descriptor::kNewTarget);
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label call_runtime(this);
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(result);
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&call_runtime);
19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  TailCallRuntime(Runtime::kNewObject, context, target, new_target);
19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context,
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                      Node* target,
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                      Node* new_target) {
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable var_obj(this, MachineRepresentation::kTagged);
20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label call_runtime(this), end(this);
20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  var_obj.Bind(result);
20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Goto(&end);
20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&call_runtime);
20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  var_obj.Bind(CallRuntime(Runtime::kNewObject, context, target, new_target));
20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Goto(&end);
20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&end);
21162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return var_obj.value();
21262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
21362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ConstructorBuiltinsAssembler::EmitFastNewObject(
21562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* context, Node* target, Node* new_target,
21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CodeAssemblerLabel* call_runtime) {
21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT(this, HasInstanceType(target, JS_FUNCTION_TYPE));
21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT(this, IsJSReceiver(new_target));
21962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Verify that the new target is a JSFunction.
22162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label fast(this), end(this);
22262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(HasInstanceType(new_target, JS_FUNCTION_TYPE), &fast);
22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Goto(call_runtime);
22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&fast);
22662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Load the initial map and verify that it's in fact a map.
22862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* initial_map =
22962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadObjectField(new_target, JSFunction::kPrototypeOrInitialMapOffset);
23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(TaggedIsSmi(initial_map), call_runtime);
23162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(DoesntHaveInstanceType(initial_map, MAP_TYPE), call_runtime);
23262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Fall back to runtime if the target differs from the new target's
23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // initial map constructor.
23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* new_target_constructor =
23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadObjectField(initial_map, Map::kConstructorOrBackPointerOffset);
23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(WordNotEqual(target, new_target_constructor), call_runtime);
23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* instance_size_words = ChangeUint32ToWord(LoadObjectField(
24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* instance_size =
24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      WordShl(instance_size_words, IntPtrConstant(kPointerSizeLog2));
24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* object = Allocate(instance_size);
24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreMapNoWriteBarrier(object, initial_map);
24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* empty_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 empty_array);
24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset,
25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 empty_array);
25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  instance_size_words = ChangeUint32ToWord(LoadObjectField(
25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  instance_size =
25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      WordShl(instance_size_words, IntPtrConstant(kPointerSizeLog2));
25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Perform in-object slack tracking if requested.
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* bit_field3 = LoadMapBitField3(initial_map);
25962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label slack_tracking(this), finalize(this, Label::kDeferred), done(this);
26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IsSetWord32<Map::ConstructionCounter>(bit_field3), &slack_tracking);
26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Initialize remaining fields.
26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("no slack tracking");
26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             instance_size, Heap::kUndefinedValueRootIndex);
26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&end);
26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
27062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
27162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Bind(&slack_tracking);
27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Decrease generous allocation count.
27462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    STATIC_ASSERT(Map::ConstructionCounter::kNext == 32);
27562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("update allocation count");
27662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* new_bit_field3 = Int32Sub(
27762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        bit_field3, Int32Constant(1 << Map::ConstructionCounter::kShift));
27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(initial_map, Map::kBitField3Offset,
27962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   new_bit_field3,
28062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   MachineRepresentation::kWord32);
28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GotoIf(IsClearWord32<Map::ConstructionCounter>(new_bit_field3), &finalize);
28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* unused_fields = LoadObjectField(
28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8());
28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* used_size =
28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrSub(instance_size, WordShl(ChangeUint32ToWord(unused_fields),
28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         IntPtrConstant(kPointerSizeLog2)));
28862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("initialize filler fields (no finalize)");
29062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InitializeFieldsWithRoot(object, used_size, instance_size,
29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             Heap::kOnePointerFillerMapRootIndex);
29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
29362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("initialize undefined fields (no finalize)");
29462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
29562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             used_size, Heap::kUndefinedValueRootIndex);
29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&end);
29762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Finalize the instance size.
30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Bind(&finalize);
30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* unused_fields = LoadObjectField(
30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8());
30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* used_size =
30662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrSub(instance_size, WordShl(ChangeUint32ToWord(unused_fields),
30762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         IntPtrConstant(kPointerSizeLog2)));
30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
30962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("initialize filler fields (finalize)");
31062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InitializeFieldsWithRoot(object, used_size, instance_size,
31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             Heap::kOnePointerFillerMapRootIndex);
31262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("initialize undefined fields (finalize)");
31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
31562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             used_size, Heap::kUndefinedValueRootIndex);
31662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CallRuntime(Runtime::kFinalizeInstanceSize, context, initial_map);
31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&end);
31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&end);
32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return object;
32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
32462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
32562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ConstructorBuiltinsAssembler::EmitFastNewFunctionContext(
32662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* function, Node* slots, Node* context, ScopeType scope_type) {
32762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  slots = ChangeUint32ToWord(slots);
32862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
32962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(ishell): Use CSA::OptimalParameterMode() here.
33062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler::ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS;
33162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* min_context_slots = IntPtrConstant(Context::MIN_CONTEXT_SLOTS);
33262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* length = IntPtrAdd(slots, min_context_slots);
33362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* size = GetFixedArrayAllocationSize(length, FAST_ELEMENTS, mode);
33462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
33562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Create a new closure from the given function info in new space
33662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* function_context = Allocate(size);
33762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Heap::RootListIndex context_type;
33962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (scope_type) {
34062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case EVAL_SCOPE:
34162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      context_type = Heap::kEvalContextMapRootIndex;
34262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
34362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case FUNCTION_SCOPE:
34462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      context_type = Heap::kFunctionContextMapRootIndex;
34562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
34662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    default:
34762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      UNREACHABLE();
34862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
34962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreMapNoWriteBarrier(function_context, context_type);
35062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(function_context, Context::kLengthOffset,
35162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 SmiTag(length));
35262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Set up the fixed slots.
35462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreFixedArrayElement(function_context, Context::CLOSURE_INDEX, function,
35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         SKIP_WRITE_BARRIER);
35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreFixedArrayElement(function_context, Context::PREVIOUS_INDEX, context,
35762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         SKIP_WRITE_BARRIER);
35862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreFixedArrayElement(function_context, Context::EXTENSION_INDEX,
35962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         TheHoleConstant(), SKIP_WRITE_BARRIER);
36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Copy the native context from the previous context.
36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* native_context = LoadNativeContext(context);
36362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreFixedArrayElement(function_context, Context::NATIVE_CONTEXT_INDEX,
36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         native_context, SKIP_WRITE_BARRIER);
36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Initialize the rest of the slots to undefined.
36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* undefined = UndefinedConstant();
36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BuildFastFixedArrayForEach(
36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      function_context, FAST_ELEMENTS, min_context_slots, length,
37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      [this, undefined](Node* context, Node* offset) {
37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        StoreNoWriteBarrier(MachineRepresentation::kTagged, context, offset,
37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                            undefined);
37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      },
37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      mode);
37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
37662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return function_context;
37762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// static
38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint ConstructorBuiltinsAssembler::MaximumFunctionContextSlots() {
38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return FLAG_test_small_max_function_context_stub_size ? kSmallMaximumSlots
38262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                        : kMaximumSlots;
38362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
38462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
38562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastNewFunctionContextEval, ConstructorBuiltinsAssembler) {
38662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* function = Parameter(FastNewFunctionContextDescriptor::kFunction);
38762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* slots = Parameter(FastNewFunctionContextDescriptor::kSlots);
38862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(FastNewFunctionContextDescriptor::kContext);
38962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(EmitFastNewFunctionContext(function, slots, context,
39062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    ScopeType::EVAL_SCOPE));
39162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
39262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
39362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastNewFunctionContextFunction, ConstructorBuiltinsAssembler) {
39462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* function = Parameter(FastNewFunctionContextDescriptor::kFunction);
39562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* slots = Parameter(FastNewFunctionContextDescriptor::kSlots);
39662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(FastNewFunctionContextDescriptor::kContext);
39762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(EmitFastNewFunctionContext(function, slots, context,
39862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    ScopeType::FUNCTION_SCOPE));
39962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
40062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
40162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Code> Builtins::NewFunctionContext(ScopeType scope_type) {
40262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (scope_type) {
40362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case ScopeType::EVAL_SCOPE:
40462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastNewFunctionContextEval();
40562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case ScopeType::FUNCTION_SCOPE:
40662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastNewFunctionContextFunction();
40762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    default:
40862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      UNREACHABLE();
40962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
41062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Handle<Code>::null();
41162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
41262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
41362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ConstructorBuiltinsAssembler::EmitFastCloneRegExp(Node* closure,
41462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                        Node* literal_index,
41562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                        Node* pattern,
41662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                        Node* flags,
41762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                        Node* context) {
41862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef CodeStubAssembler::Label Label;
41962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef CodeStubAssembler::Variable Variable;
42062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef compiler::Node Node;
42162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label call_runtime(this, Label::kDeferred), end(this);
42362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
42462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable result(this, MachineRepresentation::kTagged);
42562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
42662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* cell = LoadObjectField(closure, JSFunction::kFeedbackVectorOffset);
42762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* feedback_vector = LoadObjectField(cell, Cell::kValueOffset);
42862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* boilerplate = LoadFixedArrayElement(feedback_vector, literal_index, 0,
42962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                            CodeStubAssembler::SMI_PARAMETERS);
43062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IsUndefined(boilerplate), &call_runtime);
43162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
43262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
43362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
43462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* copy = Allocate(size);
43562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    for (int offset = 0; offset < size; offset += kPointerSize) {
43662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Node* value = LoadObjectField(boilerplate, offset);
43762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      StoreObjectFieldNoWriteBarrier(copy, offset, value);
43862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
43962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(copy);
44062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&end);
44162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
44262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
44362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&call_runtime);
44462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
44562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(CallRuntime(Runtime::kCreateRegExpLiteral, context, closure,
44662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                            literal_index, pattern, flags));
44762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&end);
44862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
44962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
45062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&end);
45162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return result.value();
45262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
45362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
45462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastCloneRegExp, ConstructorBuiltinsAssembler) {
45562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* closure = Parameter(FastCloneRegExpDescriptor::kClosure);
45662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* literal_index = Parameter(FastCloneRegExpDescriptor::kLiteralIndex);
45762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* pattern = Parameter(FastCloneRegExpDescriptor::kPattern);
45862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* flags = Parameter(FastCloneRegExpDescriptor::kFlags);
45962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(FastCloneRegExpDescriptor::kContext);
46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
46162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(EmitFastCloneRegExp(closure, literal_index, pattern, flags, context));
46262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
46362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
46462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ConstructorBuiltinsAssembler::NonEmptyShallowClone(
46562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* boilerplate, Node* boilerplate_map, Node* boilerplate_elements,
46662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* allocation_site, Node* capacity, ElementsKind kind) {
46762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef CodeStubAssembler::ParameterMode ParameterMode;
46862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
46962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ParameterMode param_mode = OptimalParameterMode();
47062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
47162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* length = LoadJSArrayLength(boilerplate);
47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  capacity = TaggedToParameter(capacity, param_mode);
47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node *array, *elements;
47562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  std::tie(array, elements) = AllocateUninitializedJSArrayWithElements(
47662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      kind, boilerplate_map, length, allocation_site, capacity, param_mode);
47762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
47862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Comment("copy elements header");
47962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Header consists of map and length.
48062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize);
48162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreMap(elements, LoadMap(boilerplate_elements));
48262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
48362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int offset = FixedArrayBase::kLengthOffset;
48462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(
48562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        elements, offset, LoadObjectField(boilerplate_elements, offset));
48662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
48762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
48862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  length = TaggedToParameter(length, param_mode);
48962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
49062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Comment("copy boilerplate elements");
49162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CopyFixedArrayElements(kind, boilerplate_elements, elements, length,
49262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         SKIP_WRITE_BARRIER, param_mode);
49362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1);
49462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
49562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return array;
49662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
49762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
49862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ConstructorBuiltinsAssembler::EmitFastCloneShallowArray(
49962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* closure, Node* literal_index, Node* context,
50062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CodeAssemblerLabel* call_runtime, AllocationSiteMode allocation_site_mode) {
50162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef CodeStubAssembler::Label Label;
50262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef CodeStubAssembler::Variable Variable;
50362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef compiler::Node Node;
50462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
50562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label zero_capacity(this), cow_elements(this), fast_elements(this),
50662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return_result(this);
50762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable result(this, MachineRepresentation::kTagged);
50862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
50962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* cell = LoadObjectField(closure, JSFunction::kFeedbackVectorOffset);
51062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* feedback_vector = LoadObjectField(cell, Cell::kValueOffset);
51162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* allocation_site = LoadFixedArrayElement(
51262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      feedback_vector, literal_index, 0, CodeStubAssembler::SMI_PARAMETERS);
51362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
51462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IsUndefined(allocation_site), call_runtime);
51562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  allocation_site = LoadFixedArrayElement(feedback_vector, literal_index, 0,
51662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          CodeStubAssembler::SMI_PARAMETERS);
51762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
51862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* boilerplate =
51962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadObjectField(allocation_site, AllocationSite::kTransitionInfoOffset);
52062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* boilerplate_map = LoadMap(boilerplate);
52162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* boilerplate_elements = LoadElements(boilerplate);
52262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* capacity = LoadFixedArrayBaseLength(boilerplate_elements);
52362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  allocation_site =
52462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      allocation_site_mode == TRACK_ALLOCATION_SITE ? allocation_site : nullptr;
52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
52662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* zero = SmiConstant(Smi::kZero);
52762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(SmiEqual(capacity, zero), &zero_capacity);
52862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
52962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* elements_map = LoadMap(boilerplate_elements);
53062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IsFixedCOWArrayMap(elements_map), &cow_elements);
53162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
53262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IsFixedArrayMap(elements_map), &fast_elements);
53362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
53462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("fast double elements path");
53562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (FLAG_debug_code) {
53662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Label correct_elements_map(this), abort(this, Label::kDeferred);
53762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Branch(IsFixedDoubleArrayMap(elements_map), &correct_elements_map,
53862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             &abort);
53962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
54062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Bind(&abort);
54162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      {
54262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Node* abort_id = SmiConstant(
54362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            Smi::FromInt(BailoutReason::kExpectedFixedDoubleArrayMap));
54462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        CallRuntime(Runtime::kAbort, context, abort_id);
54562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        result.Bind(UndefinedConstant());
54662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Goto(&return_result);
54762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
54862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Bind(&correct_elements_map);
54962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
55062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
55162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* array =
55262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        NonEmptyShallowClone(boilerplate, boilerplate_map, boilerplate_elements,
55362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             allocation_site, capacity, FAST_DOUBLE_ELEMENTS);
55462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(array);
55562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&return_result);
55662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
55762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
55862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&fast_elements);
55962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
56062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("fast elements path");
56162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* array =
56262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        NonEmptyShallowClone(boilerplate, boilerplate_map, boilerplate_elements,
56362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             allocation_site, capacity, FAST_ELEMENTS);
56462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(array);
56562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&return_result);
56662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
56762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
56862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable length(this, MachineRepresentation::kTagged),
56962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      elements(this, MachineRepresentation::kTagged);
57062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label allocate_without_elements(this);
57162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
57262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&cow_elements);
57362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
57462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("fixed cow path");
57562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    length.Bind(LoadJSArrayLength(boilerplate));
57662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    elements.Bind(boilerplate_elements);
57762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
57862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&allocate_without_elements);
57962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
58062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
58162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&zero_capacity);
58262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
58362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("zero capacity path");
58462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    length.Bind(zero);
58562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    elements.Bind(LoadRoot(Heap::kEmptyFixedArrayRootIndex));
58662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
58762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&allocate_without_elements);
58862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
58962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
59062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&allocate_without_elements);
59162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
59262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* array = AllocateUninitializedJSArrayWithoutElements(
59362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        FAST_ELEMENTS, boilerplate_map, length.value(), allocation_site);
59462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectField(array, JSObject::kElementsOffset, elements.value());
59562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(array);
59662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&return_result);
59762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
59862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
59962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&return_result);
60062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return result.value();
60162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
60262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
60362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid ConstructorBuiltinsAssembler::CreateFastCloneShallowArrayBuiltin(
60462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    AllocationSiteMode allocation_site_mode) {
60562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef compiler::Node Node;
60662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef CodeStubAssembler::Label Label;
60762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
60862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* closure = Parameter(FastCloneShallowArrayDescriptor::kClosure);
60962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* literal_index =
61062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Parameter(FastCloneShallowArrayDescriptor::kLiteralIndex);
61162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* constant_elements =
61262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Parameter(FastCloneShallowArrayDescriptor::kConstantElements);
61362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(FastCloneShallowArrayDescriptor::kContext);
61462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label call_runtime(this, Label::kDeferred);
61562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(EmitFastCloneShallowArray(closure, literal_index, context,
61662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   &call_runtime, allocation_site_mode));
61762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
61862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&call_runtime);
61962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
62062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("call runtime");
62162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* flags =
62262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        SmiConstant(Smi::FromInt(ArrayLiteral::kShallowElements |
62362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 (allocation_site_mode == TRACK_ALLOCATION_SITE
62462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      ? 0
62562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      : ArrayLiteral::kDisableMementos)));
62662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Return(CallRuntime(Runtime::kCreateArrayLiteral, context, closure,
62762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       literal_index, constant_elements, flags));
62862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
62962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
63062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
63162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastCloneShallowArrayTrack, ConstructorBuiltinsAssembler) {
63262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CreateFastCloneShallowArrayBuiltin(TRACK_ALLOCATION_SITE);
63362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
63462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
63562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastCloneShallowArrayDontTrack, ConstructorBuiltinsAssembler) {
63662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CreateFastCloneShallowArrayBuiltin(DONT_TRACK_ALLOCATION_SITE);
63762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
63862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
63962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Code> Builtins::NewCloneShallowArray(
64062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    AllocationSiteMode allocation_mode) {
64162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (allocation_mode) {
64262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case TRACK_ALLOCATION_SITE:
64362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowArrayTrack();
64462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case DONT_TRACK_ALLOCATION_SITE:
64562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowArrayDontTrack();
64662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    default:
64762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      UNREACHABLE();
64862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
64962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Handle<Code>::null();
65062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
65162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
65262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// static
65362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint ConstructorBuiltinsAssembler::FastCloneShallowObjectPropertiesCount(
65462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int literal_length) {
65562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // This heuristic of setting empty literals to have
65662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // kInitialGlobalObjectUnusedPropertiesCount must remain in-sync with the
65762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // runtime.
65862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(verwaest): Unify this with the heuristic in the runtime.
65962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return literal_length == 0
66062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             ? JSObject::kInitialGlobalObjectUnusedPropertiesCount
66162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             : literal_length;
66262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
66362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
66462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ConstructorBuiltinsAssembler::EmitFastCloneShallowObject(
66562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CodeAssemblerLabel* call_runtime, Node* closure, Node* literals_index,
66662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* properties_count) {
66762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* cell = LoadObjectField(closure, JSFunction::kFeedbackVectorOffset);
66862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* feedback_vector = LoadObjectField(cell, Cell::kValueOffset);
66962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* allocation_site = LoadFixedArrayElement(
67062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      feedback_vector, literals_index, 0, CodeStubAssembler::SMI_PARAMETERS);
67162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IsUndefined(allocation_site), call_runtime);
67262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
67362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Calculate the object and allocation size based on the properties count.
67462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* object_size = IntPtrAdd(WordShl(properties_count, kPointerSizeLog2),
67562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                IntPtrConstant(JSObject::kHeaderSize));
67662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* allocation_size = object_size;
67762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (FLAG_allocation_site_pretenuring) {
67862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    allocation_size =
67962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrAdd(object_size, IntPtrConstant(AllocationMemento::kSize));
68062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
68162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* boilerplate =
68262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadObjectField(allocation_site, AllocationSite::kTransitionInfoOffset);
68362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* boilerplate_map = LoadMap(boilerplate);
68462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* instance_size = LoadMapInstanceSize(boilerplate_map);
68562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* size_in_words = WordShr(object_size, kPointerSizeLog2);
68662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIfNot(WordEqual(instance_size, size_in_words), call_runtime);
68762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
68862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* copy = Allocate(allocation_size);
68962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
69062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Copy boilerplate elements.
69162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable offset(this, MachineType::PointerRepresentation());
69262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  offset.Bind(IntPtrConstant(-kHeapObjectTag));
69362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* end_offset = IntPtrAdd(object_size, offset.value());
69462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label loop_body(this, &offset), loop_check(this, &offset);
69562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // We should always have an object size greater than zero.
69662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Goto(&loop_body);
69762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&loop_body);
69862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
69962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // The Allocate above guarantees that the copy lies in new space. This
70062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // allows us to skip write barriers. This is necessary since we may also be
70162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // copying unboxed doubles.
70262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* field = Load(MachineType::IntPtr(), boilerplate, offset.value());
70362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreNoWriteBarrier(MachineType::PointerRepresentation(), copy,
70462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                        offset.value(), field);
70562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&loop_check);
70662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
70762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&loop_check);
70862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
70962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    offset.Bind(IntPtrAdd(offset.value(), IntPtrConstant(kPointerSize)));
71062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GotoIfNot(IntPtrGreaterThanOrEqual(offset.value(), end_offset), &loop_body);
71162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
71262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
71362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (FLAG_allocation_site_pretenuring) {
71462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* memento = InnerAllocate(copy, object_size);
71562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreMapNoWriteBarrier(memento, Heap::kAllocationMementoMapRootIndex);
71662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(
71762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        memento, AllocationMemento::kAllocationSiteOffset, allocation_site);
71862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* memento_create_count = LoadObjectField(
71962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        allocation_site, AllocationSite::kPretenureCreateCountOffset);
72062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    memento_create_count =
72162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        SmiAdd(memento_create_count, SmiConstant(Smi::FromInt(1)));
72262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(allocation_site,
72362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   AllocationSite::kPretenureCreateCountOffset,
72462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   memento_create_count);
72562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
72662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
72762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(verwaest): Allocate and fill in double boxes.
72862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return copy;
72962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
73062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
73162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid ConstructorBuiltinsAssembler::CreateFastCloneShallowObjectBuiltin(
73262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int properties_count) {
73362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_GE(properties_count, 0);
73462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_LE(properties_count, kMaximumClonedShallowObjectProperties);
73562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label call_runtime(this);
73662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* closure = Parameter(0);
73762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* literals_index = Parameter(1);
73862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* properties_count_node =
74062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      IntPtrConstant(FastCloneShallowObjectPropertiesCount(properties_count));
74162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* copy = EmitFastCloneShallowObject(
74262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      &call_runtime, closure, literals_index, properties_count_node);
74362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(copy);
74462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
74562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&call_runtime);
74662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* constant_properties = Parameter(2);
74762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* flags = Parameter(3);
74862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(4);
74962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  TailCallRuntime(Runtime::kCreateObjectLiteral, context, closure,
75062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  literals_index, constant_properties, flags);
75162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
75262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
75362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define SHALLOW_OBJECT_BUILTIN(props)                                       \
75462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  TF_BUILTIN(FastCloneShallowObject##props, ConstructorBuiltinsAssembler) { \
75562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CreateFastCloneShallowObjectBuiltin(props);                             \
75662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
75762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
75862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSHALLOW_OBJECT_BUILTIN(0);
75962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSHALLOW_OBJECT_BUILTIN(1);
76062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSHALLOW_OBJECT_BUILTIN(2);
76162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSHALLOW_OBJECT_BUILTIN(3);
76262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSHALLOW_OBJECT_BUILTIN(4);
76362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSHALLOW_OBJECT_BUILTIN(5);
76462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSHALLOW_OBJECT_BUILTIN(6);
76562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
76662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Code> Builtins::NewCloneShallowObject(int length) {
76762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (length) {
76862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case 0:
76962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowObject0();
77062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case 1:
77162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowObject1();
77262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case 2:
77362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowObject2();
77462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case 3:
77562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowObject3();
77662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case 4:
77762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowObject4();
77862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case 5:
77962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowObject5();
78062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case 6:
78162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return FastCloneShallowObject6();
78262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    default:
78362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      UNREACHABLE();
78462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
78562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Handle<Code>::null();
78662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
78762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
78862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace internal
78962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace v8
790