11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_COMPILER_ALLOCATION_BUILDER_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_ALLOCATION_BUILDER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h"
91cb0ef41Sopenharmony_ci#include "src/compiler/node.h"
101cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace v8 {
131cb0ef41Sopenharmony_cinamespace internal {
141cb0ef41Sopenharmony_cinamespace compiler {
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci// A helper class to construct inline allocations on the simplified operator
171cb0ef41Sopenharmony_ci// level. This keeps track of the effect chain for initial stores on a newly
181cb0ef41Sopenharmony_ci// allocated object and also provides helpers for commonly allocated objects.
191cb0ef41Sopenharmony_ciclass AllocationBuilder final {
201cb0ef41Sopenharmony_ci public:
211cb0ef41Sopenharmony_ci  AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control)
221cb0ef41Sopenharmony_ci      : jsgraph_(jsgraph),
231cb0ef41Sopenharmony_ci        allocation_(nullptr),
241cb0ef41Sopenharmony_ci        effect_(effect),
251cb0ef41Sopenharmony_ci        control_(control) {}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci  // Primitive allocation of static size.
281cb0ef41Sopenharmony_ci  inline void Allocate(int size,
291cb0ef41Sopenharmony_ci                       AllocationType allocation = AllocationType::kYoung,
301cb0ef41Sopenharmony_ci                       Type type = Type::Any());
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  // Primitive store into a field.
331cb0ef41Sopenharmony_ci  void Store(const FieldAccess& access, Node* value) {
341cb0ef41Sopenharmony_ci    effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_,
351cb0ef41Sopenharmony_ci                               value, effect_, control_);
361cb0ef41Sopenharmony_ci  }
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  // Primitive store into an element.
391cb0ef41Sopenharmony_ci  void Store(ElementAccess const& access, Node* index, Node* value) {
401cb0ef41Sopenharmony_ci    effect_ = graph()->NewNode(simplified()->StoreElement(access), allocation_,
411cb0ef41Sopenharmony_ci                               index, value, effect_, control_);
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  // Compound allocation of a context.
451cb0ef41Sopenharmony_ci  inline void AllocateContext(int variadic_part_length, MapRef map);
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  // Compound allocation of a FixedArray.
481cb0ef41Sopenharmony_ci  inline bool CanAllocateArray(
491cb0ef41Sopenharmony_ci      int length, MapRef map,
501cb0ef41Sopenharmony_ci      AllocationType allocation = AllocationType::kYoung);
511cb0ef41Sopenharmony_ci  inline void AllocateArray(int length, MapRef map,
521cb0ef41Sopenharmony_ci                            AllocationType allocation = AllocationType::kYoung);
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  // Compound allocation of a SloppyArgumentsElements
551cb0ef41Sopenharmony_ci  inline bool CanAllocateSloppyArgumentElements(
561cb0ef41Sopenharmony_ci      int length, MapRef map,
571cb0ef41Sopenharmony_ci      AllocationType allocation = AllocationType::kYoung);
581cb0ef41Sopenharmony_ci  inline void AllocateSloppyArgumentElements(
591cb0ef41Sopenharmony_ci      int length, MapRef map,
601cb0ef41Sopenharmony_ci      AllocationType allocation = AllocationType::kYoung);
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  // Compound store of a constant into a field.
631cb0ef41Sopenharmony_ci  void Store(const FieldAccess& access, const ObjectRef& value) {
641cb0ef41Sopenharmony_ci    Store(access, jsgraph()->Constant(value));
651cb0ef41Sopenharmony_ci  }
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  void FinishAndChange(Node* node) {
681cb0ef41Sopenharmony_ci    NodeProperties::SetType(allocation_, NodeProperties::GetType(node));
691cb0ef41Sopenharmony_ci    node->ReplaceInput(0, allocation_);
701cb0ef41Sopenharmony_ci    node->ReplaceInput(1, effect_);
711cb0ef41Sopenharmony_ci    node->TrimInputCount(2);
721cb0ef41Sopenharmony_ci    NodeProperties::ChangeOp(node, common()->FinishRegion());
731cb0ef41Sopenharmony_ci  }
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  Node* Finish() {
761cb0ef41Sopenharmony_ci    return graph()->NewNode(common()->FinishRegion(), allocation_, effect_);
771cb0ef41Sopenharmony_ci  }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci protected:
801cb0ef41Sopenharmony_ci  JSGraph* jsgraph() { return jsgraph_; }
811cb0ef41Sopenharmony_ci  Isolate* isolate() const { return jsgraph_->isolate(); }
821cb0ef41Sopenharmony_ci  Graph* graph() { return jsgraph_->graph(); }
831cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common() { return jsgraph_->common(); }
841cb0ef41Sopenharmony_ci  SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); }
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci private:
871cb0ef41Sopenharmony_ci  JSGraph* const jsgraph_;
881cb0ef41Sopenharmony_ci  Node* allocation_;
891cb0ef41Sopenharmony_ci  Node* effect_;
901cb0ef41Sopenharmony_ci  Node* control_;
911cb0ef41Sopenharmony_ci};
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci}  // namespace compiler
941cb0ef41Sopenharmony_ci}  // namespace internal
951cb0ef41Sopenharmony_ci}  // namespace v8
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_ALLOCATION_BUILDER_H_
98