1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/js-create-lowering.h"
6
7#include "src/codegen/code-factory.h"
8#include "src/compiler/access-builder.h"
9#include "src/compiler/allocation-builder-inl.h"
10#include "src/compiler/common-operator.h"
11#include "src/compiler/compilation-dependencies.h"
12#include "src/compiler/js-graph.h"
13#include "src/compiler/js-operator.h"
14#include "src/compiler/linkage.h"
15#include "src/compiler/node-matchers.h"
16#include "src/compiler/node-properties.h"
17#include "src/compiler/node.h"
18#include "src/compiler/operator-properties.h"
19#include "src/compiler/simplified-operator.h"
20#include "src/compiler/state-values-utils.h"
21#include "src/execution/protectors.h"
22#include "src/objects/arguments.h"
23#include "src/objects/hash-table-inl.h"
24#include "src/objects/heap-number.h"
25#include "src/objects/js-collection-iterator.h"
26#include "src/objects/js-generator.h"
27#include "src/objects/js-promise.h"
28#include "src/objects/js-regexp-inl.h"
29#include "src/objects/objects-inl.h"
30#include "src/objects/template-objects.h"
31
32namespace v8 {
33namespace internal {
34namespace compiler {
35
36namespace {
37
38// Retrieves the frame state holding actual argument values.
39FrameState GetArgumentsFrameState(FrameState frame_state) {
40  FrameState outer_state{NodeProperties::GetFrameStateInput(frame_state)};
41  return outer_state.frame_state_info().type() ==
42                 FrameStateType::kArgumentsAdaptor
43             ? outer_state
44             : frame_state;
45}
46
47// When initializing arrays, we'll unfold the loop if the number of
48// elements is known to be of this type.
49const int kElementLoopUnrollLimit = 16;
50
51// Limits up to which context allocations are inlined.
52const int kFunctionContextAllocationLimit = 16;
53const int kBlockContextAllocationLimit = 16;
54
55}  // namespace
56
57Reduction JSCreateLowering::Reduce(Node* node) {
58  switch (node->opcode()) {
59    case IrOpcode::kJSCreate:
60      return ReduceJSCreate(node);
61    case IrOpcode::kJSCreateArguments:
62      return ReduceJSCreateArguments(node);
63    case IrOpcode::kJSCreateArray:
64      return ReduceJSCreateArray(node);
65    case IrOpcode::kJSCreateArrayIterator:
66      return ReduceJSCreateArrayIterator(node);
67    case IrOpcode::kJSCreateAsyncFunctionObject:
68      return ReduceJSCreateAsyncFunctionObject(node);
69    case IrOpcode::kJSCreateBoundFunction:
70      return ReduceJSCreateBoundFunction(node);
71    case IrOpcode::kJSCreateClosure:
72      return ReduceJSCreateClosure(node);
73    case IrOpcode::kJSCreateCollectionIterator:
74      return ReduceJSCreateCollectionIterator(node);
75    case IrOpcode::kJSCreateIterResultObject:
76      return ReduceJSCreateIterResultObject(node);
77    case IrOpcode::kJSCreateStringIterator:
78      return ReduceJSCreateStringIterator(node);
79    case IrOpcode::kJSCreateKeyValueArray:
80      return ReduceJSCreateKeyValueArray(node);
81    case IrOpcode::kJSCreatePromise:
82      return ReduceJSCreatePromise(node);
83    case IrOpcode::kJSCreateLiteralArray:
84    case IrOpcode::kJSCreateLiteralObject:
85      return ReduceJSCreateLiteralArrayOrObject(node);
86    case IrOpcode::kJSCreateLiteralRegExp:
87      return ReduceJSCreateLiteralRegExp(node);
88    case IrOpcode::kJSGetTemplateObject:
89      return ReduceJSGetTemplateObject(node);
90    case IrOpcode::kJSCreateEmptyLiteralArray:
91      return ReduceJSCreateEmptyLiteralArray(node);
92    case IrOpcode::kJSCreateEmptyLiteralObject:
93      return ReduceJSCreateEmptyLiteralObject(node);
94    case IrOpcode::kJSCreateFunctionContext:
95      return ReduceJSCreateFunctionContext(node);
96    case IrOpcode::kJSCreateWithContext:
97      return ReduceJSCreateWithContext(node);
98    case IrOpcode::kJSCreateCatchContext:
99      return ReduceJSCreateCatchContext(node);
100    case IrOpcode::kJSCreateBlockContext:
101      return ReduceJSCreateBlockContext(node);
102    case IrOpcode::kJSCreateGeneratorObject:
103      return ReduceJSCreateGeneratorObject(node);
104    case IrOpcode::kJSCreateObject:
105      return ReduceJSCreateObject(node);
106    default:
107      break;
108  }
109  return NoChange();
110}
111
112Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
113  DCHECK_EQ(IrOpcode::kJSCreate, node->opcode());
114  Node* const new_target = NodeProperties::GetValueInput(node, 1);
115  Node* const effect = NodeProperties::GetEffectInput(node);
116  Node* const control = NodeProperties::GetControlInput(node);
117
118  base::Optional<MapRef> initial_map =
119      NodeProperties::GetJSCreateMap(broker(), node);
120  if (!initial_map.has_value()) return NoChange();
121
122  JSFunctionRef original_constructor =
123      HeapObjectMatcher(new_target).Ref(broker()).AsJSFunction();
124  SlackTrackingPrediction slack_tracking_prediction =
125      dependencies()->DependOnInitialMapInstanceSizePrediction(
126          original_constructor);
127
128  // Emit code to allocate the JSObject instance for the
129  // {original_constructor}.
130  AllocationBuilder a(jsgraph(), effect, control);
131  a.Allocate(slack_tracking_prediction.instance_size());
132  a.Store(AccessBuilder::ForMap(), *initial_map);
133  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
134          jsgraph()->EmptyFixedArrayConstant());
135  a.Store(AccessBuilder::ForJSObjectElements(),
136          jsgraph()->EmptyFixedArrayConstant());
137  for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
138       ++i) {
139    a.Store(AccessBuilder::ForJSObjectInObjectProperty(*initial_map, i),
140            jsgraph()->UndefinedConstant());
141  }
142
143  RelaxControls(node);
144  a.FinishAndChange(node);
145  return Changed(node);
146}
147
148Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
149  DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
150  CreateArgumentsType type = CreateArgumentsTypeOf(node->op());
151  FrameState frame_state{NodeProperties::GetFrameStateInput(node)};
152  Node* const control = graph()->start();
153  FrameStateInfo state_info = frame_state.frame_state_info();
154  SharedFunctionInfoRef shared =
155      MakeRef(broker(), state_info.shared_info().ToHandleChecked());
156
157  // Use the ArgumentsAccessStub for materializing both mapped and unmapped
158  // arguments object, but only for non-inlined (i.e. outermost) frames.
159  if (frame_state.outer_frame_state()->opcode() != IrOpcode::kFrameState) {
160    switch (type) {
161      case CreateArgumentsType::kMappedArguments: {
162        // TODO(turbofan): Duplicate parameters are not handled yet.
163        if (shared.has_duplicate_parameters()) return NoChange();
164        Node* const callee = NodeProperties::GetValueInput(node, 0);
165        Node* const context = NodeProperties::GetContextInput(node);
166        Node* effect = NodeProperties::GetEffectInput(node);
167        Node* const arguments_length =
168            graph()->NewNode(simplified()->ArgumentsLength());
169        // Allocate the elements backing store.
170        bool has_aliased_arguments = false;
171        Node* const elements = effect = TryAllocateAliasedArguments(
172            effect, control, context, arguments_length, shared,
173            &has_aliased_arguments);
174        if (elements == nullptr) return NoChange();
175
176        // Load the arguments object map.
177        Node* const arguments_map = jsgraph()->Constant(
178            has_aliased_arguments
179                ? native_context().fast_aliased_arguments_map()
180                : native_context().sloppy_arguments_map());
181        // Actually allocate and initialize the arguments object.
182        AllocationBuilder a(jsgraph(), effect, control);
183        STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kTaggedSize);
184        a.Allocate(JSSloppyArgumentsObject::kSize);
185        a.Store(AccessBuilder::ForMap(), arguments_map);
186        a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
187                jsgraph()->EmptyFixedArrayConstant());
188        a.Store(AccessBuilder::ForJSObjectElements(), elements);
189        a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
190        a.Store(AccessBuilder::ForArgumentsCallee(), callee);
191        RelaxControls(node);
192        a.FinishAndChange(node);
193        return Changed(node);
194      }
195      case CreateArgumentsType::kUnmappedArguments: {
196        Node* effect = NodeProperties::GetEffectInput(node);
197        Node* const arguments_length =
198            graph()->NewNode(simplified()->ArgumentsLength());
199        // Allocate the elements backing store.
200        Node* const elements = effect = graph()->NewNode(
201            simplified()->NewArgumentsElements(
202                CreateArgumentsType::kUnmappedArguments,
203                shared.internal_formal_parameter_count_without_receiver()),
204            arguments_length, effect);
205        // Load the arguments object map.
206        Node* const arguments_map =
207            jsgraph()->Constant(native_context().strict_arguments_map());
208        // Actually allocate and initialize the arguments object.
209        AllocationBuilder a(jsgraph(), effect, control);
210        STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kTaggedSize);
211        a.Allocate(JSStrictArgumentsObject::kSize);
212        a.Store(AccessBuilder::ForMap(), arguments_map);
213        a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
214                jsgraph()->EmptyFixedArrayConstant());
215        a.Store(AccessBuilder::ForJSObjectElements(), elements);
216        a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
217        RelaxControls(node);
218        a.FinishAndChange(node);
219        return Changed(node);
220      }
221      case CreateArgumentsType::kRestParameter: {
222        Node* effect = NodeProperties::GetEffectInput(node);
223        Node* const arguments_length =
224            graph()->NewNode(simplified()->ArgumentsLength());
225        Node* const rest_length = graph()->NewNode(simplified()->RestLength(
226            shared.internal_formal_parameter_count_without_receiver()));
227        // Allocate the elements backing store.
228        Node* const elements = effect = graph()->NewNode(
229            simplified()->NewArgumentsElements(
230                CreateArgumentsType::kRestParameter,
231                shared.internal_formal_parameter_count_without_receiver()),
232            arguments_length, effect);
233        // Load the JSArray object map.
234        Node* const jsarray_map = jsgraph()->Constant(
235            native_context().js_array_packed_elements_map());
236        // Actually allocate and initialize the jsarray.
237        AllocationBuilder a(jsgraph(), effect, control);
238        STATIC_ASSERT(JSArray::kHeaderSize == 4 * kTaggedSize);
239        a.Allocate(JSArray::kHeaderSize);
240        a.Store(AccessBuilder::ForMap(), jsarray_map);
241        a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
242                jsgraph()->EmptyFixedArrayConstant());
243        a.Store(AccessBuilder::ForJSObjectElements(), elements);
244        a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), rest_length);
245        RelaxControls(node);
246        a.FinishAndChange(node);
247        return Changed(node);
248      }
249    }
250    UNREACHABLE();
251  }
252  // Use inline allocation for all mapped arguments objects within inlined
253  // (i.e. non-outermost) frames, independent of the object size.
254  DCHECK_EQ(frame_state.outer_frame_state()->opcode(), IrOpcode::kFrameState);
255  switch (type) {
256    case CreateArgumentsType::kMappedArguments: {
257      Node* const callee = NodeProperties::GetValueInput(node, 0);
258      Node* const context = NodeProperties::GetContextInput(node);
259      Node* effect = NodeProperties::GetEffectInput(node);
260      // TODO(turbofan): Duplicate parameters are not handled yet.
261      if (shared.has_duplicate_parameters()) return NoChange();
262      // Choose the correct frame state and frame state info depending on
263      // whether there conceptually is an arguments adaptor frame in the call
264      // chain.
265      FrameState args_state = GetArgumentsFrameState(frame_state);
266      if (args_state.parameters()->opcode() == IrOpcode::kDeadValue) {
267        // This protects against an incompletely propagated DeadValue node.
268        // If the FrameState has a DeadValue input, then this node will be
269        // pruned anyway.
270        return NoChange();
271      }
272      FrameStateInfo args_state_info = args_state.frame_state_info();
273      int length = args_state_info.parameter_count() - 1;  // Minus receiver.
274      // Prepare element backing store to be used by arguments object.
275      bool has_aliased_arguments = false;
276      Node* const elements = TryAllocateAliasedArguments(
277          effect, control, args_state, context, shared, &has_aliased_arguments);
278      if (elements == nullptr) return NoChange();
279      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
280      // Load the arguments object map.
281      Node* const arguments_map = jsgraph()->Constant(
282          has_aliased_arguments ? native_context().fast_aliased_arguments_map()
283                                : native_context().sloppy_arguments_map());
284      // Actually allocate and initialize the arguments object.
285      AllocationBuilder a(jsgraph(), effect, control);
286      STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kTaggedSize);
287      a.Allocate(JSSloppyArgumentsObject::kSize);
288      a.Store(AccessBuilder::ForMap(), arguments_map);
289      a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
290              jsgraph()->EmptyFixedArrayConstant());
291      a.Store(AccessBuilder::ForJSObjectElements(), elements);
292      a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
293      a.Store(AccessBuilder::ForArgumentsCallee(), callee);
294      RelaxControls(node);
295      a.FinishAndChange(node);
296      return Changed(node);
297    }
298    case CreateArgumentsType::kUnmappedArguments: {
299      // Use inline allocation for all unmapped arguments objects within inlined
300      // (i.e. non-outermost) frames, independent of the object size.
301      Node* effect = NodeProperties::GetEffectInput(node);
302      // Choose the correct frame state and frame state info depending on
303      // whether there conceptually is an arguments adaptor frame in the call
304      // chain.
305      FrameState args_state = GetArgumentsFrameState(frame_state);
306      if (args_state.parameters()->opcode() == IrOpcode::kDeadValue) {
307        // This protects against an incompletely propagated DeadValue node.
308        // If the FrameState has a DeadValue input, then this node will be
309        // pruned anyway.
310        return NoChange();
311      }
312      FrameStateInfo args_state_info = args_state.frame_state_info();
313      int length = args_state_info.parameter_count() - 1;  // Minus receiver.
314      // Prepare element backing store to be used by arguments object.
315      Node* const elements = TryAllocateArguments(effect, control, args_state);
316      if (elements == nullptr) return NoChange();
317      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
318      // Load the arguments object map.
319      Node* const arguments_map =
320          jsgraph()->Constant(native_context().strict_arguments_map());
321      // Actually allocate and initialize the arguments object.
322      AllocationBuilder a(jsgraph(), effect, control);
323      STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kTaggedSize);
324      a.Allocate(JSStrictArgumentsObject::kSize);
325      a.Store(AccessBuilder::ForMap(), arguments_map);
326      a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
327              jsgraph()->EmptyFixedArrayConstant());
328      a.Store(AccessBuilder::ForJSObjectElements(), elements);
329      a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
330      RelaxControls(node);
331      a.FinishAndChange(node);
332      return Changed(node);
333    }
334    case CreateArgumentsType::kRestParameter: {
335      int start_index =
336          shared.internal_formal_parameter_count_without_receiver();
337      // Use inline allocation for all unmapped arguments objects within inlined
338      // (i.e. non-outermost) frames, independent of the object size.
339      Node* effect = NodeProperties::GetEffectInput(node);
340      // Choose the correct frame state and frame state info depending on
341      // whether there conceptually is an arguments adaptor frame in the call
342      // chain.
343      FrameState args_state = GetArgumentsFrameState(frame_state);
344      if (args_state.parameters()->opcode() == IrOpcode::kDeadValue) {
345        // This protects against an incompletely propagated DeadValue node.
346        // If the FrameState has a DeadValue input, then this node will be
347        // pruned anyway.
348        return NoChange();
349      }
350      FrameStateInfo args_state_info = args_state.frame_state_info();
351      // Prepare element backing store to be used by the rest array.
352      Node* const elements =
353          TryAllocateRestArguments(effect, control, args_state, start_index);
354      if (elements == nullptr) return NoChange();
355      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
356      // Load the JSArray object map.
357      Node* const jsarray_map =
358          jsgraph()->Constant(native_context().js_array_packed_elements_map());
359      // Actually allocate and initialize the jsarray.
360      AllocationBuilder a(jsgraph(), effect, control);
361
362      // -1 to minus receiver
363      int argument_count = args_state_info.parameter_count() - 1;
364      int length = std::max(0, argument_count - start_index);
365      STATIC_ASSERT(JSArray::kHeaderSize == 4 * kTaggedSize);
366      a.Allocate(JSArray::kHeaderSize);
367      a.Store(AccessBuilder::ForMap(), jsarray_map);
368      a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
369              jsgraph()->EmptyFixedArrayConstant());
370      a.Store(AccessBuilder::ForJSObjectElements(), elements);
371      a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS),
372              jsgraph()->Constant(length));
373      RelaxControls(node);
374      a.FinishAndChange(node);
375      return Changed(node);
376    }
377  }
378  UNREACHABLE();
379}
380
381Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
382  DCHECK_EQ(IrOpcode::kJSCreateGeneratorObject, node->opcode());
383  Node* const closure = NodeProperties::GetValueInput(node, 0);
384  Node* const receiver = NodeProperties::GetValueInput(node, 1);
385  Node* const context = NodeProperties::GetContextInput(node);
386  Type const closure_type = NodeProperties::GetType(closure);
387  Node* effect = NodeProperties::GetEffectInput(node);
388  Node* const control = NodeProperties::GetControlInput(node);
389  if (closure_type.IsHeapConstant()) {
390    DCHECK(closure_type.AsHeapConstant()->Ref().IsJSFunction());
391    JSFunctionRef js_function =
392        closure_type.AsHeapConstant()->Ref().AsJSFunction();
393    if (!js_function.has_initial_map(dependencies())) return NoChange();
394
395    SlackTrackingPrediction slack_tracking_prediction =
396        dependencies()->DependOnInitialMapInstanceSizePrediction(js_function);
397
398    MapRef initial_map = js_function.initial_map(dependencies());
399    DCHECK(initial_map.instance_type() == JS_GENERATOR_OBJECT_TYPE ||
400           initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
401
402    // Allocate a register file.
403    SharedFunctionInfoRef shared = js_function.shared();
404    DCHECK(shared.HasBytecodeArray());
405    int parameter_count_no_receiver =
406        shared.internal_formal_parameter_count_without_receiver();
407    int length = parameter_count_no_receiver +
408                 shared.GetBytecodeArray().register_count();
409    MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
410    AllocationBuilder ab(jsgraph(), effect, control);
411    if (!ab.CanAllocateArray(length, fixed_array_map)) {
412      return NoChange();
413    }
414    ab.AllocateArray(length, fixed_array_map);
415    for (int i = 0; i < length; ++i) {
416      ab.Store(AccessBuilder::ForFixedArraySlot(i),
417               jsgraph()->UndefinedConstant());
418    }
419    Node* parameters_and_registers = effect = ab.Finish();
420
421    // Emit code to allocate the JS[Async]GeneratorObject instance.
422    AllocationBuilder a(jsgraph(), effect, control);
423    a.Allocate(slack_tracking_prediction.instance_size());
424    Node* undefined = jsgraph()->UndefinedConstant();
425    a.Store(AccessBuilder::ForMap(), initial_map);
426    a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
427            jsgraph()->EmptyFixedArrayConstant());
428    a.Store(AccessBuilder::ForJSObjectElements(),
429            jsgraph()->EmptyFixedArrayConstant());
430    a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
431    a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
432    a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
433    a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(), undefined);
434    a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
435            jsgraph()->Constant(JSGeneratorObject::kNext));
436    a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
437            jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
438    a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
439            parameters_and_registers);
440
441    if (initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE) {
442      a.Store(AccessBuilder::ForJSAsyncGeneratorObjectQueue(), undefined);
443      a.Store(AccessBuilder::ForJSAsyncGeneratorObjectIsAwaiting(),
444              jsgraph()->ZeroConstant());
445    }
446
447    // Handle in-object properties, too.
448    for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
449         ++i) {
450      a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
451              undefined);
452    }
453    a.FinishAndChange(node);
454    return Changed(node);
455  }
456  return NoChange();
457}
458
459// Constructs an array with a variable {length} when no upper bound
460// is known for the capacity.
461Reduction JSCreateLowering::ReduceNewArray(
462    Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind,
463    AllocationType allocation,
464    const SlackTrackingPrediction& slack_tracking_prediction) {
465  DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
466  Node* effect = NodeProperties::GetEffectInput(node);
467  Node* control = NodeProperties::GetControlInput(node);
468
469  // Constructing an Array via new Array(N) where N is an unsigned
470  // integer, always creates a holey backing store.
471  base::Optional<MapRef> maybe_initial_map =
472      initial_map.AsElementsKind(GetHoleyElementsKind(elements_kind));
473  if (!maybe_initial_map.has_value()) return NoChange();
474  initial_map = maybe_initial_map.value();
475
476  // Because CheckBounds performs implicit conversion from string to number, an
477  // additional CheckNumber is required to behave correctly for calls with a
478  // single string argument.
479  length = effect = graph()->NewNode(
480      simplified()->CheckNumber(FeedbackSource{}), length, effect, control);
481
482  // Check that the {limit} is an unsigned integer in the valid range.
483  // This has to be kept in sync with src/runtime/runtime-array.cc,
484  // where this limit is protected.
485  length = effect = graph()->NewNode(
486      simplified()->CheckBounds(FeedbackSource()), length,
487      jsgraph()->Constant(JSArray::kInitialMaxFastElementArray), effect,
488      control);
489
490  // Construct elements and properties for the resulting JSArray.
491  Node* elements = effect =
492      graph()->NewNode(IsDoubleElementsKind(initial_map.elements_kind())
493                           ? simplified()->NewDoubleElements(allocation)
494                           : simplified()->NewSmiOrObjectElements(allocation),
495                       length, effect, control);
496
497  // Perform the allocation of the actual JSArray object.
498  AllocationBuilder a(jsgraph(), effect, control);
499  a.Allocate(slack_tracking_prediction.instance_size(), allocation);
500  a.Store(AccessBuilder::ForMap(), initial_map);
501  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
502          jsgraph()->EmptyFixedArrayConstant());
503  a.Store(AccessBuilder::ForJSObjectElements(), elements);
504  a.Store(AccessBuilder::ForJSArrayLength(initial_map.elements_kind()), length);
505  for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
506       ++i) {
507    a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
508            jsgraph()->UndefinedConstant());
509  }
510  RelaxControls(node);
511  a.FinishAndChange(node);
512  return Changed(node);
513}
514
515// Constructs an array with a variable {length} when an actual
516// upper bound is known for the {capacity}.
517Reduction JSCreateLowering::ReduceNewArray(
518    Node* node, Node* length, int capacity, MapRef initial_map,
519    ElementsKind elements_kind, AllocationType allocation,
520    const SlackTrackingPrediction& slack_tracking_prediction) {
521  DCHECK(node->opcode() == IrOpcode::kJSCreateArray ||
522         node->opcode() == IrOpcode::kJSCreateEmptyLiteralArray);
523  DCHECK(NodeProperties::GetType(length).Is(Type::Number()));
524  Node* effect = NodeProperties::GetEffectInput(node);
525  Node* control = NodeProperties::GetControlInput(node);
526
527  // Determine the appropriate elements kind.
528  if (NodeProperties::GetType(length).Max() > 0.0) {
529    elements_kind = GetHoleyElementsKind(elements_kind);
530  }
531
532  base::Optional<MapRef> maybe_initial_map =
533      initial_map.AsElementsKind(elements_kind);
534  if (!maybe_initial_map.has_value()) return NoChange();
535  initial_map = maybe_initial_map.value();
536
537  DCHECK(IsFastElementsKind(elements_kind));
538
539  // Setup elements and properties.
540  Node* elements;
541  if (capacity == 0) {
542    elements = jsgraph()->EmptyFixedArrayConstant();
543  } else {
544    elements = effect =
545        AllocateElements(effect, control, elements_kind, capacity, allocation);
546  }
547
548  // Perform the allocation of the actual JSArray object.
549  AllocationBuilder a(jsgraph(), effect, control);
550  a.Allocate(slack_tracking_prediction.instance_size(), allocation);
551  a.Store(AccessBuilder::ForMap(), initial_map);
552  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
553          jsgraph()->EmptyFixedArrayConstant());
554  a.Store(AccessBuilder::ForJSObjectElements(), elements);
555  a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
556  for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
557       ++i) {
558    a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
559            jsgraph()->UndefinedConstant());
560  }
561  RelaxControls(node);
562  a.FinishAndChange(node);
563  return Changed(node);
564}
565
566Reduction JSCreateLowering::ReduceNewArray(
567    Node* node, std::vector<Node*> values, MapRef initial_map,
568    ElementsKind elements_kind, AllocationType allocation,
569    const SlackTrackingPrediction& slack_tracking_prediction) {
570  DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
571  Node* effect = NodeProperties::GetEffectInput(node);
572  Node* control = NodeProperties::GetControlInput(node);
573
574  // Determine the appropriate elements kind.
575  DCHECK(IsFastElementsKind(elements_kind));
576
577  base::Optional<MapRef> maybe_initial_map =
578      initial_map.AsElementsKind(elements_kind);
579  if (!maybe_initial_map.has_value()) return NoChange();
580  initial_map = maybe_initial_map.value();
581
582  // Check {values} based on the {elements_kind}. These checks are guarded
583  // by the {elements_kind} feedback on the {site}, so it's safe to just
584  // deoptimize in this case.
585  if (IsSmiElementsKind(elements_kind)) {
586    for (auto& value : values) {
587      if (!NodeProperties::GetType(value).Is(Type::SignedSmall())) {
588        value = effect = graph()->NewNode(
589            simplified()->CheckSmi(FeedbackSource()), value, effect, control);
590      }
591    }
592  } else if (IsDoubleElementsKind(elements_kind)) {
593    for (auto& value : values) {
594      if (!NodeProperties::GetType(value).Is(Type::Number())) {
595        value = effect =
596            graph()->NewNode(simplified()->CheckNumber(FeedbackSource()), value,
597                             effect, control);
598      }
599      // Make sure we do not store signaling NaNs into double arrays.
600      value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
601    }
602  }
603
604  // Setup elements, properties and length.
605  Node* elements = effect =
606      AllocateElements(effect, control, elements_kind, values, allocation);
607  Node* length = jsgraph()->Constant(static_cast<int>(values.size()));
608
609  // Perform the allocation of the actual JSArray object.
610  AllocationBuilder a(jsgraph(), effect, control);
611  a.Allocate(slack_tracking_prediction.instance_size(), allocation);
612  a.Store(AccessBuilder::ForMap(), initial_map);
613  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
614          jsgraph()->EmptyFixedArrayConstant());
615  a.Store(AccessBuilder::ForJSObjectElements(), elements);
616  a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
617  for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
618       ++i) {
619    a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
620            jsgraph()->UndefinedConstant());
621  }
622  RelaxControls(node);
623  a.FinishAndChange(node);
624  return Changed(node);
625}
626
627Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
628  DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
629  CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
630  int const arity = static_cast<int>(p.arity());
631  base::Optional<AllocationSiteRef> site_ref = p.site(broker());
632  AllocationType allocation = AllocationType::kYoung;
633
634  base::Optional<MapRef> initial_map =
635      NodeProperties::GetJSCreateMap(broker(), node);
636  if (!initial_map.has_value()) return NoChange();
637
638  Node* new_target = NodeProperties::GetValueInput(node, 1);
639  JSFunctionRef original_constructor =
640      HeapObjectMatcher(new_target).Ref(broker()).AsJSFunction();
641  SlackTrackingPrediction slack_tracking_prediction =
642      dependencies()->DependOnInitialMapInstanceSizePrediction(
643          original_constructor);
644
645  // Tells whether we are protected by either the {site} or a
646  // protector cell to do certain speculative optimizations.
647  bool can_inline_call = false;
648
649  // Check if we have a feedback {site} on the {node}.
650  ElementsKind elements_kind = initial_map->elements_kind();
651  if (site_ref) {
652    elements_kind = site_ref->GetElementsKind();
653    can_inline_call = site_ref->CanInlineCall();
654    allocation = dependencies()->DependOnPretenureMode(*site_ref);
655    dependencies()->DependOnElementsKind(*site_ref);
656  } else {
657    PropertyCellRef array_constructor_protector =
658        MakeRef(broker(), factory()->array_constructor_protector());
659    array_constructor_protector.CacheAsProtector();
660    can_inline_call = array_constructor_protector.value().AsSmi() ==
661                      Protectors::kProtectorValid;
662  }
663
664  if (arity == 0) {
665    Node* length = jsgraph()->ZeroConstant();
666    int capacity = JSArray::kPreallocatedArrayElements;
667    return ReduceNewArray(node, length, capacity, *initial_map, elements_kind,
668                          allocation, slack_tracking_prediction);
669  } else if (arity == 1) {
670    Node* length = NodeProperties::GetValueInput(node, 2);
671    Type length_type = NodeProperties::GetType(length);
672    if (!length_type.Maybe(Type::Number())) {
673      // Handle the single argument case, where we know that the value
674      // cannot be a valid Array length.
675      elements_kind = GetMoreGeneralElementsKind(
676          elements_kind, IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS
677                                                            : PACKED_ELEMENTS);
678      return ReduceNewArray(node, std::vector<Node*>{length}, *initial_map,
679                            elements_kind, allocation,
680                            slack_tracking_prediction);
681    }
682    if (length_type.Is(Type::SignedSmall()) && length_type.Min() >= 0 &&
683        length_type.Max() <= kElementLoopUnrollLimit &&
684        length_type.Min() == length_type.Max()) {
685      int capacity = static_cast<int>(length_type.Max());
686      // Replace length with a constant in order to protect against a potential
687      // typer bug leading to length > capacity.
688      length = jsgraph()->Constant(capacity);
689      return ReduceNewArray(node, length, capacity, *initial_map, elements_kind,
690                            allocation, slack_tracking_prediction);
691    }
692    if (length_type.Maybe(Type::UnsignedSmall()) && can_inline_call) {
693      return ReduceNewArray(node, length, *initial_map, elements_kind,
694                            allocation, slack_tracking_prediction);
695    }
696  } else if (arity <= JSArray::kInitialMaxFastElementArray) {
697    // Gather the values to store into the newly created array.
698    bool values_all_smis = true, values_all_numbers = true,
699         values_any_nonnumber = false;
700    std::vector<Node*> values;
701    values.reserve(p.arity());
702    for (int i = 0; i < arity; ++i) {
703      Node* value = NodeProperties::GetValueInput(node, 2 + i);
704      Type value_type = NodeProperties::GetType(value);
705      if (!value_type.Is(Type::SignedSmall())) {
706        values_all_smis = false;
707      }
708      if (!value_type.Is(Type::Number())) {
709        values_all_numbers = false;
710      }
711      if (!value_type.Maybe(Type::Number())) {
712        values_any_nonnumber = true;
713      }
714      values.push_back(value);
715    }
716
717    // Try to figure out the ideal elements kind statically.
718    if (values_all_smis) {
719      // Smis can be stored with any elements kind.
720    } else if (values_all_numbers) {
721      elements_kind = GetMoreGeneralElementsKind(
722          elements_kind, IsHoleyElementsKind(elements_kind)
723                             ? HOLEY_DOUBLE_ELEMENTS
724                             : PACKED_DOUBLE_ELEMENTS);
725    } else if (values_any_nonnumber) {
726      elements_kind = GetMoreGeneralElementsKind(
727          elements_kind, IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS
728                                                            : PACKED_ELEMENTS);
729    } else if (!can_inline_call) {
730      // We have some crazy combination of types for the {values} where
731      // there's no clear decision on the elements kind statically. And
732      // we don't have a protection against deoptimization loops for the
733      // checks that are introduced in the call to ReduceNewArray, so
734      // we cannot inline this invocation of the Array constructor here.
735      return NoChange();
736    }
737    return ReduceNewArray(node, values, *initial_map, elements_kind, allocation,
738                          slack_tracking_prediction);
739  }
740  return NoChange();
741}
742
743Reduction JSCreateLowering::ReduceJSCreateArrayIterator(Node* node) {
744  DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, node->opcode());
745  CreateArrayIteratorParameters const& p =
746      CreateArrayIteratorParametersOf(node->op());
747  Node* iterated_object = NodeProperties::GetValueInput(node, 0);
748  Node* effect = NodeProperties::GetEffectInput(node);
749  Node* control = NodeProperties::GetControlInput(node);
750
751  // Create the JSArrayIterator result.
752  AllocationBuilder a(jsgraph(), effect, control);
753  a.Allocate(JSArrayIterator::kHeaderSize, AllocationType::kYoung,
754             Type::OtherObject());
755  a.Store(AccessBuilder::ForMap(),
756          native_context().initial_array_iterator_map());
757  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
758          jsgraph()->EmptyFixedArrayConstant());
759  a.Store(AccessBuilder::ForJSObjectElements(),
760          jsgraph()->EmptyFixedArrayConstant());
761  a.Store(AccessBuilder::ForJSArrayIteratorIteratedObject(), iterated_object);
762  a.Store(AccessBuilder::ForJSArrayIteratorNextIndex(),
763          jsgraph()->ZeroConstant());
764  a.Store(AccessBuilder::ForJSArrayIteratorKind(),
765          jsgraph()->Constant(static_cast<int>(p.kind())));
766  RelaxControls(node);
767  a.FinishAndChange(node);
768  return Changed(node);
769}
770
771Reduction JSCreateLowering::ReduceJSCreateAsyncFunctionObject(Node* node) {
772  DCHECK_EQ(IrOpcode::kJSCreateAsyncFunctionObject, node->opcode());
773  int const register_count = RegisterCountOf(node->op());
774  Node* closure = NodeProperties::GetValueInput(node, 0);
775  Node* receiver = NodeProperties::GetValueInput(node, 1);
776  Node* promise = NodeProperties::GetValueInput(node, 2);
777  Node* context = NodeProperties::GetContextInput(node);
778  Node* effect = NodeProperties::GetEffectInput(node);
779  Node* control = NodeProperties::GetControlInput(node);
780
781  // Create the register file.
782  MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
783  AllocationBuilder ab(jsgraph(), effect, control);
784  CHECK(ab.CanAllocateArray(register_count, fixed_array_map));
785  ab.AllocateArray(register_count, fixed_array_map);
786  for (int i = 0; i < register_count; ++i) {
787    ab.Store(AccessBuilder::ForFixedArraySlot(i),
788             jsgraph()->UndefinedConstant());
789  }
790  Node* parameters_and_registers = effect = ab.Finish();
791
792  // Create the JSAsyncFunctionObject result.
793  AllocationBuilder a(jsgraph(), effect, control);
794  a.Allocate(JSAsyncFunctionObject::kHeaderSize);
795  a.Store(AccessBuilder::ForMap(),
796          native_context().async_function_object_map());
797  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
798          jsgraph()->EmptyFixedArrayConstant());
799  a.Store(AccessBuilder::ForJSObjectElements(),
800          jsgraph()->EmptyFixedArrayConstant());
801  a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
802  a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
803  a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
804  a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(),
805          jsgraph()->UndefinedConstant());
806  a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
807          jsgraph()->Constant(JSGeneratorObject::kNext));
808  a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
809          jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
810  a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
811          parameters_and_registers);
812  a.Store(AccessBuilder::ForJSAsyncFunctionObjectPromise(), promise);
813  a.FinishAndChange(node);
814  return Changed(node);
815}
816
817namespace {
818
819MapRef MapForCollectionIterationKind(const NativeContextRef& native_context,
820                                     CollectionKind collection_kind,
821                                     IterationKind iteration_kind) {
822  switch (collection_kind) {
823    case CollectionKind::kSet:
824      switch (iteration_kind) {
825        case IterationKind::kKeys:
826          UNREACHABLE();
827        case IterationKind::kValues:
828          return native_context.set_value_iterator_map();
829        case IterationKind::kEntries:
830          return native_context.set_key_value_iterator_map();
831      }
832      break;
833    case CollectionKind::kMap:
834      switch (iteration_kind) {
835        case IterationKind::kKeys:
836          return native_context.map_key_iterator_map();
837        case IterationKind::kValues:
838          return native_context.map_value_iterator_map();
839        case IterationKind::kEntries:
840          return native_context.map_key_value_iterator_map();
841      }
842      break;
843  }
844  UNREACHABLE();
845}
846
847}  // namespace
848
849Reduction JSCreateLowering::ReduceJSCreateCollectionIterator(Node* node) {
850  DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, node->opcode());
851  CreateCollectionIteratorParameters const& p =
852      CreateCollectionIteratorParametersOf(node->op());
853  Node* iterated_object = NodeProperties::GetValueInput(node, 0);
854  Node* effect = NodeProperties::GetEffectInput(node);
855  Node* control = NodeProperties::GetControlInput(node);
856
857  // Load the OrderedHashTable from the {receiver}.
858  Node* table = effect = graph()->NewNode(
859      simplified()->LoadField(AccessBuilder::ForJSCollectionTable()),
860      iterated_object, effect, control);
861
862  // Create the JSCollectionIterator result.
863  AllocationBuilder a(jsgraph(), effect, control);
864  a.Allocate(JSCollectionIterator::kHeaderSize, AllocationType::kYoung,
865             Type::OtherObject());
866  a.Store(AccessBuilder::ForMap(),
867          MapForCollectionIterationKind(native_context(), p.collection_kind(),
868                                        p.iteration_kind()));
869  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
870          jsgraph()->EmptyFixedArrayConstant());
871  a.Store(AccessBuilder::ForJSObjectElements(),
872          jsgraph()->EmptyFixedArrayConstant());
873  a.Store(AccessBuilder::ForJSCollectionIteratorTable(), table);
874  a.Store(AccessBuilder::ForJSCollectionIteratorIndex(),
875          jsgraph()->ZeroConstant());
876  RelaxControls(node);
877  a.FinishAndChange(node);
878  return Changed(node);
879}
880
881Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
882  DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, node->opcode());
883  CreateBoundFunctionParameters const& p =
884      CreateBoundFunctionParametersOf(node->op());
885  int const arity = static_cast<int>(p.arity());
886  MapRef const map = p.map(broker());
887  Node* bound_target_function = NodeProperties::GetValueInput(node, 0);
888  Node* bound_this = NodeProperties::GetValueInput(node, 1);
889  Node* effect = NodeProperties::GetEffectInput(node);
890  Node* control = NodeProperties::GetControlInput(node);
891
892  // Create the [[BoundArguments]] for the result.
893  Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant();
894  if (arity > 0) {
895    MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
896    AllocationBuilder ab(jsgraph(), effect, control);
897    CHECK(ab.CanAllocateArray(arity, fixed_array_map));
898    ab.AllocateArray(arity, fixed_array_map);
899    for (int i = 0; i < arity; ++i) {
900      ab.Store(AccessBuilder::ForFixedArraySlot(i),
901               NodeProperties::GetValueInput(node, 2 + i));
902    }
903    bound_arguments = effect = ab.Finish();
904  }
905
906  // Create the JSBoundFunction result.
907  AllocationBuilder a(jsgraph(), effect, control);
908  a.Allocate(JSBoundFunction::kHeaderSize, AllocationType::kYoung,
909             Type::BoundFunction());
910  a.Store(AccessBuilder::ForMap(), map);
911  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
912          jsgraph()->EmptyFixedArrayConstant());
913  a.Store(AccessBuilder::ForJSObjectElements(),
914          jsgraph()->EmptyFixedArrayConstant());
915  a.Store(AccessBuilder::ForJSBoundFunctionBoundTargetFunction(),
916          bound_target_function);
917  a.Store(AccessBuilder::ForJSBoundFunctionBoundThis(), bound_this);
918  a.Store(AccessBuilder::ForJSBoundFunctionBoundArguments(), bound_arguments);
919  RelaxControls(node);
920  a.FinishAndChange(node);
921  return Changed(node);
922}
923
924Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
925  JSCreateClosureNode n(node);
926  CreateClosureParameters const& p = n.Parameters();
927  SharedFunctionInfoRef shared = p.shared_info(broker());
928  FeedbackCellRef feedback_cell = n.GetFeedbackCellRefChecked(broker());
929  HeapObjectRef code = p.code(broker());
930  Effect effect = n.effect();
931  Control control = n.control();
932  Node* context = n.context();
933
934  // Use inline allocation of closures only for instantiation sites that have
935  // seen more than one instantiation, this simplifies the generated code and
936  // also serves as a heuristic of which allocation sites benefit from it.
937  if (!feedback_cell.map().equals(
938          MakeRef(broker(), factory()->many_closures_cell_map()))) {
939    return NoChange();
940  }
941
942  // Don't inline anything for class constructors.
943  if (IsClassConstructor(shared.kind())) return NoChange();
944
945  MapRef function_map =
946      native_context().GetFunctionMapFromIndex(shared.function_map_index());
947  DCHECK(!function_map.IsInobjectSlackTrackingInProgress());
948  DCHECK(!function_map.is_dictionary_map());
949
950  // TODO(turbofan): We should use the pretenure flag from {p} here,
951  // but currently the heuristic in the parser works against us, as
952  // it marks closures like
953  //
954  //   args[l] = function(...) { ... }
955  //
956  // for old-space allocation, which doesn't always make sense. For
957  // example in case of the bluebird-parallel benchmark, where this
958  // is a core part of the *promisify* logic (see crbug.com/810132).
959  AllocationType allocation = AllocationType::kYoung;
960
961  // Emit code to allocate the JSFunction instance.
962  STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kTaggedSize);
963  AllocationBuilder a(jsgraph(), effect, control);
964  a.Allocate(function_map.instance_size(), allocation,
965             Type::CallableFunction());
966  a.Store(AccessBuilder::ForMap(), function_map);
967  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
968          jsgraph()->EmptyFixedArrayConstant());
969  a.Store(AccessBuilder::ForJSObjectElements(),
970          jsgraph()->EmptyFixedArrayConstant());
971  a.Store(AccessBuilder::ForJSFunctionSharedFunctionInfo(), shared);
972  a.Store(AccessBuilder::ForJSFunctionContext(), context);
973  a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
974  a.Store(AccessBuilder::ForJSFunctionCode(), code);
975  STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kTaggedSize);
976  if (function_map.has_prototype_slot()) {
977    a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
978            jsgraph()->TheHoleConstant());
979    STATIC_ASSERT(JSFunction::kSizeWithPrototype == 8 * kTaggedSize);
980  }
981  for (int i = 0; i < function_map.GetInObjectProperties(); i++) {
982    a.Store(AccessBuilder::ForJSObjectInObjectProperty(function_map, i),
983            jsgraph()->UndefinedConstant());
984  }
985  RelaxControls(node);
986  a.FinishAndChange(node);
987  return Changed(node);
988}
989
990Reduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) {
991  DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
992  Node* value = NodeProperties::GetValueInput(node, 0);
993  Node* done = NodeProperties::GetValueInput(node, 1);
994  Node* effect = NodeProperties::GetEffectInput(node);
995
996  Node* iterator_result_map =
997      jsgraph()->Constant(native_context().iterator_result_map());
998
999  // Emit code to allocate the JSIteratorResult instance.
1000  AllocationBuilder a(jsgraph(), effect, graph()->start());
1001  a.Allocate(JSIteratorResult::kSize);
1002  a.Store(AccessBuilder::ForMap(), iterator_result_map);
1003  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
1004          jsgraph()->EmptyFixedArrayConstant());
1005  a.Store(AccessBuilder::ForJSObjectElements(),
1006          jsgraph()->EmptyFixedArrayConstant());
1007  a.Store(AccessBuilder::ForJSIteratorResultValue(), value);
1008  a.Store(AccessBuilder::ForJSIteratorResultDone(), done);
1009  STATIC_ASSERT(JSIteratorResult::kSize == 5 * kTaggedSize);
1010  a.FinishAndChange(node);
1011  return Changed(node);
1012}
1013
1014Reduction JSCreateLowering::ReduceJSCreateStringIterator(Node* node) {
1015  DCHECK_EQ(IrOpcode::kJSCreateStringIterator, node->opcode());
1016  Node* string = NodeProperties::GetValueInput(node, 0);
1017  Node* effect = NodeProperties::GetEffectInput(node);
1018
1019  Node* map =
1020      jsgraph()->Constant(native_context().initial_string_iterator_map());
1021  // Allocate new iterator and attach the iterator to this string.
1022  AllocationBuilder a(jsgraph(), effect, graph()->start());
1023  a.Allocate(JSStringIterator::kHeaderSize, AllocationType::kYoung,
1024             Type::OtherObject());
1025  a.Store(AccessBuilder::ForMap(), map);
1026  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
1027          jsgraph()->EmptyFixedArrayConstant());
1028  a.Store(AccessBuilder::ForJSObjectElements(),
1029          jsgraph()->EmptyFixedArrayConstant());
1030  a.Store(AccessBuilder::ForJSStringIteratorString(), string);
1031  a.Store(AccessBuilder::ForJSStringIteratorIndex(), jsgraph()->SmiConstant(0));
1032  STATIC_ASSERT(JSIteratorResult::kSize == 5 * kTaggedSize);
1033  a.FinishAndChange(node);
1034  return Changed(node);
1035}
1036
1037Reduction JSCreateLowering::ReduceJSCreateKeyValueArray(Node* node) {
1038  DCHECK_EQ(IrOpcode::kJSCreateKeyValueArray, node->opcode());
1039  Node* key = NodeProperties::GetValueInput(node, 0);
1040  Node* value = NodeProperties::GetValueInput(node, 1);
1041  Node* effect = NodeProperties::GetEffectInput(node);
1042
1043  Node* array_map =
1044      jsgraph()->Constant(native_context().js_array_packed_elements_map());
1045  Node* length = jsgraph()->Constant(2);
1046
1047  AllocationBuilder aa(jsgraph(), effect, graph()->start());
1048  aa.AllocateArray(2, MakeRef(broker(), factory()->fixed_array_map()));
1049  aa.Store(AccessBuilder::ForFixedArrayElement(PACKED_ELEMENTS),
1050           jsgraph()->ZeroConstant(), key);
1051  aa.Store(AccessBuilder::ForFixedArrayElement(PACKED_ELEMENTS),
1052           jsgraph()->OneConstant(), value);
1053  Node* elements = aa.Finish();
1054
1055  AllocationBuilder a(jsgraph(), elements, graph()->start());
1056  a.Allocate(JSArray::kHeaderSize);
1057  a.Store(AccessBuilder::ForMap(), array_map);
1058  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
1059          jsgraph()->EmptyFixedArrayConstant());
1060  a.Store(AccessBuilder::ForJSObjectElements(), elements);
1061  a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), length);
1062  STATIC_ASSERT(JSArray::kHeaderSize == 4 * kTaggedSize);
1063  a.FinishAndChange(node);
1064  return Changed(node);
1065}
1066
1067Reduction JSCreateLowering::ReduceJSCreatePromise(Node* node) {
1068  DCHECK_EQ(IrOpcode::kJSCreatePromise, node->opcode());
1069  Node* effect = NodeProperties::GetEffectInput(node);
1070
1071  MapRef promise_map =
1072      native_context().promise_function().initial_map(dependencies());
1073
1074  AllocationBuilder a(jsgraph(), effect, graph()->start());
1075  a.Allocate(promise_map.instance_size());
1076  a.Store(AccessBuilder::ForMap(), promise_map);
1077  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
1078          jsgraph()->EmptyFixedArrayConstant());
1079  a.Store(AccessBuilder::ForJSObjectElements(),
1080          jsgraph()->EmptyFixedArrayConstant());
1081  a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kReactionsOrResultOffset),
1082          jsgraph()->ZeroConstant());
1083  STATIC_ASSERT(v8::Promise::kPending == 0);
1084  a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kFlagsOffset),
1085          jsgraph()->ZeroConstant());
1086  STATIC_ASSERT(JSPromise::kHeaderSize == 5 * kTaggedSize);
1087  for (int offset = JSPromise::kHeaderSize;
1088       offset < JSPromise::kSizeWithEmbedderFields; offset += kTaggedSize) {
1089    a.Store(AccessBuilder::ForJSObjectOffset(offset),
1090            jsgraph()->ZeroConstant());
1091  }
1092  a.FinishAndChange(node);
1093  return Changed(node);
1094}
1095
1096Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
1097  DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray ||
1098         node->opcode() == IrOpcode::kJSCreateLiteralObject);
1099  JSCreateLiteralOpNode n(node);
1100  CreateLiteralParameters const& p = n.Parameters();
1101  Effect effect = n.effect();
1102  Control control = n.control();
1103  ProcessedFeedback const& feedback =
1104      broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback());
1105  if (!feedback.IsInsufficient()) {
1106    AllocationSiteRef site = feedback.AsLiteral().value();
1107    if (!site.boilerplate().has_value()) return NoChange();
1108    AllocationType allocation = dependencies()->DependOnPretenureMode(site);
1109    int max_properties = kMaxFastLiteralProperties;
1110    base::Optional<Node*> maybe_value =
1111        TryAllocateFastLiteral(effect, control, *site.boilerplate(), allocation,
1112                               kMaxFastLiteralDepth, &max_properties);
1113    if (!maybe_value.has_value()) return NoChange();
1114    dependencies()->DependOnElementsKinds(site);
1115    Node* value = effect = maybe_value.value();
1116    ReplaceWithValue(node, value, effect, control);
1117    return Replace(value);
1118  }
1119  return NoChange();
1120}
1121
1122Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
1123  JSCreateEmptyLiteralArrayNode n(node);
1124  FeedbackParameter const& p = n.Parameters();
1125  ProcessedFeedback const& feedback =
1126      broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback());
1127  if (!feedback.IsInsufficient()) {
1128    AllocationSiteRef site = feedback.AsLiteral().value();
1129    DCHECK(!site.PointsToLiteral());
1130    MapRef initial_map =
1131        native_context().GetInitialJSArrayMap(site.GetElementsKind());
1132    AllocationType const allocation =
1133        dependencies()->DependOnPretenureMode(site);
1134    dependencies()->DependOnElementsKind(site);
1135    Node* length = jsgraph()->ZeroConstant();
1136    DCHECK(!initial_map.IsInobjectSlackTrackingInProgress());
1137    SlackTrackingPrediction slack_tracking_prediction(
1138        initial_map, initial_map.instance_size());
1139    return ReduceNewArray(node, length, 0, initial_map,
1140                          initial_map.elements_kind(), allocation,
1141                          slack_tracking_prediction);
1142  }
1143  return NoChange();
1144}
1145
1146Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
1147  DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralObject, node->opcode());
1148  Node* effect = NodeProperties::GetEffectInput(node);
1149  Node* control = NodeProperties::GetControlInput(node);
1150
1151  // Retrieve the initial map for the object.
1152  MapRef map = native_context().object_function().initial_map(dependencies());
1153  DCHECK(!map.is_dictionary_map());
1154  DCHECK(!map.IsInobjectSlackTrackingInProgress());
1155  Node* js_object_map = jsgraph()->Constant(map);
1156
1157  // Setup elements and properties.
1158  Node* elements = jsgraph()->EmptyFixedArrayConstant();
1159
1160  // Perform the allocation of the actual JSArray object.
1161  AllocationBuilder a(jsgraph(), effect, control);
1162  a.Allocate(map.instance_size());
1163  a.Store(AccessBuilder::ForMap(), js_object_map);
1164  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
1165          jsgraph()->EmptyFixedArrayConstant());
1166  a.Store(AccessBuilder::ForJSObjectElements(), elements);
1167  for (int i = 0; i < map.GetInObjectProperties(); i++) {
1168    a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
1169            jsgraph()->UndefinedConstant());
1170  }
1171
1172  RelaxControls(node);
1173  a.FinishAndChange(node);
1174  return Changed(node);
1175}
1176
1177Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
1178  JSCreateLiteralRegExpNode n(node);
1179  CreateLiteralParameters const& p = n.Parameters();
1180  Effect effect = n.effect();
1181  Control control = n.control();
1182  ProcessedFeedback const& feedback =
1183      broker()->GetFeedbackForRegExpLiteral(p.feedback());
1184  if (!feedback.IsInsufficient()) {
1185    RegExpBoilerplateDescriptionRef literal =
1186        feedback.AsRegExpLiteral().value();
1187    Node* value = effect = AllocateLiteralRegExp(effect, control, literal);
1188    ReplaceWithValue(node, value, effect, control);
1189    return Replace(value);
1190  }
1191  return NoChange();
1192}
1193
1194Reduction JSCreateLowering::ReduceJSGetTemplateObject(Node* node) {
1195  JSGetTemplateObjectNode n(node);
1196  GetTemplateObjectParameters const& parameters = n.Parameters();
1197
1198  const ProcessedFeedback& feedback =
1199      broker()->GetFeedbackForTemplateObject(parameters.feedback());
1200  // TODO(v8:7790): Consider not generating JSGetTemplateObject operator
1201  // in the BytecodeGraphBuilder in the first place, if template_object is not
1202  // available.
1203  if (feedback.IsInsufficient()) return NoChange();
1204
1205  JSArrayRef template_object = feedback.AsTemplateObject().value();
1206  Node* value = jsgraph()->Constant(template_object);
1207  ReplaceWithValue(node, value);
1208  return Replace(value);
1209}
1210
1211Reduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) {
1212  DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
1213  const CreateFunctionContextParameters& parameters =
1214      CreateFunctionContextParametersOf(node->op());
1215  ScopeInfoRef scope_info = parameters.scope_info(broker());
1216  int slot_count = parameters.slot_count();
1217  ScopeType scope_type = parameters.scope_type();
1218
1219  // Use inline allocation for function contexts up to a size limit.
1220  if (slot_count < kFunctionContextAllocationLimit) {
1221    // JSCreateFunctionContext[slot_count < limit]](fun)
1222    Node* effect = NodeProperties::GetEffectInput(node);
1223    Node* control = NodeProperties::GetControlInput(node);
1224    Node* context = NodeProperties::GetContextInput(node);
1225    AllocationBuilder a(jsgraph(), effect, control);
1226    STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 2);  // Ensure fully covered.
1227    int context_length = slot_count + Context::MIN_CONTEXT_SLOTS;
1228    switch (scope_type) {
1229      case EVAL_SCOPE:
1230        a.AllocateContext(context_length, native_context().eval_context_map());
1231        break;
1232      case FUNCTION_SCOPE:
1233        a.AllocateContext(context_length,
1234                          native_context().function_context_map());
1235        break;
1236      default:
1237        UNREACHABLE();
1238    }
1239    a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
1240            scope_info);
1241    a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1242    for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
1243      a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
1244    }
1245    RelaxControls(node);
1246    a.FinishAndChange(node);
1247    return Changed(node);
1248  }
1249
1250  return NoChange();
1251}
1252
1253Reduction JSCreateLowering::ReduceJSCreateWithContext(Node* node) {
1254  DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode());
1255  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
1256  Node* extension = NodeProperties::GetValueInput(node, 0);
1257  Node* effect = NodeProperties::GetEffectInput(node);
1258  Node* control = NodeProperties::GetControlInput(node);
1259  Node* context = NodeProperties::GetContextInput(node);
1260
1261  AllocationBuilder a(jsgraph(), effect, control);
1262  STATIC_ASSERT(Context::MIN_CONTEXT_EXTENDED_SLOTS ==
1263                3);  // Ensure fully covered.
1264  a.AllocateContext(Context::MIN_CONTEXT_EXTENDED_SLOTS,
1265                    native_context().with_context_map());
1266  a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
1267  a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1268  a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
1269  RelaxControls(node);
1270  a.FinishAndChange(node);
1271  return Changed(node);
1272}
1273
1274Reduction JSCreateLowering::ReduceJSCreateCatchContext(Node* node) {
1275  DCHECK_EQ(IrOpcode::kJSCreateCatchContext, node->opcode());
1276  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
1277  Node* exception = NodeProperties::GetValueInput(node, 0);
1278  Node* effect = NodeProperties::GetEffectInput(node);
1279  Node* control = NodeProperties::GetControlInput(node);
1280  Node* context = NodeProperties::GetContextInput(node);
1281
1282  AllocationBuilder a(jsgraph(), effect, control);
1283  STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 2);  // Ensure fully covered.
1284  a.AllocateContext(Context::MIN_CONTEXT_SLOTS + 1,
1285                    native_context().catch_context_map());
1286  a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
1287  a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1288  a.Store(AccessBuilder::ForContextSlot(Context::THROWN_OBJECT_INDEX),
1289          exception);
1290  RelaxControls(node);
1291  a.FinishAndChange(node);
1292  return Changed(node);
1293}
1294
1295Reduction JSCreateLowering::ReduceJSCreateBlockContext(Node* node) {
1296  DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
1297  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
1298  int const context_length = scope_info.ContextLength();
1299
1300  // Use inline allocation for block contexts up to a size limit.
1301  if (context_length < kBlockContextAllocationLimit) {
1302    // JSCreateBlockContext[scope[length < limit]](fun)
1303    Node* effect = NodeProperties::GetEffectInput(node);
1304    Node* control = NodeProperties::GetControlInput(node);
1305    Node* context = NodeProperties::GetContextInput(node);
1306
1307    AllocationBuilder a(jsgraph(), effect, control);
1308    STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 2);  // Ensure fully covered.
1309    a.AllocateContext(context_length, native_context().block_context_map());
1310    a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
1311            scope_info);
1312    a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1313    for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
1314      a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
1315    }
1316    RelaxControls(node);
1317    a.FinishAndChange(node);
1318    return Changed(node);
1319  }
1320
1321  return NoChange();
1322}
1323
1324namespace {
1325
1326base::Optional<MapRef> GetObjectCreateMap(JSHeapBroker* broker,
1327                                          HeapObjectRef prototype) {
1328  MapRef standard_map =
1329      broker->target_native_context().object_function().initial_map(
1330          broker->dependencies());
1331  if (prototype.equals(standard_map.prototype())) {
1332    return standard_map;
1333  }
1334  if (prototype.map().oddball_type() == OddballType::kNull) {
1335    return broker->target_native_context()
1336        .slow_object_with_null_prototype_map();
1337  }
1338  if (prototype.IsJSObject()) {
1339    return prototype.AsJSObject().GetObjectCreateMap();
1340  }
1341  return base::Optional<MapRef>();
1342}
1343
1344}  // namespace
1345
1346Reduction JSCreateLowering::ReduceJSCreateObject(Node* node) {
1347  DCHECK_EQ(IrOpcode::kJSCreateObject, node->opcode());
1348  Node* effect = NodeProperties::GetEffectInput(node);
1349  Node* control = NodeProperties::GetControlInput(node);
1350  Node* prototype = NodeProperties::GetValueInput(node, 0);
1351  Type prototype_type = NodeProperties::GetType(prototype);
1352  if (!prototype_type.IsHeapConstant()) return NoChange();
1353
1354  HeapObjectRef prototype_const = prototype_type.AsHeapConstant()->Ref();
1355  auto maybe_instance_map = GetObjectCreateMap(broker(), prototype_const);
1356  if (!maybe_instance_map) return NoChange();
1357  MapRef instance_map = maybe_instance_map.value();
1358
1359  Node* properties = jsgraph()->EmptyFixedArrayConstant();
1360  if (instance_map.is_dictionary_map()) {
1361    DCHECK_EQ(prototype_const.map().oddball_type(), OddballType::kNull);
1362    // Allocate an empty NameDictionary as backing store for the properties.
1363    MapRef map = MakeRef(broker(), factory()->name_dictionary_map());
1364    int capacity =
1365        NameDictionary::ComputeCapacity(NameDictionary::kInitialCapacity);
1366    DCHECK(base::bits::IsPowerOfTwo(capacity));
1367    int length = NameDictionary::EntryToIndex(InternalIndex(capacity));
1368    int size = NameDictionary::SizeFor(length);
1369
1370    AllocationBuilder a(jsgraph(), effect, control);
1371    a.Allocate(size, AllocationType::kYoung, Type::Any());
1372    a.Store(AccessBuilder::ForMap(), map);
1373    // Initialize FixedArray fields.
1374    a.Store(AccessBuilder::ForFixedArrayLength(),
1375            jsgraph()->SmiConstant(length));
1376    // Initialize HashTable fields.
1377    a.Store(AccessBuilder::ForHashTableBaseNumberOfElements(),
1378            jsgraph()->SmiConstant(0));
1379    a.Store(AccessBuilder::ForHashTableBaseNumberOfDeletedElement(),
1380            jsgraph()->SmiConstant(0));
1381    a.Store(AccessBuilder::ForHashTableBaseCapacity(),
1382            jsgraph()->SmiConstant(capacity));
1383    // Initialize Dictionary fields.
1384    a.Store(AccessBuilder::ForDictionaryNextEnumerationIndex(),
1385            jsgraph()->SmiConstant(PropertyDetails::kInitialIndex));
1386    a.Store(AccessBuilder::ForDictionaryObjectHashIndex(),
1387            jsgraph()->SmiConstant(PropertyArray::kNoHashSentinel));
1388    // Initialize the Properties fields.
1389    Node* undefined = jsgraph()->UndefinedConstant();
1390    STATIC_ASSERT(NameDictionary::kElementsStartIndex ==
1391                  NameDictionary::kObjectHashIndex + 1);
1392    for (int index = NameDictionary::kElementsStartIndex; index < length;
1393         index++) {
1394      a.Store(AccessBuilder::ForFixedArraySlot(index, kNoWriteBarrier),
1395              undefined);
1396    }
1397    properties = effect = a.Finish();
1398  }
1399
1400  int const instance_size = instance_map.instance_size();
1401  if (instance_size > kMaxRegularHeapObjectSize) return NoChange();
1402  CHECK(!instance_map.IsInobjectSlackTrackingInProgress());
1403
1404  // Emit code to allocate the JSObject instance for the given
1405  // {instance_map}.
1406  AllocationBuilder a(jsgraph(), effect, control);
1407  a.Allocate(instance_size, AllocationType::kYoung, Type::Any());
1408  a.Store(AccessBuilder::ForMap(), instance_map);
1409  a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
1410  a.Store(AccessBuilder::ForJSObjectElements(),
1411          jsgraph()->EmptyFixedArrayConstant());
1412  // Initialize Object fields.
1413  Node* undefined = jsgraph()->UndefinedConstant();
1414  for (int offset = JSObject::kHeaderSize; offset < instance_size;
1415       offset += kTaggedSize) {
1416    a.Store(AccessBuilder::ForJSObjectOffset(offset, kNoWriteBarrier),
1417            undefined);
1418  }
1419  Node* value = effect = a.Finish();
1420
1421  ReplaceWithValue(node, value, effect, control);
1422  return Replace(value);
1423}
1424
1425// Helper that allocates a FixedArray holding argument values recorded in the
1426// given {frame_state}. Serves as backing store for JSCreateArguments nodes.
1427Node* JSCreateLowering::TryAllocateArguments(Node* effect, Node* control,
1428                                             FrameState frame_state) {
1429  FrameStateInfo state_info = frame_state.frame_state_info();
1430  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
1431  if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
1432
1433  // Prepare an iterator over argument values recorded in the frame state.
1434  Node* const parameters = frame_state.parameters();
1435  StateValuesAccess parameters_access(parameters);
1436  auto parameters_it = parameters_access.begin_without_receiver();
1437
1438  // Actually allocate the backing store.
1439  MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
1440  AllocationBuilder ab(jsgraph(), effect, control);
1441  if (!ab.CanAllocateArray(argument_count, fixed_array_map)) {
1442    return nullptr;
1443  }
1444  ab.AllocateArray(argument_count, fixed_array_map);
1445  for (int i = 0; i < argument_count; ++i, ++parameters_it) {
1446    DCHECK_NOT_NULL(parameters_it.node());
1447    ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
1448             parameters_it.node());
1449  }
1450  return ab.Finish();
1451}
1452
1453// Helper that allocates a FixedArray holding argument values recorded in the
1454// given {frame_state}. Serves as backing store for JSCreateArguments nodes.
1455Node* JSCreateLowering::TryAllocateRestArguments(Node* effect, Node* control,
1456                                                 FrameState frame_state,
1457                                                 int start_index) {
1458  FrameStateInfo state_info = frame_state.frame_state_info();
1459  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
1460  int num_elements = std::max(0, argument_count - start_index);
1461  if (num_elements == 0) return jsgraph()->EmptyFixedArrayConstant();
1462
1463  // Prepare an iterator over argument values recorded in the frame state.
1464  Node* const parameters = frame_state.parameters();
1465  StateValuesAccess parameters_access(parameters);
1466  auto parameters_it =
1467      parameters_access.begin_without_receiver_and_skip(start_index);
1468
1469  // Actually allocate the backing store.
1470  MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
1471  AllocationBuilder ab(jsgraph(), effect, control);
1472  if (!ab.CanAllocateArray(num_elements, fixed_array_map)) {
1473    return nullptr;
1474  }
1475  ab.AllocateArray(num_elements, fixed_array_map);
1476  for (int i = 0; i < num_elements; ++i, ++parameters_it) {
1477    DCHECK_NOT_NULL(parameters_it.node());
1478    ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
1479             parameters_it.node());
1480  }
1481  return ab.Finish();
1482}
1483
1484// Helper that allocates a FixedArray serving as a parameter map for values
1485// recorded in the given {frame_state}. Some elements map to slots within the
1486// given {context}. Serves as backing store for JSCreateArguments nodes.
1487Node* JSCreateLowering::TryAllocateAliasedArguments(
1488    Node* effect, Node* control, FrameState frame_state, Node* context,
1489    const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) {
1490  FrameStateInfo state_info = frame_state.frame_state_info();
1491  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
1492  if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
1493
1494  // If there is no aliasing, the arguments object elements are not special in
1495  // any way, we can just return an unmapped backing store instead.
1496  int parameter_count =
1497      shared.internal_formal_parameter_count_without_receiver();
1498  if (parameter_count == 0) {
1499    return TryAllocateArguments(effect, control, frame_state);
1500  }
1501
1502  // Calculate number of argument values being aliased/mapped.
1503  int mapped_count = std::min(argument_count, parameter_count);
1504  *has_aliased_arguments = true;
1505
1506  MapRef sloppy_arguments_elements_map =
1507      MakeRef(broker(), factory()->sloppy_arguments_elements_map());
1508  AllocationBuilder ab(jsgraph(), effect, control);
1509
1510  if (!ab.CanAllocateSloppyArgumentElements(mapped_count,
1511                                            sloppy_arguments_elements_map)) {
1512    return nullptr;
1513  }
1514
1515  MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
1516  if (!ab.CanAllocateArray(argument_count, fixed_array_map)) {
1517    return nullptr;
1518  }
1519
1520  // Prepare an iterator over argument values recorded in the frame state.
1521  Node* const parameters = frame_state.parameters();
1522  StateValuesAccess parameters_access(parameters);
1523  auto parameters_it =
1524      parameters_access.begin_without_receiver_and_skip(mapped_count);
1525
1526  // The unmapped argument values recorded in the frame state are stored yet
1527  // another indirection away and then linked into the parameter map below,
1528  // whereas mapped argument values are replaced with a hole instead.
1529  ab.AllocateArray(argument_count, fixed_array_map);
1530  for (int i = 0; i < mapped_count; ++i) {
1531    ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
1532             jsgraph()->TheHoleConstant());
1533  }
1534  for (int i = mapped_count; i < argument_count; ++i, ++parameters_it) {
1535    DCHECK_NOT_NULL(parameters_it.node());
1536    ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
1537             parameters_it.node());
1538  }
1539  Node* arguments = ab.Finish();
1540
1541  // Actually allocate the backing store.
1542  AllocationBuilder a(jsgraph(), arguments, control);
1543  a.AllocateSloppyArgumentElements(mapped_count, sloppy_arguments_elements_map);
1544  a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context);
1545  a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments);
1546  for (int i = 0; i < mapped_count; ++i) {
1547    int idx = shared.context_parameters_start() + parameter_count - 1 - i;
1548    a.Store(AccessBuilder::ForSloppyArgumentsElementsMappedEntry(),
1549            jsgraph()->Constant(i), jsgraph()->Constant(idx));
1550  }
1551  return a.Finish();
1552}
1553
1554// Helper that allocates a FixedArray serving as a parameter map for values
1555// unknown at compile-time, the true {arguments_length} and {arguments_frame}
1556// values can only be determined dynamically at run-time and are provided.
1557// Serves as backing store for JSCreateArguments nodes.
1558Node* JSCreateLowering::TryAllocateAliasedArguments(
1559    Node* effect, Node* control, Node* context, Node* arguments_length,
1560    const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) {
1561  // If there is no aliasing, the arguments object elements are not
1562  // special in any way, we can just return an unmapped backing store.
1563  int parameter_count =
1564      shared.internal_formal_parameter_count_without_receiver();
1565  if (parameter_count == 0) {
1566    return graph()->NewNode(
1567        simplified()->NewArgumentsElements(
1568            CreateArgumentsType::kUnmappedArguments, parameter_count),
1569        arguments_length, effect);
1570  }
1571
1572  int mapped_count = parameter_count;
1573  MapRef sloppy_arguments_elements_map =
1574      MakeRef(broker(), factory()->sloppy_arguments_elements_map());
1575
1576  {
1577    AllocationBuilder ab(jsgraph(), effect, control);
1578    if (!ab.CanAllocateSloppyArgumentElements(mapped_count,
1579                                              sloppy_arguments_elements_map)) {
1580      return nullptr;
1581    }
1582  }
1583
1584  // From here on we are going to allocate a mapped (aka. aliased) elements
1585  // backing store. We do not statically know how many arguments exist, but
1586  // dynamically selecting the hole for some of the "mapped" elements allows
1587  // using a static shape for the parameter map.
1588  *has_aliased_arguments = true;
1589
1590  // The unmapped argument values are stored yet another indirection away and
1591  // then linked into the parameter map below, whereas mapped argument values
1592  // (i.e. the first {mapped_count} elements) are replaced with a hole instead.
1593  Node* arguments = effect =
1594      graph()->NewNode(simplified()->NewArgumentsElements(
1595                           CreateArgumentsType::kMappedArguments, mapped_count),
1596                       arguments_length, effect);
1597
1598  // Actually allocate the backing store.
1599  AllocationBuilder a(jsgraph(), effect, control);
1600  a.AllocateSloppyArgumentElements(mapped_count, sloppy_arguments_elements_map);
1601  a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context);
1602  a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments);
1603  for (int i = 0; i < mapped_count; ++i) {
1604    int idx = shared.context_parameters_start() + parameter_count - 1 - i;
1605    Node* value = graph()->NewNode(
1606        common()->Select(MachineRepresentation::kTagged),
1607        graph()->NewNode(simplified()->NumberLessThan(), jsgraph()->Constant(i),
1608                         arguments_length),
1609        jsgraph()->Constant(idx), jsgraph()->TheHoleConstant());
1610    a.Store(AccessBuilder::ForSloppyArgumentsElementsMappedEntry(),
1611            jsgraph()->Constant(i), value);
1612  }
1613  return a.Finish();
1614}
1615
1616Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
1617                                         ElementsKind elements_kind,
1618                                         int capacity,
1619                                         AllocationType allocation) {
1620  DCHECK_LE(1, capacity);
1621  DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
1622
1623  Handle<Map> elements_map = IsDoubleElementsKind(elements_kind)
1624                                 ? factory()->fixed_double_array_map()
1625                                 : factory()->fixed_array_map();
1626  ElementAccess access = IsDoubleElementsKind(elements_kind)
1627                             ? AccessBuilder::ForFixedDoubleArrayElement()
1628                             : AccessBuilder::ForFixedArrayElement();
1629  Node* value = jsgraph()->TheHoleConstant();
1630
1631  // Actually allocate the backing store.
1632  AllocationBuilder a(jsgraph(), effect, control);
1633  a.AllocateArray(capacity, MakeRef(broker(), elements_map), allocation);
1634  for (int i = 0; i < capacity; ++i) {
1635    Node* index = jsgraph()->Constant(i);
1636    a.Store(access, index, value);
1637  }
1638  return a.Finish();
1639}
1640
1641Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
1642                                         ElementsKind elements_kind,
1643                                         std::vector<Node*> const& values,
1644                                         AllocationType allocation) {
1645  int const capacity = static_cast<int>(values.size());
1646  DCHECK_LE(1, capacity);
1647  DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
1648
1649  Handle<Map> elements_map = IsDoubleElementsKind(elements_kind)
1650                                 ? factory()->fixed_double_array_map()
1651                                 : factory()->fixed_array_map();
1652  ElementAccess access = IsDoubleElementsKind(elements_kind)
1653                             ? AccessBuilder::ForFixedDoubleArrayElement()
1654                             : AccessBuilder::ForFixedArrayElement();
1655
1656  // Actually allocate the backing store.
1657  AllocationBuilder a(jsgraph(), effect, control);
1658  a.AllocateArray(capacity, MakeRef(broker(), elements_map), allocation);
1659  for (int i = 0; i < capacity; ++i) {
1660    Node* index = jsgraph()->Constant(i);
1661    a.Store(access, index, values[i]);
1662  }
1663  return a.Finish();
1664}
1665
1666base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteral(
1667    Node* effect, Node* control, JSObjectRef boilerplate,
1668    AllocationType allocation, int max_depth, int* max_properties) {
1669  DCHECK_GE(max_depth, 0);
1670  DCHECK_GE(*max_properties, 0);
1671
1672  if (max_depth == 0) return {};
1673
1674  // Prevent concurrent migrations of boilerplate objects.
1675  JSHeapBroker::BoilerplateMigrationGuardIfNeeded boilerplate_access_guard(
1676      broker());
1677
1678  // Now that we hold the migration lock, get the current map.
1679  MapRef boilerplate_map = boilerplate.map();
1680  // Protect against concurrent changes to the boilerplate object by checking
1681  // for an identical value at the end of the compilation.
1682  dependencies()->DependOnObjectSlotValue(boilerplate, HeapObject::kMapOffset,
1683                                          boilerplate_map);
1684  {
1685    base::Optional<MapRef> current_boilerplate_map =
1686        boilerplate.map_direct_read();
1687    if (!current_boilerplate_map.has_value() ||
1688        !current_boilerplate_map->equals(boilerplate_map)) {
1689      return {};
1690    }
1691  }
1692
1693  // Bail out if the boilerplate map has been deprecated.  The map could of
1694  // course be deprecated at some point after the line below, but it's not a
1695  // correctness issue -- it only means the literal won't be created with the
1696  // most up to date map(s).
1697  if (boilerplate_map.is_deprecated()) return {};
1698
1699  // We currently only support in-object properties.
1700  if (boilerplate.map().elements_kind() == DICTIONARY_ELEMENTS ||
1701      boilerplate.map().is_dictionary_map() ||
1702      !boilerplate.raw_properties_or_hash().has_value()) {
1703    return {};
1704  }
1705  {
1706    ObjectRef properties = *boilerplate.raw_properties_or_hash();
1707    bool const empty = properties.IsSmi() ||
1708                       properties.equals(MakeRef<Object>(
1709                           broker(), factory()->empty_fixed_array())) ||
1710                       properties.equals(MakeRef<Object>(
1711                           broker(), factory()->empty_property_array()));
1712    if (!empty) return {};
1713  }
1714
1715  // Compute the in-object properties to store first (might have effects).
1716  ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone());
1717  inobject_fields.reserve(boilerplate_map.GetInObjectProperties());
1718  int const boilerplate_nof = boilerplate_map.NumberOfOwnDescriptors();
1719  for (InternalIndex i : InternalIndex::Range(boilerplate_nof)) {
1720    PropertyDetails const property_details =
1721        boilerplate_map.GetPropertyDetails(i);
1722    if (property_details.location() != PropertyLocation::kField) continue;
1723    DCHECK_EQ(PropertyKind::kData, property_details.kind());
1724    if ((*max_properties)-- == 0) return {};
1725
1726    NameRef property_name = boilerplate_map.GetPropertyKey(i);
1727    FieldIndex index = boilerplate_map.GetFieldIndexFor(i);
1728    ConstFieldInfo const_field_info(boilerplate_map.object());
1729    FieldAccess access = {kTaggedBase,
1730                          index.offset(),
1731                          property_name.object(),
1732                          MaybeHandle<Map>(),
1733                          Type::Any(),
1734                          MachineType::AnyTagged(),
1735                          kFullWriteBarrier,
1736                          const_field_info};
1737
1738    // Note: the use of RawInobjectPropertyAt (vs. the higher-level
1739    // GetOwnFastDataProperty) here is necessary, since the underlying value
1740    // may be `uninitialized`, which the latter explicitly does not support.
1741    base::Optional<ObjectRef> maybe_boilerplate_value =
1742        boilerplate.RawInobjectPropertyAt(index);
1743    if (!maybe_boilerplate_value.has_value()) return {};
1744
1745    // Note: We don't need to take a compilation dependency verifying the value
1746    // of `boilerplate_value`, since boilerplate properties are constant after
1747    // initialization modulo map migration. We protect against concurrent map
1748    // migrations (other than elements kind transition, which don't affect us)
1749    // via the boilerplate_migration_access lock.
1750    ObjectRef boilerplate_value = maybe_boilerplate_value.value();
1751
1752    // Uninitialized fields are marked through the `uninitialized_value` Oddball
1753    // (even for Smi representation!), or in the case of Double representation
1754    // through a HeapNumber containing the hole-NaN. Since Double-to-Tagged
1755    // representation changes are done in-place, we may even encounter these
1756    // HeapNumbers in Tagged representation.
1757    // Note that although we create nodes to write `uninitialized_value` into
1758    // the object, the field should be overwritten immediately with a real
1759    // value, and `uninitialized_value` should never be exposed to JS.
1760    ObjectRef uninitialized_oddball =
1761        MakeRef<HeapObject>(broker(), factory()->uninitialized_value());
1762    if (boilerplate_value.equals(uninitialized_oddball) ||
1763        (boilerplate_value.IsHeapNumber() &&
1764         boilerplate_value.AsHeapNumber().value_as_bits() == kHoleNanInt64)) {
1765      access.const_field_info = ConstFieldInfo::None();
1766    }
1767
1768    Node* value;
1769    if (boilerplate_value.IsJSObject()) {
1770      JSObjectRef boilerplate_object = boilerplate_value.AsJSObject();
1771      base::Optional<Node*> maybe_value =
1772          TryAllocateFastLiteral(effect, control, boilerplate_object,
1773                                 allocation, max_depth - 1, max_properties);
1774      if (!maybe_value.has_value()) return {};
1775      value = effect = maybe_value.value();
1776    } else if (property_details.representation().IsDouble()) {
1777      double number = boilerplate_value.AsHeapNumber().value();
1778      // Allocate a mutable HeapNumber box and store the value into it.
1779      AllocationBuilder builder(jsgraph(), effect, control);
1780      builder.Allocate(HeapNumber::kSize, allocation);
1781      builder.Store(AccessBuilder::ForMap(),
1782                    MakeRef(broker(), factory()->heap_number_map()));
1783      builder.Store(AccessBuilder::ForHeapNumberValue(),
1784                    jsgraph()->Constant(number));
1785      value = effect = builder.Finish();
1786    } else {
1787      // It's fine to store the 'uninitialized' Oddball into a Smi field since
1788      // it will get overwritten anyways and the store's MachineType (AnyTagged)
1789      // is compatible with it.
1790      DCHECK_IMPLIES(property_details.representation().IsSmi() &&
1791                         !boilerplate_value.IsSmi(),
1792                     boilerplate_value.equals(uninitialized_oddball));
1793      value = jsgraph()->Constant(boilerplate_value);
1794    }
1795    inobject_fields.push_back(std::make_pair(access, value));
1796  }
1797
1798  // Fill slack at the end of the boilerplate object with filler maps.
1799  int const boilerplate_length = boilerplate_map.GetInObjectProperties();
1800  for (int index = static_cast<int>(inobject_fields.size());
1801       index < boilerplate_length; ++index) {
1802    DCHECK(!V8_MAP_PACKING_BOOL);
1803    // TODO(wenyuzhao): Fix incorrect MachineType when V8_MAP_PACKING is
1804    // enabled.
1805    FieldAccess access =
1806        AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index);
1807    Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
1808    inobject_fields.push_back(std::make_pair(access, value));
1809  }
1810
1811  // Setup the elements backing store.
1812  base::Optional<Node*> maybe_elements = TryAllocateFastLiteralElements(
1813      effect, control, boilerplate, allocation, max_depth, max_properties);
1814  if (!maybe_elements.has_value()) return {};
1815  Node* elements = maybe_elements.value();
1816  if (elements->op()->EffectOutputCount() > 0) effect = elements;
1817
1818  // Actually allocate and initialize the object.
1819  AllocationBuilder builder(jsgraph(), effect, control);
1820  builder.Allocate(boilerplate_map.instance_size(), allocation,
1821                   Type::For(boilerplate_map));
1822  builder.Store(AccessBuilder::ForMap(), boilerplate_map);
1823  builder.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
1824                jsgraph()->EmptyFixedArrayConstant());
1825  builder.Store(AccessBuilder::ForJSObjectElements(), elements);
1826  if (boilerplate.IsJSArray()) {
1827    JSArrayRef boilerplate_array = boilerplate.AsJSArray();
1828    builder.Store(AccessBuilder::ForJSArrayLength(
1829                      boilerplate_array.map().elements_kind()),
1830                  boilerplate_array.GetBoilerplateLength());
1831  }
1832  for (auto const& inobject_field : inobject_fields) {
1833    builder.Store(inobject_field.first, inobject_field.second);
1834  }
1835  return builder.Finish();
1836}
1837
1838base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteralElements(
1839    Node* effect, Node* control, JSObjectRef boilerplate,
1840    AllocationType allocation, int max_depth, int* max_properties) {
1841  DCHECK_GT(max_depth, 0);
1842  DCHECK_GE(*max_properties, 0);
1843
1844  base::Optional<FixedArrayBaseRef> maybe_boilerplate_elements =
1845      boilerplate.elements(kRelaxedLoad);
1846  if (!maybe_boilerplate_elements.has_value()) return {};
1847  FixedArrayBaseRef boilerplate_elements = maybe_boilerplate_elements.value();
1848  // Protect against concurrent changes to the boilerplate object by checking
1849  // for an identical value at the end of the compilation.
1850  dependencies()->DependOnObjectSlotValue(
1851      boilerplate, JSObject::kElementsOffset, boilerplate_elements);
1852
1853  // Empty or copy-on-write elements just store a constant.
1854  int const elements_length = boilerplate_elements.length();
1855  MapRef elements_map = boilerplate_elements.map();
1856  // Protect against concurrent changes to the boilerplate object by checking
1857  // for an identical value at the end of the compilation.
1858  dependencies()->DependOnObjectSlotValue(boilerplate_elements,
1859                                          HeapObject::kMapOffset, elements_map);
1860  if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
1861    if (allocation == AllocationType::kOld &&
1862        !boilerplate.IsElementsTenured(boilerplate_elements)) {
1863      return {};
1864    }
1865    return jsgraph()->Constant(boilerplate_elements);
1866  }
1867
1868  // Compute the elements to store first (might have effects).
1869  ZoneVector<Node*> elements_values(elements_length, zone());
1870  if (boilerplate_elements.IsFixedDoubleArray()) {
1871    int const size = FixedDoubleArray::SizeFor(boilerplate_elements.length());
1872    if (size > kMaxRegularHeapObjectSize) return {};
1873
1874    FixedDoubleArrayRef elements = boilerplate_elements.AsFixedDoubleArray();
1875    for (int i = 0; i < elements_length; ++i) {
1876      Float64 value = elements.GetFromImmutableFixedDoubleArray(i);
1877      elements_values[i] = value.is_hole_nan()
1878                               ? jsgraph()->TheHoleConstant()
1879                               : jsgraph()->Constant(value.get_scalar());
1880    }
1881  } else {
1882    FixedArrayRef elements = boilerplate_elements.AsFixedArray();
1883    for (int i = 0; i < elements_length; ++i) {
1884      if ((*max_properties)-- == 0) return {};
1885      base::Optional<ObjectRef> element_value = elements.TryGet(i);
1886      if (!element_value.has_value()) return {};
1887      if (element_value->IsJSObject()) {
1888        base::Optional<Node*> object =
1889            TryAllocateFastLiteral(effect, control, element_value->AsJSObject(),
1890                                   allocation, max_depth - 1, max_properties);
1891        if (!object.has_value()) return {};
1892        elements_values[i] = effect = *object;
1893      } else {
1894        elements_values[i] = jsgraph()->Constant(*element_value);
1895      }
1896    }
1897  }
1898
1899  // Allocate the backing store array and store the elements.
1900  AllocationBuilder ab(jsgraph(), effect, control);
1901  CHECK(ab.CanAllocateArray(elements_length, elements_map, allocation));
1902  ab.AllocateArray(elements_length, elements_map, allocation);
1903  ElementAccess const access = boilerplate_elements.IsFixedDoubleArray()
1904                                   ? AccessBuilder::ForFixedDoubleArrayElement()
1905                                   : AccessBuilder::ForFixedArrayElement();
1906  for (int i = 0; i < elements_length; ++i) {
1907    ab.Store(access, jsgraph()->Constant(i), elements_values[i]);
1908  }
1909  return ab.Finish();
1910}
1911
1912Node* JSCreateLowering::AllocateLiteralRegExp(
1913    Node* effect, Node* control, RegExpBoilerplateDescriptionRef boilerplate) {
1914  MapRef initial_map =
1915      native_context().regexp_function().initial_map(dependencies());
1916
1917  // Sanity check that JSRegExp object layout hasn't changed.
1918  STATIC_ASSERT(JSRegExp::kDataOffset == JSObject::kHeaderSize);
1919  STATIC_ASSERT(JSRegExp::kSourceOffset == JSRegExp::kDataOffset + kTaggedSize);
1920  STATIC_ASSERT(JSRegExp::kFlagsOffset ==
1921                JSRegExp::kSourceOffset + kTaggedSize);
1922  STATIC_ASSERT(JSRegExp::kHeaderSize == JSRegExp::kFlagsOffset + kTaggedSize);
1923  STATIC_ASSERT(JSRegExp::kLastIndexOffset == JSRegExp::kHeaderSize);
1924  DCHECK_EQ(JSRegExp::Size(), JSRegExp::kLastIndexOffset + kTaggedSize);
1925
1926  AllocationBuilder builder(jsgraph(), effect, control);
1927  builder.Allocate(JSRegExp::Size(), AllocationType::kYoung,
1928                   Type::For(initial_map));
1929  builder.Store(AccessBuilder::ForMap(), initial_map);
1930  builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
1931                jsgraph()->EmptyFixedArrayConstant());
1932  builder.Store(AccessBuilder::ForJSObjectElements(),
1933                jsgraph()->EmptyFixedArrayConstant());
1934
1935  builder.Store(AccessBuilder::ForJSRegExpData(), boilerplate.data());
1936  builder.Store(AccessBuilder::ForJSRegExpSource(), boilerplate.source());
1937  builder.Store(AccessBuilder::ForJSRegExpFlags(),
1938                jsgraph()->SmiConstant(boilerplate.flags()));
1939  builder.Store(AccessBuilder::ForJSRegExpLastIndex(),
1940                jsgraph()->SmiConstant(JSRegExp::kInitialLastIndexValue));
1941
1942  return builder.Finish();
1943}
1944
1945Factory* JSCreateLowering::factory() const {
1946  return jsgraph()->isolate()->factory();
1947}
1948
1949Graph* JSCreateLowering::graph() const { return jsgraph()->graph(); }
1950
1951CommonOperatorBuilder* JSCreateLowering::common() const {
1952  return jsgraph()->common();
1953}
1954
1955SimplifiedOperatorBuilder* JSCreateLowering::simplified() const {
1956  return jsgraph()->simplified();
1957}
1958
1959NativeContextRef JSCreateLowering::native_context() const {
1960  return broker()->target_native_context();
1961}
1962
1963}  // namespace compiler
1964}  // namespace internal
1965}  // namespace v8
1966