1109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Copyright 2016 the V8 project authors. All rights reserved. 2109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// found in the LICENSE file. 4109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 5109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/js-create-lowering.h" 6109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 7109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/allocation-site-scopes.h" 8109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/code-factory.h" 9109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compilation-dependencies.h" 10109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/access-builder.h" 11109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/common-operator.h" 12109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/js-graph.h" 13109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/js-operator.h" 14109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/linkage.h" 15109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/node.h" 16109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/node-properties.h" 17109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/operator-properties.h" 18109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/simplified-operator.h" 19109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/compiler/state-values-utils.h" 20109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 21109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace v8 { 22109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace internal { 23109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace compiler { 24109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 25109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace { 26109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 27109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// A helper class to construct inline allocations on the simplified operator 28109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// level. This keeps track of the effect chain for initial stores on a newly 29109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// allocated object and also provides helpers for commonly allocated objects. 30109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass AllocationBuilder final { 31109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public: 32109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control) 33109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : jsgraph_(jsgraph), 34109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch allocation_(nullptr), 35109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect_(effect), 36109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch control_(control) {} 37109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 38109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Primitive allocation of static size. 39c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void Allocate(int size, PretenureFlag pretenure = NOT_TENURED, 40c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Type* type = Type::Any()) { 4113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect_ = graph()->NewNode( 4213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch common()->BeginRegion(RegionObservability::kNotObservable), effect_); 43109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch allocation_ = 44109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch graph()->NewNode(simplified()->Allocate(pretenure), 45109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jsgraph()->Constant(size), effect_, control_); 46c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // TODO(turbofan): Maybe we should put the Type* onto the Allocate operator 47c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // at some point, or maybe we should have a completely differnt story. 48c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch NodeProperties::SetType(allocation_, type); 49109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect_ = allocation_; 50109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 51109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 52109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Primitive store into a field. 53109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void Store(const FieldAccess& access, Node* value) { 54109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_, 55109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch value, effect_, control_); 56109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 57109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 58109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Primitive store into an element. 59109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void Store(ElementAccess const& access, Node* index, Node* value) { 60109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect_ = graph()->NewNode(simplified()->StoreElement(access), allocation_, 61109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch index, value, effect_, control_); 62109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 63109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 64109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Compound allocation of a FixedArray. 65109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void AllocateArray(int length, Handle<Map> map, 66109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PretenureFlag pretenure = NOT_TENURED) { 67109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(map->instance_type() == FIXED_ARRAY_TYPE || 68109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch map->instance_type() == FIXED_DOUBLE_ARRAY_TYPE); 69109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int size = (map->instance_type() == FIXED_ARRAY_TYPE) 70109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ? FixedArray::SizeFor(length) 71109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : FixedDoubleArray::SizeFor(length); 72c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Allocate(size, pretenure, Type::OtherInternal()); 73109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Store(AccessBuilder::ForMap(), map); 74109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length)); 75109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 76109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 77109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Compound store of a constant into a field. 78109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void Store(const FieldAccess& access, Handle<Object> value) { 79109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Store(access, jsgraph()->Constant(value)); 80109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 81109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 82109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void FinishAndChange(Node* node) { 83109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NodeProperties::SetType(allocation_, NodeProperties::GetType(node)); 84109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch node->ReplaceInput(0, allocation_); 85109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch node->ReplaceInput(1, effect_); 86109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch node->TrimInputCount(2); 87109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NodeProperties::ChangeOp(node, common()->FinishRegion()); 88109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 89109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 90109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* Finish() { 91109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return graph()->NewNode(common()->FinishRegion(), allocation_, effect_); 92109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 93109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 94109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch protected: 95109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch JSGraph* jsgraph() { return jsgraph_; } 96109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Graph* graph() { return jsgraph_->graph(); } 97109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CommonOperatorBuilder* common() { return jsgraph_->common(); } 98109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); } 99109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 100109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private: 101109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch JSGraph* const jsgraph_; 102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* allocation_; 103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect_; 104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* control_; 105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}; 106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Retrieves the frame state holding actual argument values. 108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* GetArgumentsFrameState(Node* frame_state) { 109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* const outer_state = NodeProperties::GetFrameStateInput(frame_state); 110109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameStateInfo outer_state_info = OpParameter<FrameStateInfo>(outer_state); 111109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return outer_state_info.type() == FrameStateType::kArgumentsAdaptor 112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ? outer_state 113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : frame_state; 114109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 115109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 116109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Checks whether allocation using the given target and new.target can be 117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// inlined. 118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool IsAllocationInlineable(Handle<JSFunction> target, 119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSFunction> new_target) { 120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return new_target->has_initial_map() && 121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch new_target->initial_map()->constructor_or_backpointer() == *target; 122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 123109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// When initializing arrays, we'll unfold the loop if the number of 125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// elements is known to be of this type. 126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochconst int kElementLoopUnrollLimit = 16; 127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 128109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Limits up to which context allocations are inlined. 129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochconst int kFunctionContextAllocationLimit = 16; 130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochconst int kBlockContextAllocationLimit = 16; 131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Determines whether the given array or object literal boilerplate satisfies 133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// all limits to be considered for fast deep-copying and computes the total 134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// size of all objects that are part of the graph. 135109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool IsFastLiteral(Handle<JSObject> boilerplate, int max_depth, 136109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int* max_properties) { 137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_GE(max_depth, 0); 138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_GE(*max_properties, 0); 139109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Make sure the boilerplate map is not deprecated. 141109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!JSObject::TryMigrateInstance(boilerplate)) return false; 142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Check for too deep nesting. 144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (max_depth == 0) return false; 145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Check the elements. 147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Isolate* const isolate = boilerplate->GetIsolate(); 148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArrayBase> elements(boilerplate->elements(), isolate); 149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (elements->length() > 0 && 150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements->map() != isolate->heap()->fixed_cow_array_map()) { 151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (boilerplate->HasFastSmiOrObjectElements()) { 152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int length = elements->length(); 154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < length; i++) { 155109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if ((*max_properties)-- == 0) return false; 156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> value(fast_elements->get(i), isolate); 157109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (value->IsJSObject()) { 158109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 159109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!IsFastLiteral(value_object, max_depth - 1, max_properties)) { 160109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return false; 161109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 162109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 163109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 164109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (!boilerplate->HasFastDoubleElements()) { 165109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return false; 166109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 167109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 168109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 169109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // TODO(turbofan): Do we want to support out-of-object properties? 170109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArray> properties(boilerplate->properties(), isolate); 171109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (properties->length() > 0) return false; 172109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 173109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Check the in-object properties. 174109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<DescriptorArray> descriptors( 175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch boilerplate->map()->instance_descriptors(), isolate); 176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int limit = boilerplate->map()->NumberOfOwnDescriptors(); 177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < limit; i++) { 178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PropertyDetails details = descriptors->GetDetails(i); 179109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (details.type() != DATA) continue; 180109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if ((*max_properties)-- == 0) return false; 181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldIndex field_index = FieldIndex::ForDescriptor(boilerplate->map(), i); 182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (boilerplate->IsUnboxedDoubleField(field_index)) continue; 183109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> value(boilerplate->RawFastPropertyAt(field_index), isolate); 184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (value->IsJSObject()) { 185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!IsFastLiteral(value_object, max_depth - 1, max_properties)) { 187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return false; 188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 190109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 191109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return true; 192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 194109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Maximum depth and total number of elements and properties for literal 195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// graphs to be considered for fast deep-copying. 196109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochconst int kMaxFastLiteralDepth = 3; 197109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochconst int kMaxFastLiteralProperties = 8; 198109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace 200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::Reduce(Node* node) { 202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch switch (node->opcode()) { 203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreate: 204109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreate(node); 205109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateArguments: 206109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreateArguments(node); 207109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateArray: 208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreateArray(node); 209bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case IrOpcode::kJSCreateClosure: 210bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return ReduceJSCreateClosure(node); 211109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateIterResultObject: 212109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreateIterResultObject(node); 213c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kJSCreateKeyValueArray: 214c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return ReduceJSCreateKeyValueArray(node); 215109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateLiteralArray: 216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateLiteralObject: 217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreateLiteral(node); 218109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateFunctionContext: 219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreateFunctionContext(node); 220109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateWithContext: 221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreateWithContext(node); 222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateCatchContext: 223109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreateCatchContext(node); 224109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kJSCreateBlockContext: 225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceJSCreateBlockContext(node); 226109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch default: 227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return NoChange(); 230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreate(Node* node) { 233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreate, node->opcode()); 234109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const target = NodeProperties::GetValueInput(node, 0); 235109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Type* const target_type = NodeProperties::GetType(target); 236109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const new_target = NodeProperties::GetValueInput(node, 1); 237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Type* const new_target_type = NodeProperties::GetType(new_target); 238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const effect = NodeProperties::GetEffectInput(node); 239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Extract constructor and original constructor function. 240c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (target_type->IsHeapConstant() && new_target_type->IsHeapConstant() && 241c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch new_target_type->AsHeapConstant()->Value()->IsJSFunction()) { 242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSFunction> constructor = 243c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value()); 244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSFunction> original_constructor = 245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSFunction>::cast(new_target_type->AsHeapConstant()->Value()); 246109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(constructor->IsConstructor()); 247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(original_constructor->IsConstructor()); 248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Check if we can inline the allocation. 250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (IsAllocationInlineable(constructor, original_constructor)) { 251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Force completion of inobject slack tracking before 252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // generating code to finalize the instance size. 253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch original_constructor->CompleteInobjectSlackTrackingIfActive(); 254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Compute instance size from initial map of {original_constructor}. 256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Map> initial_map(original_constructor->initial_map(), isolate()); 257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int const instance_size = initial_map->instance_size(); 258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Add a dependency on the {initial_map} to make sure that this code is 260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // deoptimized whenever the {initial_map} of the {original_constructor} 261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // changes. 262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch dependencies()->AssumeInitialMapCantChange(initial_map); 263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Emit code to allocate the JSObject instance for the 265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // {original_constructor}. 266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, graph()->start()); 267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Allocate(instance_size); 268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForMap(), initial_map); 269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectProperties(), 270109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jsgraph()->EmptyFixedArrayConstant()); 271109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectElements(), 272109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jsgraph()->EmptyFixedArrayConstant()); 273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) { 274109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i), 275109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jsgraph()->UndefinedConstant()); 276109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 277109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 279109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return NoChange(); 282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 284109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreateArguments(Node* node) { 285109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode()); 286109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CreateArgumentsType type = CreateArgumentsTypeOf(node->op()); 287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* const frame_state = NodeProperties::GetFrameStateInput(node); 288109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput); 289bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* const control = graph()->start(); 290109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); 291109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Use the ArgumentsAccessStub for materializing both mapped and unmapped 293109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // arguments object, but only for non-inlined (i.e. outermost) frames. 294109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (outer_state->opcode() != IrOpcode::kFrameState) { 295109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch switch (type) { 296109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case CreateArgumentsType::kMappedArguments: { 297109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // TODO(mstarzinger): Duplicate parameters are not handled yet. 298109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<SharedFunctionInfo> shared_info; 299109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!state_info.shared_info().ToHandle(&shared_info) || 300109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch shared_info->has_duplicate_parameters()) { 301109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return NoChange(); 302109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 303109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Callable callable = CodeFactory::FastNewSloppyArguments(isolate()); 304bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operator::Properties properties = node->op()->properties(); 305109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallDescriptor* desc = Linkage::GetStubCallDescriptor( 306109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 307bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CallDescriptor::kNoFlags, properties); 308109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* new_op = common()->Call(desc); 309109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* stub_code = jsgraph()->HeapConstant(callable.code()); 310109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch node->InsertInput(graph()->zone(), 0, stub_code); 311bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch node->RemoveInput(3); // Remove the frame state. 312109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NodeProperties::ChangeOp(node, new_op); 313109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 314109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 315109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case CreateArgumentsType::kUnmappedArguments: { 316109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Callable callable = CodeFactory::FastNewStrictArguments(isolate()); 317bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operator::Properties properties = node->op()->properties(); 318109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallDescriptor* desc = Linkage::GetStubCallDescriptor( 319109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 32013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CallDescriptor::kNeedsFrameState, properties); 321109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* new_op = common()->Call(desc); 322109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* stub_code = jsgraph()->HeapConstant(callable.code()); 323109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch node->InsertInput(graph()->zone(), 0, stub_code); 324109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NodeProperties::ChangeOp(node, new_op); 325109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 326109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 327109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case CreateArgumentsType::kRestParameter: { 328109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Callable callable = CodeFactory::FastNewRestParameter(isolate()); 329bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operator::Properties properties = node->op()->properties(); 330109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallDescriptor* desc = Linkage::GetStubCallDescriptor( 331109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 33213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CallDescriptor::kNeedsFrameState, properties); 333109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* new_op = common()->Call(desc); 334109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* stub_code = jsgraph()->HeapConstant(callable.code()); 335109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch node->InsertInput(graph()->zone(), 0, stub_code); 336109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NodeProperties::ChangeOp(node, new_op); 337109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 338109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 339109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 340109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch UNREACHABLE(); 341109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (outer_state->opcode() == IrOpcode::kFrameState) { 342109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Use inline allocation for all mapped arguments objects within inlined 343109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // (i.e. non-outermost) frames, independent of the object size. 344109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (type == CreateArgumentsType::kMappedArguments) { 345109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<SharedFunctionInfo> shared; 346109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); 347109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const callee = NodeProperties::GetValueInput(node, 0); 348109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const context = NodeProperties::GetContextInput(node); 349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // TODO(mstarzinger): Duplicate parameters are not handled yet. 351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (shared->has_duplicate_parameters()) return NoChange(); 352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Choose the correct frame state and frame state info depending on 353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // whether there conceptually is an arguments adaptor frame in the call 354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // chain. 355109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const args_state = GetArgumentsFrameState(frame_state); 356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state); 357109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Prepare element backing store to be used by arguments object. 358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool has_aliased_arguments = false; 359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const elements = AllocateAliasedArguments( 360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect, control, args_state, context, shared, &has_aliased_arguments); 361109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect = elements->op()->EffectOutputCount() > 0 ? elements : effect; 362c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Load the arguments object map. 363c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* const arguments_map = jsgraph()->HeapConstant(handle( 364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch has_aliased_arguments ? native_context()->fast_aliased_arguments_map() 365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch : native_context()->sloppy_arguments_map(), 366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate())); 367109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Actually allocate and initialize the arguments object. 368109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 369109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* properties = jsgraph()->EmptyFixedArrayConstant(); 370109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int length = args_state_info.parameter_count() - 1; // Minus receiver. 371109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kPointerSize); 372109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Allocate(JSSloppyArgumentsObject::kSize); 373c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.Store(AccessBuilder::ForMap(), arguments_map); 374109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectProperties(), properties); 375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectElements(), elements); 376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); 377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForArgumentsCallee(), callee); 378109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RelaxControls(node); 379109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 380109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 381109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (type == CreateArgumentsType::kUnmappedArguments) { 382109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Use inline allocation for all unmapped arguments objects within inlined 383109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // (i.e. non-outermost) frames, independent of the object size. 384109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 385109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Choose the correct frame state and frame state info depending on 386109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // whether there conceptually is an arguments adaptor frame in the call 387109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // chain. 388109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const args_state = GetArgumentsFrameState(frame_state); 389109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state); 390109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Prepare element backing store to be used by arguments object. 391109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const elements = AllocateArguments(effect, control, args_state); 392109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect = elements->op()->EffectOutputCount() > 0 ? elements : effect; 393c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Load the arguments object map. 394c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* const arguments_map = jsgraph()->HeapConstant( 395c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch handle(native_context()->strict_arguments_map(), isolate())); 396109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Actually allocate and initialize the arguments object. 397109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 398109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* properties = jsgraph()->EmptyFixedArrayConstant(); 399109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int length = args_state_info.parameter_count() - 1; // Minus receiver. 400109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize); 401109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Allocate(JSStrictArgumentsObject::kSize); 402c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.Store(AccessBuilder::ForMap(), arguments_map); 403109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectProperties(), properties); 404109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectElements(), elements); 405109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); 406109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RelaxControls(node); 407109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 408109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 409109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (type == CreateArgumentsType::kRestParameter) { 410109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<SharedFunctionInfo> shared; 411109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); 412109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int start_index = shared->internal_formal_parameter_count(); 413109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Use inline allocation for all unmapped arguments objects within inlined 414109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // (i.e. non-outermost) frames, independent of the object size. 415109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 416109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Choose the correct frame state and frame state info depending on 417109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // whether there conceptually is an arguments adaptor frame in the call 418109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // chain. 419109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const args_state = GetArgumentsFrameState(frame_state); 420109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state); 421109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Prepare element backing store to be used by the rest array. 422109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const elements = 423109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocateRestArguments(effect, control, args_state, start_index); 424109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect = elements->op()->EffectOutputCount() > 0 ? elements : effect; 425c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Load the JSArray object map. 426c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* const jsarray_map = jsgraph()->HeapConstant(handle( 427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch native_context()->js_array_fast_elements_map_index(), isolate())); 428109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Actually allocate and initialize the jsarray. 429109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 430109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* properties = jsgraph()->EmptyFixedArrayConstant(); 431109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 432109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // -1 to minus receiver 433109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int argument_count = args_state_info.parameter_count() - 1; 434109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int length = std::max(0, argument_count - start_index); 435109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); 436109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Allocate(JSArray::kSize); 437c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.Store(AccessBuilder::ForMap(), jsarray_map); 438109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectProperties(), properties); 439109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectElements(), elements); 440109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), 441109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jsgraph()->Constant(length)); 442109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RelaxControls(node); 443109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 444109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 445109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 446109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 447109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 448109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return NoChange(); 449109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 450109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 451109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceNewArray(Node* node, Node* length, 452109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int capacity, 453109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AllocationSite> site) { 454109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); 455109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 456109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Extract transition and tenuring feedback from the {site} and add 459109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // appropriate code dependencies on the {site} if deoptimization is 460109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // enabled. 461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PretenureFlag pretenure = site->GetPretenureMode(); 462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ElementsKind elements_kind = site->GetElementsKind(); 463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(IsFastElementsKind(elements_kind)); 464bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (NodeProperties::GetType(length)->Max() > 0) { 465bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch elements_kind = GetHoleyElementsKind(elements_kind); 466bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 467109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch dependencies()->AssumeTenuringDecision(site); 468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch dependencies()->AssumeTransitionStable(site); 469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 470c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Retrieve the initial map for the array. 471c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int const array_map_index = Context::ArrayMapIndex(elements_kind); 472c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* js_array_map = jsgraph()->HeapConstant( 473c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch handle(Map::cast(native_context()->get(array_map_index)), isolate())); 474109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 475109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Setup elements and properties. 476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* elements; 477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (capacity == 0) { 478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements = jsgraph()->EmptyFixedArrayConstant(); 479109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements = effect = 481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocateElements(effect, control, elements_kind, capacity, pretenure); 482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* properties = jsgraph()->EmptyFixedArrayConstant(); 484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Perform the allocation of the actual JSArray object. 486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Allocate(JSArray::kSize, pretenure); 488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForMap(), js_array_map); 489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectProperties(), properties); 490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectElements(), elements); 491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length); 492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RelaxControls(node); 493109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 494109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochReduction JSCreateLowering::ReduceNewArrayToStubCall( 498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* node, Handle<AllocationSite> site) { 499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); 500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int const arity = static_cast<int>(p.arity()); 501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ElementsKind elements_kind = site->GetElementsKind(); 503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AllocationSiteOverrideMode override_mode = 504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE) 505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? DISABLE_ALLOCATION_SITES 506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : DONT_OVERRIDE; 507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (arity == 0) { 509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArrayNoArgumentConstructorStub stub(isolate(), elements_kind, 510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch override_mode); 511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor* desc = Linkage::GetStubCallDescriptor( 512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 1, 513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState); 514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); 515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); 516c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(0)); 517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); 518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, common()->Call(desc)); 519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (arity == 1) { 521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AllocationSiteOverrideMode override_mode = 522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE) 523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? DISABLE_ALLOCATION_SITES 524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : DONT_OVERRIDE; 525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsHoleyElementsKind(elements_kind)) { 527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArraySingleArgumentConstructorStub stub(isolate(), elements_kind, 528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch override_mode); 529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor* desc = Linkage::GetStubCallDescriptor( 530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, 531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState); 532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); 533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); 534c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(1)); 535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); 536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, common()->Call(desc)); 537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* control = NodeProperties::GetControlInput(node); 542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* length = NodeProperties::GetValueInput(node, 2); 543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* equal = graph()->NewNode(simplified()->ReferenceEqual(), length, 544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->ZeroConstant()); 545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch = 547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), equal, control); 548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* call_holey; 549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* call_packed; 550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_success_packed; 551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_success_holey; 552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* context = NodeProperties::GetContextInput(node); 553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_equal = graph()->NewNode(common()->IfTrue(), branch); 555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArraySingleArgumentConstructorStub stub(isolate(), elements_kind, 557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch override_mode); 558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor* desc = Linkage::GetStubCallDescriptor( 559f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, 560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState); 561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* inputs[] = {jsgraph()->HeapConstant(stub.GetCode()), 563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InputAt(1), 564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->HeapConstant(site), 565c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->Constant(1), 566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->UndefinedConstant(), 567f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length, 568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch context, 569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_state, 570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch effect, 571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_equal}; 572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch call_holey = 574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Call(desc), arraysize(inputs), inputs); 575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_success_holey = graph()->NewNode(common()->IfSuccess(), call_holey); 576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_not_equal = graph()->NewNode(common()->IfFalse(), branch); 578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Require elements kind to "go holey." 580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArraySingleArgumentConstructorStub stub( 581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), GetHoleyElementsKind(elements_kind), override_mode); 582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor* desc = Linkage::GetStubCallDescriptor( 583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, 584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState); 585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* inputs[] = {jsgraph()->HeapConstant(stub.GetCode()), 587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InputAt(1), 588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->HeapConstant(site), 589c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->Constant(1), 590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->UndefinedConstant(), 591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length, 592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch context, 593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_state, 594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch effect, 595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_not_equal}; 596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch call_packed = 598f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Call(desc), arraysize(inputs), inputs); 599f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_success_packed = graph()->NewNode(common()->IfSuccess(), call_packed); 600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* merge = graph()->NewNode(common()->Merge(2), if_success_holey, 602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_success_packed); 603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), call_holey, 604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch call_packed, merge); 605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* phi = 606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch call_holey, call_packed, merge); 608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, phi, effect_phi, merge); 610f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(arity > 1); 614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArrayNArgumentsConstructorStub stub(isolate()); 615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor* desc = Linkage::GetStubCallDescriptor( 616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), arity + 1, 617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState); 618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); 619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); 620c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity)); 621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); 622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, common()->Call(desc)); 623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 626109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreateArray(Node* node) { 627109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); 628109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); 629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* target = NodeProperties::GetValueInput(node, 0); 630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* new_target = NodeProperties::GetValueInput(node, 1); 631109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(mstarzinger): Array constructor can throw. Hook up exceptional edges. 633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (NodeProperties::IsExceptionalCall(node)) return NoChange(); 634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 635109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // TODO(bmeurer): Optimize the subclassing case. 636109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (target != new_target) return NoChange(); 637109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 638109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Check if we have a feedback {site} on the {node}. 639109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AllocationSite> site = p.site(); 640109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (p.site().is_null()) return NoChange(); 641109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 642109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Attempt to inline calls to the Array constructor for the relevant cases 643109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // where either no arguments are provided, or exactly one unsigned number 644109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // argument is given. 645109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (site->CanInlineCall()) { 646109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (p.arity() == 0) { 647109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* length = jsgraph()->ZeroConstant(); 648109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int capacity = JSArray::kPreallocatedArrayElements; 649109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceNewArray(node, length, capacity, site); 650109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (p.arity() == 1) { 651109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* length = NodeProperties::GetValueInput(node, 2); 652109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Type* length_type = NodeProperties::GetType(length); 653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (length_type->Is(Type::SignedSmall()) && length_type->Min() >= 0 && 654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length_type->Max() <= kElementLoopUnrollLimit && 655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length_type->Min() == length_type->Max()) { 656109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int capacity = static_cast<int>(length_type->Max()); 657109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ReduceNewArray(node, length, capacity, site); 658109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 659109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceNewArrayToStubCall(node, site); 663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 664109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 665bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochReduction JSCreateLowering::ReduceJSCreateClosure(Node* node) { 666bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); 667bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); 668bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<SharedFunctionInfo> shared = p.shared_info(); 669bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 67013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 67113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* control = NodeProperties::GetControlInput(node); 67213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* context = NodeProperties::GetContextInput(node); 673c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int const function_map_index = 67413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Context::FunctionMapIndex(shared->language_mode(), shared->kind()); 675c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* function_map = jsgraph()->HeapConstant( 676c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch handle(Map::cast(native_context()->get(function_map_index)), isolate())); 67713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Note that it is only safe to embed the raw entry point of the compile 67813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // lazy stub into the code, because that stub is immortal and immovable. 679c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* compile_entry = jsgraph()->PointerConstant( 680c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->isolate()->builtins()->CompileLazy()->entry()); 68113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant(); 68213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* empty_literals_array = jsgraph()->EmptyLiteralsArrayConstant(); 68313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* the_hole = jsgraph()->TheHoleConstant(); 68413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* undefined = jsgraph()->UndefinedConstant(); 68513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AllocationBuilder a(jsgraph(), effect, control); 68613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch STATIC_ASSERT(JSFunction::kSize == 9 * kPointerSize); 68713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Allocate(JSFunction::kSize, p.pretenure()); 68813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForMap(), function_map); 68913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForJSObjectProperties(), empty_fixed_array); 69013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForJSObjectElements(), empty_fixed_array); 69113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForJSFunctionLiterals(), empty_literals_array); 69213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(), the_hole); 69313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForJSFunctionSharedFunctionInfo(), shared); 69413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForJSFunctionContext(), context); 69513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForJSFunctionCodeEntry(), compile_entry); 69613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.Store(AccessBuilder::ForJSFunctionNextFunctionLink(), undefined); 69713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelaxControls(node); 69813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch a.FinishAndChange(node); 69913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(node); 700bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 701bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 702109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) { 703109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode()); 704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* value = NodeProperties::GetValueInput(node, 0); 705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* done = NodeProperties::GetValueInput(node, 1); 706109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 708c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* iterator_result_map = jsgraph()->HeapConstant( 709c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch handle(native_context()->iterator_result_map(), isolate())); 710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Emit code to allocate the JSIteratorResult instance. 712109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, graph()->start()); 713109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Allocate(JSIteratorResult::kSize); 714109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForMap(), iterator_result_map); 715109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectProperties(), 716109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jsgraph()->EmptyFixedArrayConstant()); 717109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSObjectElements(), 718109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jsgraph()->EmptyFixedArrayConstant()); 719109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSIteratorResultValue(), value); 720109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForJSIteratorResultDone(), done); 721109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 722109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 723109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 724109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 725109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 726c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSCreateLowering::ReduceJSCreateKeyValueArray(Node* node) { 727c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(IrOpcode::kJSCreateKeyValueArray, node->opcode()); 728c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* key = NodeProperties::GetValueInput(node, 0); 729c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* value = NodeProperties::GetValueInput(node, 1); 730c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 731c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 732c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* array_map = jsgraph()->HeapConstant( 733c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch handle(native_context()->js_array_fast_elements_map_index())); 734c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* properties = jsgraph()->EmptyFixedArrayConstant(); 735c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* length = jsgraph()->Constant(2); 736c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 737c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AllocationBuilder aa(jsgraph(), effect, graph()->start()); 738c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch aa.AllocateArray(2, factory()->fixed_array_map()); 739c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch aa.Store(AccessBuilder::ForFixedArrayElement(FAST_ELEMENTS), 740c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->Constant(0), key); 741c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch aa.Store(AccessBuilder::ForFixedArrayElement(FAST_ELEMENTS), 742c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->Constant(1), value); 743c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* elements = aa.Finish(); 744c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AllocationBuilder a(jsgraph(), elements, graph()->start()); 746c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.Allocate(JSArray::kSize); 747c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.Store(AccessBuilder::ForMap(), array_map); 748c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.Store(AccessBuilder::ForJSObjectProperties(), properties); 749c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.Store(AccessBuilder::ForJSObjectElements(), elements); 750c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.Store(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), length); 751c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); 752c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch a.FinishAndChange(node); 753c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Changed(node); 754c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 755c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 756109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreateLiteral(Node* node) { 757109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray || 758109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch node->opcode() == IrOpcode::kJSCreateLiteralObject); 759109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); 760109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 761109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 762109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 763109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<LiteralsArray> literals_array; 764109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (GetSpecializationLiterals(node).ToHandle(&literals_array)) { 765109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> literal(literals_array->literal(p.index()), isolate()); 766109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (literal->IsAllocationSite()) { 767109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AllocationSite> site = Handle<AllocationSite>::cast(literal); 768109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()), 769109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate()); 770109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int max_properties = kMaxFastLiteralProperties; 771109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { 772109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationSiteUsageContext site_context(isolate(), site, false); 773109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch site_context.EnterNewScope(); 774109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* value = effect = 775109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocateFastLiteral(effect, control, boilerplate, &site_context); 776109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch site_context.ExitScope(site, boilerplate); 777109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ReplaceWithValue(node, value, effect, control); 778109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Replace(value); 779109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 780109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 781109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 782109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 783109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return NoChange(); 784109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 785109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 786109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) { 787109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode()); 788109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int slot_count = OpParameter<int>(node->op()); 789109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const closure = NodeProperties::GetValueInput(node, 0); 790109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 791109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Use inline allocation for function contexts up to a size limit. 792109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (slot_count < kFunctionContextAllocationLimit) { 793109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // JSCreateFunctionContext[slot_count < limit]](fun) 794109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 795109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 796109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 797109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* extension = jsgraph()->TheHoleConstant(); 798109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 799109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. 800109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int context_length = slot_count + Context::MIN_CONTEXT_SLOTS; 801109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.AllocateArray(context_length, factory()->function_context_map()); 802109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); 803109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); 804109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); 805109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX), 806c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->HeapConstant(native_context())); 807109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { 808109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant()); 809109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 810109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RelaxControls(node); 811109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 812109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 813109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 814109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 815109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return NoChange(); 816109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 817109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 818109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreateWithContext(Node* node) { 819109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode()); 820f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node); 821109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* object = NodeProperties::GetValueInput(node, 0); 822109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* closure = NodeProperties::GetValueInput(node, 1); 823109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 824109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 825109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AllocationBuilder aa(jsgraph(), effect, control); 828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch aa.Allocate(ContextExtension::kSize); 829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch aa.Store(AccessBuilder::ForMap(), factory()->context_extension_map()); 830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch aa.Store(AccessBuilder::ForContextExtensionScopeInfo(), scope_info); 831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch aa.Store(AccessBuilder::ForContextExtensionExtension(), object); 832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* extension = aa.Finish(); 833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AllocationBuilder a(jsgraph(), extension, control); 835109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. 836109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); 837109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); 838109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); 839f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); 840109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX), 841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->HeapConstant(native_context())); 842109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RelaxControls(node); 843109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 844109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 845109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 846109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 847109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreateCatchContext(Node* node) { 848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateCatchContext, node->opcode()); 849f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const CreateCatchContextParameters& parameters = 850f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CreateCatchContextParametersOf(node->op()); 851109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* exception = NodeProperties::GetValueInput(node, 0); 852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* closure = NodeProperties::GetValueInput(node, 1); 853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 854109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 855109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 856f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 857f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AllocationBuilder aa(jsgraph(), effect, control); 858f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch aa.Allocate(ContextExtension::kSize); 859f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch aa.Store(AccessBuilder::ForMap(), factory()->context_extension_map()); 860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch aa.Store(AccessBuilder::ForContextExtensionScopeInfo(), 861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch parameters.scope_info()); 862f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch aa.Store(AccessBuilder::ForContextExtensionExtension(), 863f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch parameters.catch_name()); 864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* extension = aa.Finish(); 865f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AllocationBuilder a(jsgraph(), extension, control); 867109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. 868109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.AllocateArray(Context::MIN_CONTEXT_SLOTS + 1, 869109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch factory()->catch_context_map()); 870109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); 871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); 872f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); 873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX), 874c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->HeapConstant(native_context())); 875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::THROWN_OBJECT_INDEX), 876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch exception); 877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RelaxControls(node); 878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochReduction JSCreateLowering::ReduceJSCreateBlockContext(Node* node) { 883109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode()); 884109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node); 885109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int const context_length = scope_info->ContextLength(); 886109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const closure = NodeProperties::GetValueInput(node, 0); 887109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 888109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Use inline allocation for block contexts up to a size limit. 889109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (context_length < kBlockContextAllocationLimit) { 890109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // JSCreateBlockContext[scope[length < limit]](fun) 891109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 892109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 893109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 894109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* extension = jsgraph()->Constant(scope_info); 895c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 896109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 897109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. 898109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.AllocateArray(context_length, factory()->block_context_map()); 899109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); 900109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); 901109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension); 902109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX), 903c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->HeapConstant(native_context())); 904109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { 905109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant()); 906109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 907109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RelaxControls(node); 908109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.FinishAndChange(node); 909109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Changed(node); 910109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 911109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 912109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return NoChange(); 913109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 914109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 915109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Helper that allocates a FixedArray holding argument values recorded in the 916109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// given {frame_state}. Serves as backing store for JSCreateArguments nodes. 917109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* JSCreateLowering::AllocateArguments(Node* effect, Node* control, 918109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* frame_state) { 919109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); 920109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int argument_count = state_info.parameter_count() - 1; // Minus receiver. 921109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant(); 922109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 923109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Prepare an iterator over argument values recorded in the frame state. 924109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const parameters = frame_state->InputAt(kFrameStateParametersInput); 925109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch StateValuesAccess parameters_access(parameters); 926109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch auto parameters_it = ++parameters_access.begin(); 927109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 928109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Actually allocate the backing store. 929109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 930109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.AllocateArray(argument_count, factory()->fixed_array_map()); 931109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < argument_count; ++i, ++parameters_it) { 932109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForFixedArraySlot(i), (*parameters_it).node); 933109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 934109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return a.Finish(); 935109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 936109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 937109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Helper that allocates a FixedArray holding argument values recorded in the 938109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// given {frame_state}. Serves as backing store for JSCreateArguments nodes. 939109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* JSCreateLowering::AllocateRestArguments(Node* effect, Node* control, 940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* frame_state, 941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int start_index) { 942109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); 943109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int argument_count = state_info.parameter_count() - 1; // Minus receiver. 944109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int num_elements = std::max(0, argument_count - start_index); 945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (num_elements == 0) return jsgraph()->EmptyFixedArrayConstant(); 946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 947109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Prepare an iterator over argument values recorded in the frame state. 948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const parameters = frame_state->InputAt(kFrameStateParametersInput); 949109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch StateValuesAccess parameters_access(parameters); 950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch auto parameters_it = ++parameters_access.begin(); 951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 952109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Skip unused arguments. 953109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < start_index; i++) { 954109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ++parameters_it; 955109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 956109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 957109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Actually allocate the backing store. 958109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 959109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.AllocateArray(num_elements, factory()->fixed_array_map()); 960109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < num_elements; ++i, ++parameters_it) { 961109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForFixedArraySlot(i), (*parameters_it).node); 962109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 963109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return a.Finish(); 964109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 965109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 966109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Helper that allocates a FixedArray serving as a parameter map for values 967109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// recorded in the given {frame_state}. Some elements map to slots within the 968109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// given {context}. Serves as backing store for JSCreateArguments nodes. 969109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* JSCreateLowering::AllocateAliasedArguments( 970109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect, Node* control, Node* frame_state, Node* context, 971109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<SharedFunctionInfo> shared, bool* has_aliased_arguments) { 972109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); 973109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int argument_count = state_info.parameter_count() - 1; // Minus receiver. 974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant(); 975109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 976109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // If there is no aliasing, the arguments object elements are not special in 977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // any way, we can just return an unmapped backing store instead. 978109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int parameter_count = shared->internal_formal_parameter_count(); 979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (parameter_count == 0) { 980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return AllocateArguments(effect, control, frame_state); 981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Calculate number of argument values being aliased/mapped. 984109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int mapped_count = Min(argument_count, parameter_count); 985109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch *has_aliased_arguments = true; 986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Prepare an iterator over argument values recorded in the frame state. 988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const parameters = frame_state->InputAt(kFrameStateParametersInput); 989109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch StateValuesAccess parameters_access(parameters); 990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch auto paratemers_it = ++parameters_access.begin(); 991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // The unmapped argument values recorded in the frame state are stored yet 993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // another indirection away and then linked into the parameter map below, 994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // whereas mapped argument values are replaced with a hole instead. 995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder aa(jsgraph(), effect, control); 996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch aa.AllocateArray(argument_count, factory()->fixed_array_map()); 997109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < mapped_count; ++i, ++paratemers_it) { 998109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch aa.Store(AccessBuilder::ForFixedArraySlot(i), jsgraph()->TheHoleConstant()); 999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = mapped_count; i < argument_count; ++i, ++paratemers_it) { 1001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch aa.Store(AccessBuilder::ForFixedArraySlot(i), (*paratemers_it).node); 1002109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1003109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* arguments = aa.Finish(); 1004109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1005109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Actually allocate the backing store. 1006109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), arguments, control); 1007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.AllocateArray(mapped_count + 2, factory()->sloppy_arguments_elements_map()); 1008109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForFixedArraySlot(0), context); 1009109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForFixedArraySlot(1), arguments); 1010109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < mapped_count; ++i) { 1011109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 - i; 1012109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(AccessBuilder::ForFixedArraySlot(i + 2), jsgraph()->Constant(idx)); 1013109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1014109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return a.Finish(); 1015109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1016109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1017109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* JSCreateLowering::AllocateElements(Node* effect, Node* control, 1018109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ElementsKind elements_kind, 1019109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int capacity, 1020109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PretenureFlag pretenure) { 1021109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_LE(1, capacity); 1022109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray); 1023109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1024109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Map> elements_map = IsFastDoubleElementsKind(elements_kind) 1025109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ? factory()->fixed_double_array_map() 1026109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : factory()->fixed_array_map(); 1027109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ElementAccess access = IsFastDoubleElementsKind(elements_kind) 1028109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ? AccessBuilder::ForFixedDoubleArrayElement() 1029109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : AccessBuilder::ForFixedArrayElement(); 1030f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* value; 1031f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (IsFastDoubleElementsKind(elements_kind)) { 1032f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Load the hole NaN pattern from the canonical location. 1033f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch value = effect = graph()->NewNode( 1034f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForExternalDoubleValue()), 1035f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->ExternalConstant( 1036f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ExternalReference::address_of_the_hole_nan()), 1037f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 1038f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else { 1039f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch value = jsgraph()->TheHoleConstant(); 1040f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1041109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1042109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Actually allocate the backing store. 1043109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder a(jsgraph(), effect, control); 1044109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.AllocateArray(capacity, elements_map, pretenure); 1045109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < capacity; ++i) { 1046109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* index = jsgraph()->Constant(i); 1047109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch a.Store(access, index, value); 1048109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1049109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return a.Finish(); 1050109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1051109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1052109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* JSCreateLowering::AllocateFastLiteral( 1053109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect, Node* control, Handle<JSObject> boilerplate, 1054109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationSiteUsageContext* site_context) { 1055109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AllocationSite> current_site(*site_context->current(), isolate()); 1056109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch dependencies()->AssumeTransitionStable(current_site); 1057109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1058109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PretenureFlag pretenure = NOT_TENURED; 1059109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (FLAG_allocation_site_pretenuring) { 1060109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AllocationSite> top_site(*site_context->top(), isolate()); 1061109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch pretenure = top_site->GetPretenureMode(); 1062109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (current_site.is_identical_to(top_site)) { 1063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // We install a dependency for pretenuring only on the outermost literal. 1064109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch dependencies()->AssumeTenuringDecision(top_site); 1065109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1066109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1067109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1068109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Setup the properties backing store. 1069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* properties = jsgraph()->EmptyFixedArrayConstant(); 1070109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1071109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Setup the elements backing store. 1072109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* elements = AllocateFastLiteralElements(effect, control, boilerplate, 1073109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch pretenure, site_context); 1074109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (elements->op()->EffectOutputCount() > 0) effect = elements; 1075109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1076109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Compute the in-object properties to store first (might have effects). 1077109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Map> boilerplate_map(boilerplate->map(), isolate()); 1078109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone()); 1079109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inobject_fields.reserve(boilerplate_map->GetInObjectProperties()); 1080109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int const boilerplate_nof = boilerplate_map->NumberOfOwnDescriptors(); 1081109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < boilerplate_nof; ++i) { 1082109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PropertyDetails const property_details = 1083109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch boilerplate_map->instance_descriptors()->GetDetails(i); 1084109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (property_details.type() != DATA) continue; 1085109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Name> property_name( 1086109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch boilerplate_map->instance_descriptors()->GetKey(i), isolate()); 1087109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldIndex index = FieldIndex::ForDescriptor(*boilerplate_map, i); 1088bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FieldAccess access = { 1089f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch kTaggedBase, index.offset(), property_name, 1090f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier}; 1091109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* value; 1092109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (boilerplate->IsUnboxedDoubleField(index)) { 1093109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch access.machine_type = MachineType::Float64(); 1094109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch access.type = Type::Number(); 1095109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch value = jsgraph()->Constant(boilerplate->RawFastDoublePropertyAt(index)); 1096109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1097109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> boilerplate_value(boilerplate->RawFastPropertyAt(index), 1098109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate()); 1099109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (boilerplate_value->IsJSObject()) { 1100109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> boilerplate_object = 1101109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject>::cast(boilerplate_value); 1102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AllocationSite> current_site = site_context->EnterNewScope(); 1103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch value = effect = AllocateFastLiteral(effect, control, 1104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch boilerplate_object, site_context); 1105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch site_context->ExitScope(current_site, boilerplate_object); 1106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (property_details.representation().IsDouble()) { 1107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Allocate a mutable HeapNumber box and store the value into it. 110813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode( 110913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch common()->BeginRegion(RegionObservability::kNotObservable), effect); 11103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch value = effect = graph()->NewNode( 1111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->Allocate(pretenure), 1112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch jsgraph()->Constant(HeapNumber::kSize), effect, control); 1113bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch effect = graph()->NewNode( 1114bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch simplified()->StoreField(AccessBuilder::ForMap()), value, 1115bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch jsgraph()->HeapConstant(factory()->mutable_heap_number_map()), 1116bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch effect, control); 11173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch effect = graph()->NewNode( 11183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), 11193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch value, jsgraph()->Constant( 11203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<HeapNumber>::cast(boilerplate_value)->value()), 1121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect, control); 1122bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch value = effect = 1123bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph()->NewNode(common()->FinishRegion(), value, effect); 1124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (property_details.representation().IsSmi()) { 1125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Ensure that value is stored as smi. 112613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch value = boilerplate_value->IsUninitialized(isolate()) 1127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ? jsgraph()->ZeroConstant() 1128109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : jsgraph()->Constant(boilerplate_value); 1129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch value = jsgraph()->Constant(boilerplate_value); 1131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inobject_fields.push_back(std::make_pair(access, value)); 1134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1135109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1136109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Fill slack at the end of the boilerplate object with filler maps. 1137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int const boilerplate_length = boilerplate_map->GetInObjectProperties(); 1138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int index = static_cast<int>(inobject_fields.size()); 1139109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch index < boilerplate_length; ++index) { 1140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldAccess access = 1141109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index); 1142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map()); 1143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inobject_fields.push_back(std::make_pair(access, value)); 1144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Actually allocate and initialize the object. 1147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder builder(jsgraph(), effect, control); 1148c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.Allocate(boilerplate_map->instance_size(), pretenure, 1149c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Type::OtherObject()); 1150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch builder.Store(AccessBuilder::ForMap(), boilerplate_map); 1151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch builder.Store(AccessBuilder::ForJSObjectProperties(), properties); 1152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch builder.Store(AccessBuilder::ForJSObjectElements(), elements); 1153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (boilerplate_map->IsJSArrayMap()) { 1154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSArray> boilerplate_array = Handle<JSArray>::cast(boilerplate); 1155109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch builder.Store( 1156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AccessBuilder::ForJSArrayLength(boilerplate_array->GetElementsKind()), 1157109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch handle(boilerplate_array->length(), isolate())); 1158109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1159109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (auto const inobject_field : inobject_fields) { 1160109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch builder.Store(inobject_field.first, inobject_field.second); 1161109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1162109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return builder.Finish(); 1163109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1164109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1165109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* JSCreateLowering::AllocateFastLiteralElements( 1166109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* effect, Node* control, Handle<JSObject> boilerplate, 1167109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PretenureFlag pretenure, AllocationSiteUsageContext* site_context) { 1168109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArrayBase> boilerplate_elements(boilerplate->elements(), 1169109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate()); 1170109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1171109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Empty or copy-on-write elements just store a constant. 1172109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (boilerplate_elements->length() == 0 || 1173109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch boilerplate_elements->map() == isolate()->heap()->fixed_cow_array_map()) { 1174109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (pretenure == TENURED && 1175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate()->heap()->InNewSpace(*boilerplate_elements)) { 1176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // If we would like to pretenure a fixed cow array, we must ensure that 1177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // the array is already in old space, otherwise we'll create too many 1178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // old-to-new-space pointers (overflowing the store buffer). 1179109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch boilerplate_elements = Handle<FixedArrayBase>( 1180109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate()->factory()->CopyAndTenureFixedCOWArray( 1181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArray>::cast(boilerplate_elements))); 1182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch boilerplate->set_elements(*boilerplate_elements); 1183109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return jsgraph()->HeapConstant(boilerplate_elements); 1185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Compute the elements to store first (might have effects). 1188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int const elements_length = boilerplate_elements->length(); 1189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Map> elements_map(boilerplate_elements->map(), isolate()); 1190109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ZoneVector<Node*> elements_values(elements_length, zone()); 1191109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (elements_map->instance_type() == FIXED_DOUBLE_ARRAY_TYPE) { 1192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedDoubleArray> elements = 1193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedDoubleArray>::cast(boilerplate_elements); 1194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* the_hole_value = nullptr; 1195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < elements_length; ++i) { 1196109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (elements->is_the_hole(i)) { 1197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (the_hole_value == nullptr) { 1198f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Load the hole NaN pattern from the canonical location. 1199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch the_hole_value = effect = graph()->NewNode( 1200f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForExternalDoubleValue()), 1201f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->ExternalConstant( 1202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ExternalReference::address_of_the_hole_nan()), 1203f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 1204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1205f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch elements_values[i] = the_hole_value; 1206109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1207109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements_values[i] = jsgraph()->Constant(elements->get_scalar(i)); 1208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1211109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArray> elements = 1212109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArray>::cast(boilerplate_elements); 1213109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < elements_length; ++i) { 1214c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (elements->is_the_hole(isolate(), i)) { 1215109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements_values[i] = jsgraph()->TheHoleConstant(); 1216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> element_value(elements->get(i), isolate()); 1218109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (element_value->IsJSObject()) { 1219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> boilerplate_object = 1220109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject>::cast(element_value); 1221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AllocationSite> current_site = site_context->EnterNewScope(); 1222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements_values[i] = effect = AllocateFastLiteral( 1223109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch effect, control, boilerplate_object, site_context); 1224109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch site_context->ExitScope(current_site, boilerplate_object); 1225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1226109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements_values[i] = jsgraph()->Constant(element_value); 1227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Allocate the backing store array and store the elements. 1233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllocationBuilder builder(jsgraph(), effect, control); 1234109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch builder.AllocateArray(elements_length, elements_map, pretenure); 1235109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ElementAccess const access = 1236109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch (elements_map->instance_type() == FIXED_DOUBLE_ARRAY_TYPE) 1237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ? AccessBuilder::ForFixedDoubleArrayElement() 1238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : AccessBuilder::ForFixedArrayElement(); 1239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < elements_length; ++i) { 1240109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch builder.Store(access, jsgraph()->Constant(i), elements_values[i]); 1241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return builder.Finish(); 1243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1245109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochMaybeHandle<LiteralsArray> JSCreateLowering::GetSpecializationLiterals( 1246109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* node) { 1247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* const closure = NodeProperties::GetValueInput(node, 0); 1248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch switch (closure->opcode()) { 1249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kHeapConstant: { 1250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<HeapObject> object = OpParameter<Handle<HeapObject>>(closure); 1251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return handle(Handle<JSFunction>::cast(object)->literals()); 1252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case IrOpcode::kParameter: { 1254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int const index = ParameterIndexOf(closure->op()); 1255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // The closure is always the last parameter to a JavaScript function, and 1256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // {Parameter} indices start at -1, so value outputs of {Start} look like 1257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // this: closure, receiver, param0, ..., paramN, context. 1258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (index == -1) { 1259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return literals_array_; 1260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch default: 1264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return MaybeHandle<LiteralsArray>(); 1267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochFactory* JSCreateLowering::factory() const { return isolate()->factory(); } 1270109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1271109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochGraph* JSCreateLowering::graph() const { return jsgraph()->graph(); } 1272109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochIsolate* JSCreateLowering::isolate() const { return jsgraph()->isolate(); } 1274109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1275109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochJSOperatorBuilder* JSCreateLowering::javascript() const { 1276109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return jsgraph()->javascript(); 1277109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1279109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochCommonOperatorBuilder* JSCreateLowering::common() const { 1280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return jsgraph()->common(); 1281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochSimplifiedOperatorBuilder* JSCreateLowering::simplified() const { 1284109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return jsgraph()->simplified(); 1285109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1286109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochMachineOperatorBuilder* JSCreateLowering::machine() const { 1288109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return jsgraph()->machine(); 1289109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1290109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1291109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace compiler 1292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace internal 1293109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace v8 1294