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