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