1bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// found in the LICENSE file.
4bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/compiler/code-assembler.h"
6bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
7bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include <ostream>
8bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
9bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/code-factory.h"
10bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/compiler/graph.h"
11bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/compiler/instruction-selector.h"
12bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/compiler/linkage.h"
13bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/compiler/node-matchers.h"
14bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/compiler/pipeline.h"
15bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/compiler/raw-machine-assembler.h"
16bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/compiler/schedule.h"
17bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/frames.h"
18bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/interface-descriptors.h"
19bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/interpreter/bytecodes.h"
20bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/machine-type.h"
21bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/macro-assembler.h"
2213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/utils.h"
23f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/zone/zone.h"
24bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
25bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochnamespace v8 {
26bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochnamespace internal {
27bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochnamespace compiler {
28bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
29bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone,
30bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             const CallInterfaceDescriptor& descriptor,
31bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             Code::Flags flags, const char* name,
32bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             size_t result_size)
33bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    : CodeAssembler(
34bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          isolate, zone,
35bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          Linkage::GetStubCallDescriptor(
36bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              isolate, zone, descriptor, descriptor.GetStackParameterCount(),
37bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              CallDescriptor::kNoFlags, Operator::kNoProperties,
38bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              MachineType::AnyTagged(), result_size),
39bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          flags, name) {}
40bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
41bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone, int parameter_count,
42bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             Code::Flags flags, const char* name)
43bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    : CodeAssembler(isolate, zone,
44c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                    Linkage::GetJSCallDescriptor(
45c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                        zone, false, parameter_count,
46c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                        Code::ExtractKindFromFlags(flags) == Code::BUILTIN
47c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                            ? CallDescriptor::kPushArgumentCount
48c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                            : CallDescriptor::kNoFlags),
49bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                    flags, name) {}
50bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
51bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone,
52bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             CallDescriptor* call_descriptor, Code::Flags flags,
53bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             const char* name)
54bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    : raw_assembler_(new RawMachineAssembler(
55bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          isolate, new (zone) Graph(zone), call_descriptor,
56bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          MachineType::PointerRepresentation(),
57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          InstructionSelector::SupportedMachineOperatorFlags(),
58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          InstructionSelector::AlignmentRequirements())),
59bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      flags_(flags),
60bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      name_(name),
61bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      code_generated_(false),
62bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      variables_(zone) {}
63bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
64bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeAssembler::~CodeAssembler() {}
65bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
66bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::CallPrologue() {}
67bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
68bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::CallEpilogue() {}
69bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
70bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochHandle<Code> CodeAssembler::GenerateCode() {
71bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(!code_generated_);
72bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
73bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Schedule* schedule = raw_assembler_->Export();
74bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Handle<Code> code = Pipeline::GenerateCodeForCodeStub(
75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), raw_assembler_->call_descriptor(), raw_assembler_->graph(),
76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      schedule, flags_, name_);
77bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
78bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  code_generated_ = true;
79bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return code;
80bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
81bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
82bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool CodeAssembler::Is64() const { return raw_assembler_->machine()->Is64(); }
83bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
84bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool CodeAssembler::IsFloat64RoundUpSupported() const {
85bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->machine()->Float64RoundUp().IsSupported();
86bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
87bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
88bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool CodeAssembler::IsFloat64RoundDownSupported() const {
89bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->machine()->Float64RoundDown().IsSupported();
90bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
91bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
92c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool CodeAssembler::IsFloat64RoundTiesEvenSupported() const {
93c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return raw_assembler_->machine()->Float64RoundTiesEven().IsSupported();
94c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
95c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
96bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool CodeAssembler::IsFloat64RoundTruncateSupported() const {
97bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->machine()->Float64RoundTruncate().IsSupported();
98bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
99bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
100bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Int32Constant(int32_t value) {
101bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Int32Constant(value);
102bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
103bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
104bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Int64Constant(int64_t value) {
105bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Int64Constant(value);
106bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
108bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::IntPtrConstant(intptr_t value) {
109bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->IntPtrConstant(value);
110bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
111bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::NumberConstant(double value) {
113bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->NumberConstant(value);
114bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
115bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
116bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::SmiConstant(Smi* value) {
117c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return BitcastWordToTaggedSigned(IntPtrConstant(bit_cast<intptr_t>(value)));
118c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
119c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
120c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochNode* CodeAssembler::SmiConstant(int value) {
121c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return SmiConstant(Smi::FromInt(value));
122bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
123bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
124bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::HeapConstant(Handle<HeapObject> object) {
125bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->HeapConstant(object);
126bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
128bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::BooleanConstant(bool value) {
129bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->BooleanConstant(value);
130bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
131bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
132bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::ExternalConstant(ExternalReference address) {
133bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->ExternalConstant(address);
134bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
135bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
136bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Float64Constant(double value) {
137bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Float64Constant(value);
138bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
139bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
140bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::NaNConstant() {
141bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return LoadRoot(Heap::kNanValueRootIndex);
142bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
143bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
144bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool CodeAssembler::ToInt32Constant(Node* node, int32_t& out_value) {
145bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Int64Matcher m(node);
146bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (m.HasValue() &&
147bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      m.IsInRange(std::numeric_limits<int32_t>::min(),
148bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                  std::numeric_limits<int32_t>::max())) {
149bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    out_value = static_cast<int32_t>(m.Value());
150bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return true;
151bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
152bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return false;
154bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
155bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
156bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool CodeAssembler::ToInt64Constant(Node* node, int64_t& out_value) {
157bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Int64Matcher m(node);
158bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (m.HasValue()) out_value = m.Value();
159bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return m.HasValue();
160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
161bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
162c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool CodeAssembler::ToSmiConstant(Node* node, Smi*& out_value) {
163c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (node->opcode() == IrOpcode::kBitcastWordToTaggedSigned) {
164c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    node = node->InputAt(0);
165c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
166c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return false;
167c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
168c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  IntPtrMatcher m(node);
169c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (m.HasValue()) {
170c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    out_value = Smi::cast(bit_cast<Object*>(m.Value()));
171c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return true;
172c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
173c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return false;
174c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
175c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
176bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool CodeAssembler::ToIntPtrConstant(Node* node, intptr_t& out_value) {
177bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  IntPtrMatcher m(node);
178bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (m.HasValue()) out_value = m.Value();
179bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return m.HasValue();
180bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
181bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
182bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Parameter(int value) {
183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Parameter(value);
184bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
185bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
186bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::Return(Node* value) {
187bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Return(value);
188bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
189bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
190c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid CodeAssembler::PopAndReturn(Node* pop, Node* value) {
191c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return raw_assembler_->PopAndReturn(pop, value);
192c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
193c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
19413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid CodeAssembler::DebugBreak() { raw_assembler_->DebugBreak(); }
19513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
19613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid CodeAssembler::Comment(const char* format, ...) {
19713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (!FLAG_code_comments) return;
19813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  char buffer[4 * KB];
19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  StringBuilder builder(buffer, arraysize(buffer));
20013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  va_list arguments;
20113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  va_start(arguments, format);
20213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  builder.AddFormattedList(format, arguments);
20313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  va_end(arguments);
20413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Copy the string before recording it in the assembler to avoid
20613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // issues when the stack allocated buffer goes out of scope.
20713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const int prefix_len = 2;
20813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int length = builder.position() + 1;
20913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  char* copy = reinterpret_cast<char*>(malloc(length + prefix_len));
21013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  MemCopy(copy + prefix_len, builder.Finalize(), length);
21113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  copy[0] = ';';
21213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  copy[1] = ' ';
21313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  raw_assembler_->Comment(copy);
21413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
21513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::Bind(CodeAssembler::Label* label) { return label->Bind(); }
217bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
218bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::LoadFramePointer() {
219bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->LoadFramePointer();
220bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
222bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::LoadParentFramePointer() {
223bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->LoadParentFramePointer();
224bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
225bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
226bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::LoadStackPointer() {
227bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->LoadStackPointer();
228bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
229bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
230bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define DEFINE_CODE_ASSEMBLER_BINARY_OP(name)   \
231bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* CodeAssembler::name(Node* a, Node* b) { \
232bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return raw_assembler_->name(a, b);          \
233bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
234bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCODE_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_ASSEMBLER_BINARY_OP)
235bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#undef DEFINE_CODE_ASSEMBLER_BINARY_OP
236bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::WordShl(Node* value, int shift) {
238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return (shift != 0) ? raw_assembler_->WordShl(value, IntPtrConstant(shift))
239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      : value;
240bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::WordShr(Node* value, int shift) {
243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return (shift != 0) ? raw_assembler_->WordShr(value, IntPtrConstant(shift))
244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      : value;
245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::Word32Shr(Node* value, int shift) {
248c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return (shift != 0) ? raw_assembler_->Word32Shr(value, Int32Constant(shift))
249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      : value;
250bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
251bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
252bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::ChangeUint32ToWord(Node* value) {
253bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (raw_assembler_->machine()->Is64()) {
254bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    value = raw_assembler_->ChangeUint32ToUint64(value);
255bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
256bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return value;
257bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
258bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
259bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::ChangeInt32ToIntPtr(Node* value) {
260bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (raw_assembler_->machine()->Is64()) {
261bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    value = raw_assembler_->ChangeInt32ToInt64(value);
262bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
263bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return value;
264bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
265bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochNode* CodeAssembler::RoundIntPtrToFloat64(Node* value) {
267f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (raw_assembler_->machine()->Is64()) {
268f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return raw_assembler_->RoundInt64ToFloat64(value);
269f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return raw_assembler_->ChangeInt32ToFloat64(value);
271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
273bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define DEFINE_CODE_ASSEMBLER_UNARY_OP(name) \
274bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* CodeAssembler::name(Node* a) { return raw_assembler_->name(a); }
275bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCODE_ASSEMBLER_UNARY_OP_LIST(DEFINE_CODE_ASSEMBLER_UNARY_OP)
276bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#undef DEFINE_CODE_ASSEMBLER_UNARY_OP
277bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
278bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Load(MachineType rep, Node* base) {
279bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Load(rep, base);
280bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
281bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
282bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Load(MachineType rep, Node* base, Node* index) {
283bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Load(rep, base, index);
284bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
285bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
286bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::AtomicLoad(MachineType rep, Node* base, Node* index) {
287bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->AtomicLoad(rep, base, index);
288bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
289bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
290bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::LoadRoot(Heap::RootListIndex root_index) {
291bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) {
292bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Handle<Object> root = isolate()->heap()->root_handle(root_index);
293bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (root->IsSmi()) {
294bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return SmiConstant(Smi::cast(*root));
295bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    } else {
296bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return HeapConstant(Handle<HeapObject>::cast(root));
297bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
298bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
299bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
300bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* roots_array_start =
301bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ExternalConstant(ExternalReference::roots_array_start(isolate()));
302bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return Load(MachineType::AnyTagged(), roots_array_start,
303bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              IntPtrConstant(root_index * kPointerSize));
304bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
305bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
306bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* value) {
307bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Store(rep, base, value, kFullWriteBarrier);
308bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
309bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
310bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* index,
311bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           Node* value) {
312bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Store(rep, base, index, value, kFullWriteBarrier);
313bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
314bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
315bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base,
316bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                         Node* value) {
317bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Store(rep, base, value, kNoWriteBarrier);
318bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
319bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
320bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base,
321bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                         Node* index, Node* value) {
322bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Store(rep, base, index, value, kNoWriteBarrier);
323bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
324bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
325bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::AtomicStore(MachineRepresentation rep, Node* base,
326bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 Node* index, Node* value) {
327bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->AtomicStore(rep, base, index, value);
328bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
329bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
330bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::StoreRoot(Heap::RootListIndex root_index, Node* value) {
331bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(Heap::RootCanBeWrittenAfterInitialization(root_index));
332bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* roots_array_start =
333bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ExternalConstant(ExternalReference::roots_array_start(isolate()));
334bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return StoreNoWriteBarrier(MachineRepresentation::kTagged, roots_array_start,
335bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             IntPtrConstant(root_index * kPointerSize), value);
336bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
337bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochNode* CodeAssembler::Retain(Node* value) {
339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return raw_assembler_->Retain(value);
340f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
342bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Projection(int index, Node* value) {
343bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Projection(index, value);
344bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
345bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeAssembler::GotoIfException(Node* node, Label* if_exception,
347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    Variable* exception_var) {
348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Label success(this), exception(this, Label::kDeferred);
349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  success.MergeVariables();
350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  exception.MergeVariables();
351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  raw_assembler_->Continuations(node, success.label_, exception.label_);
354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Bind(&exception);
356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* op = raw_assembler_->common()->IfException();
357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* exception_value = raw_assembler_->AddNode(op, node, node);
358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (exception_var != nullptr) {
359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    exception_var->Bind(exception_value);
360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Goto(if_exception);
362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Bind(&success);
364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
366bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
367bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           Node** args) {
368bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallPrologue();
369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* return_value = raw_assembler_->CallN(descriptor, code_target, args);
370bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallEpilogue();
371bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return return_value;
372bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
373bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
374bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallN(CallDescriptor* descriptor, Node* code_target,
375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                               Node** args) {
376bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallN(descriptor, code_target, args);
377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
379bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallRuntime(Runtime::FunctionId function_id,
380bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 Node* context) {
381bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallPrologue();
382bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* return_value = raw_assembler_->CallRuntime0(function_id, context);
383bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallEpilogue();
384bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return return_value;
385bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
386bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
387bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context,
388bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 Node* arg1) {
389bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallPrologue();
390bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* return_value = raw_assembler_->CallRuntime1(function_id, arg1, context);
391bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallEpilogue();
392bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return return_value;
393bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
394bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
395bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context,
396bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 Node* arg1, Node* arg2) {
397bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallPrologue();
398bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* return_value =
399bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      raw_assembler_->CallRuntime2(function_id, arg1, arg2, context);
400bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallEpilogue();
401bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return return_value;
402bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
403bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
404bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context,
405bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 Node* arg1, Node* arg2, Node* arg3) {
406bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallPrologue();
407bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* return_value =
408bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      raw_assembler_->CallRuntime3(function_id, arg1, arg2, arg3, context);
409bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallEpilogue();
410bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return return_value;
411bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
412bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
413bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context,
414bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 Node* arg1, Node* arg2, Node* arg3,
415bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 Node* arg4) {
416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallPrologue();
417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* return_value = raw_assembler_->CallRuntime4(function_id, arg1, arg2,
418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                                    arg3, arg4, context);
419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallEpilogue();
420bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return return_value;
421bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
422bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
423c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochNode* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context,
424c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                 Node* arg1, Node* arg2, Node* arg3, Node* arg4,
425c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                 Node* arg5) {
426c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  CallPrologue();
427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* return_value = raw_assembler_->CallRuntime5(function_id, arg1, arg2,
428c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                                    arg3, arg4, arg5, context);
429c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  CallEpilogue();
430c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return return_value;
431c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
432c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
433bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id,
434bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     Node* context) {
435bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallRuntime0(function_id, context);
436bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
437bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
438bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id,
439bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     Node* context, Node* arg1) {
440bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallRuntime1(function_id, arg1, context);
441bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
442bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
443bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id,
444bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     Node* context, Node* arg1, Node* arg2) {
445bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallRuntime2(function_id, arg1, arg2, context);
446bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
447bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
448bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id,
449bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     Node* context, Node* arg1, Node* arg2,
450bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     Node* arg3) {
451bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallRuntime3(function_id, arg1, arg2, arg3,
452bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                          context);
453bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
454bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
455bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id,
456bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     Node* context, Node* arg1, Node* arg2,
457bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                     Node* arg3, Node* arg4) {
458bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallRuntime4(function_id, arg1, arg2, arg3, arg4,
459bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                          context);
460bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
461bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
462f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id,
463f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     Node* context, Node* arg1, Node* arg2,
464f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     Node* arg3, Node* arg4, Node* arg5) {
465f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return raw_assembler_->TailCallRuntime5(function_id, arg1, arg2, arg3, arg4,
466f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                          arg5, context);
467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
468f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochNode* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id,
470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     Node* context, Node* arg1, Node* arg2,
471f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     Node* arg3, Node* arg4, Node* arg5,
472f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     Node* arg6) {
473f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return raw_assembler_->TailCallRuntime6(function_id, arg1, arg2, arg3, arg4,
474f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          arg5, arg6, context);
475f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
476f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
477bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallStub(Callable const& callable, Node* context,
478bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* arg1, size_t result_size) {
479bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* target = HeapConstant(callable.code());
480bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return CallStub(callable.descriptor(), target, context, arg1, result_size);
481bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
482bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
483bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallStub(Callable const& callable, Node* context,
484bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* arg1, Node* arg2, size_t result_size) {
485bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* target = HeapConstant(callable.code());
486bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return CallStub(callable.descriptor(), target, context, arg1, arg2,
487bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                  result_size);
488bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
489bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
490bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallStub(Callable const& callable, Node* context,
491bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* arg1, Node* arg2, Node* arg3,
492bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              size_t result_size) {
493bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* target = HeapConstant(callable.code());
494bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return CallStub(callable.descriptor(), target, context, arg1, arg2, arg3,
495bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                  result_size);
496bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
497bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochNode* CodeAssembler::CallStub(Callable const& callable, Node* context,
499f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              Node* arg1, Node* arg2, Node* arg3, Node* arg4,
500f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              size_t result_size) {
501f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* target = HeapConstant(callable.code());
502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return CallStub(callable.descriptor(), target, context, arg1, arg2, arg3,
503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  arg4, result_size);
504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
50613e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* CodeAssembler::CallStubN(Callable const& callable, Node** args,
50713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                               size_t result_size) {
50813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* target = HeapConstant(callable.code());
50913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return CallStubN(callable.descriptor(), target, args, result_size);
51013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
51113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
512bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              Node* target, Node* context, size_t result_size) {
514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineType::AnyTagged(), result_size);
518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node** args = zone()->NewArray<Node*>(1);
520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[0] = context;
521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return CallN(call_descriptor, target, args);
523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
526bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* target, Node* context, Node* arg1,
527bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              size_t result_size) {
528bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
529bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
530bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
531bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      MachineType::AnyTagged(), result_size);
532bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
533bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node** args = zone()->NewArray<Node*>(2);
534bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[0] = arg1;
535bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[1] = context;
536bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
537bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return CallN(call_descriptor, target, args);
538bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
539bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
540bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
541bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* target, Node* context, Node* arg1,
542bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* arg2, size_t result_size) {
543bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
544bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
545bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
546bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      MachineType::AnyTagged(), result_size);
547bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
548bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node** args = zone()->NewArray<Node*>(3);
549bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[0] = arg1;
550bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[1] = arg2;
551bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[2] = context;
552bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
553bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return CallN(call_descriptor, target, args);
554bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
555bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
556bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
557bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* target, Node* context, Node* arg1,
558bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* arg2, Node* arg3, size_t result_size) {
559bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
560bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
561bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
562bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      MachineType::AnyTagged(), result_size);
563bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
564bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node** args = zone()->NewArray<Node*>(4);
565bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[0] = arg1;
566bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[1] = arg2;
567bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[2] = arg3;
568bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[3] = context;
569bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
570bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return CallN(call_descriptor, target, args);
571bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
572bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
573bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
574bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* target, Node* context, Node* arg1,
575bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* arg2, Node* arg3, Node* arg4,
576bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              size_t result_size) {
577bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
578bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
579bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
580bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      MachineType::AnyTagged(), result_size);
581bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
582bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node** args = zone()->NewArray<Node*>(5);
583bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[0] = arg1;
584bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[1] = arg2;
585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[2] = arg3;
586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[3] = arg4;
587bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[4] = context;
588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
589bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return CallN(call_descriptor, target, args);
590bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
591bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
592bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
593bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* target, Node* context, Node* arg1,
594bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              Node* arg2, Node* arg3, Node* arg4, Node* arg5,
595bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              size_t result_size) {
596bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
597bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
598bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
599bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      MachineType::AnyTagged(), result_size);
600bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
601bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node** args = zone()->NewArray<Node*>(6);
602bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[0] = arg1;
603bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[1] = arg2;
604bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[2] = arg3;
605bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[3] = arg4;
606bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[4] = arg5;
607bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[5] = context;
608bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
609bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return CallN(call_descriptor, target, args);
610bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
611bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              Node* target, Node* context, const Arg& arg1,
614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              const Arg& arg2, size_t result_size) {
615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineType::AnyTagged(), result_size);
619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int kArgsCount = 3;
621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node** args = zone()->NewArray<Node*>(kArgsCount);
622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true));
623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg1.index] = arg1.value;
624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg2.index] = arg2.value;
625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[kArgsCount - 1] = context;
626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr));
627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return CallN(call_descriptor, target, args);
629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              Node* target, Node* context, const Arg& arg1,
633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              const Arg& arg2, const Arg& arg3,
634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              size_t result_size) {
635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineType::AnyTagged(), result_size);
639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int kArgsCount = 4;
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node** args = zone()->NewArray<Node*>(kArgsCount);
642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true));
643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg1.index] = arg1.value;
644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg2.index] = arg2.value;
645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg3.index] = arg3.value;
646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[kArgsCount - 1] = context;
647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr));
648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return CallN(call_descriptor, target, args);
650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              Node* target, Node* context, const Arg& arg1,
654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              const Arg& arg2, const Arg& arg3, const Arg& arg4,
655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              size_t result_size) {
656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineType::AnyTagged(), result_size);
660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int kArgsCount = 5;
662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node** args = zone()->NewArray<Node*>(kArgsCount);
663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true));
664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg1.index] = arg1.value;
665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg2.index] = arg2.value;
666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg3.index] = arg3.value;
667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg4.index] = arg4.value;
668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[kArgsCount - 1] = context;
669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr));
670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return CallN(call_descriptor, target, args);
672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              Node* target, Node* context, const Arg& arg1,
676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              const Arg& arg2, const Arg& arg3, const Arg& arg4,
677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              const Arg& arg5, size_t result_size) {
678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineType::AnyTagged(), result_size);
682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int kArgsCount = 6;
684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node** args = zone()->NewArray<Node*>(kArgsCount);
685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true));
686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg1.index] = arg1.value;
687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg2.index] = arg2.value;
688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg3.index] = arg3.value;
689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg4.index] = arg4.value;
690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg5.index] = arg5.value;
691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[kArgsCount - 1] = context;
692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr));
693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return CallN(call_descriptor, target, args);
695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
69713e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               int js_parameter_count, Node* target,
699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               Node** args, size_t result_size) {
70013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      isolate(), zone(), descriptor,
702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      descriptor.GetStackParameterCount() + js_parameter_count,
70313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      CallDescriptor::kNoFlags, Operator::kNoProperties,
70413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      MachineType::AnyTagged(), result_size);
70513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
70613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return CallN(call_descriptor, target, args);
70713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
70813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
709bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  Node* arg1, size_t result_size) {
711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* target = HeapConstant(callable.code());
712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return TailCallStub(callable.descriptor(), target, context, arg1,
713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      result_size);
714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
717bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  Node* arg1, Node* arg2, size_t result_size) {
718bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* target = HeapConstant(callable.code());
719bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return TailCallStub(callable.descriptor(), target, context, arg1, arg2,
720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      result_size);
721bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
722bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
723bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
724bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  Node* arg1, Node* arg2, Node* arg3,
725bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  size_t result_size) {
726bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* target = HeapConstant(callable.code());
727bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return TailCallStub(callable.descriptor(), target, context, arg1, arg2, arg3,
728bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      result_size);
729bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  Node* arg1, Node* arg2, Node* arg3,
733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  Node* arg4, size_t result_size) {
734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* target = HeapConstant(callable.code());
735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return TailCallStub(callable.descriptor(), target, context, arg1, arg2, arg3,
736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      arg4, result_size);
737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
739c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochNode* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
740c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  Node* arg1, Node* arg2, Node* arg3,
741c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  Node* arg4, Node* arg5, size_t result_size) {
742c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* target = HeapConstant(callable.code());
743c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return TailCallStub(callable.descriptor(), target, context, arg1, arg2, arg3,
744c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                      arg4, arg5, result_size);
745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
746c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  Node* target, Node* context, Node* arg1,
749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  size_t result_size) {
750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineType::AnyTagged(), result_size);
754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node** args = zone()->NewArray<Node*>(2);
756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[0] = arg1;
757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[1] = context;
758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return raw_assembler_->TailCallN(call_descriptor, target, args);
760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
762bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
763bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  Node* target, Node* context, Node* arg1,
764bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  Node* arg2, size_t result_size) {
765bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
766bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
767bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      MachineType::AnyTagged(), result_size);
769bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
770bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node** args = zone()->NewArray<Node*>(3);
771bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[0] = arg1;
772bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[1] = arg2;
773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[2] = context;
774bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
775bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallN(call_descriptor, target, args);
776bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
777bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
778bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
779bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  Node* target, Node* context, Node* arg1,
780bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  Node* arg2, Node* arg3, size_t result_size) {
781bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
782bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
783bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
784bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      MachineType::AnyTagged(), result_size);
785bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
786bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node** args = zone()->NewArray<Node*>(4);
787bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[0] = arg1;
788bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[1] = arg2;
789bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[2] = arg3;
790bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  args[3] = context;
791bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
792bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallN(call_descriptor, target, args);
793bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
794bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
79513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
79613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                  Node* target, Node* context, Node* arg1,
79713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                  Node* arg2, Node* arg3, Node* arg4,
79813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                  size_t result_size) {
79913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
80013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
80113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
80213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      MachineType::AnyTagged(), result_size);
80313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
80413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node** args = zone()->NewArray<Node*>(5);
80513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[0] = arg1;
80613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[1] = arg2;
80713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[2] = arg3;
80813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[3] = arg4;
80913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[4] = context;
81013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
81113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return raw_assembler_->TailCallN(call_descriptor, target, args);
81213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
81313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  Node* target, Node* context, Node* arg1,
816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  Node* arg2, Node* arg3, Node* arg4,
817f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  Node* arg5, size_t result_size) {
818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
819f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
820f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
821f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      MachineType::AnyTagged(), result_size);
822f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
823f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node** args = zone()->NewArray<Node*>(6);
824f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  args[0] = arg1;
825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  args[1] = arg2;
826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  args[2] = arg3;
827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  args[3] = arg4;
828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  args[4] = arg5;
829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  args[5] = context;
830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return raw_assembler_->TailCallN(call_descriptor, target, args);
832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochNode* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
835c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  Node* target, Node* context, Node* arg1,
836c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  Node* arg2, Node* arg3, Node* arg4,
837c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  Node* arg5, Node* arg6, size_t result_size) {
838c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
839c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
840c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      MachineType::AnyTagged(), result_size);
842c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
843c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node** args = zone()->NewArray<Node*>(7);
844c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[0] = arg1;
845c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[1] = arg2;
846c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[2] = arg3;
847c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[3] = arg4;
848c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[4] = arg5;
849c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[5] = arg6;
850c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[6] = context;
851c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
852c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return raw_assembler_->TailCallN(call_descriptor, target, args);
853c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
854c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
855c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochNode* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  Node* target, Node* context, const Arg& arg1,
857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  const Arg& arg2, const Arg& arg3,
858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  const Arg& arg4, size_t result_size) {
859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
862f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineType::AnyTagged(), result_size);
863f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
864f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int kArgsCount = 5;
865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node** args = zone()->NewArray<Node*>(kArgsCount);
866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true));
867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg1.index] = arg1.value;
868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg2.index] = arg2.value;
869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg3.index] = arg3.value;
870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg4.index] = arg4.value;
871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[kArgsCount - 1] = context;
872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr));
873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return raw_assembler_->TailCallN(call_descriptor, target, args);
875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  Node* target, Node* context, const Arg& arg1,
879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  const Arg& arg2, const Arg& arg3,
880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  const Arg& arg4, const Arg& arg5,
881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  size_t result_size) {
882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineType::AnyTagged(), result_size);
886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int kArgsCount = 6;
888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node** args = zone()->NewArray<Node*>(kArgsCount);
889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true));
890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg1.index] = arg1.value;
891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg2.index] = arg2.value;
892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg3.index] = arg3.value;
893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg4.index] = arg4.value;
894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[arg5.index] = arg5.value;
895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args[kArgsCount - 1] = context;
896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr));
897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return raw_assembler_->TailCallN(call_descriptor, target, args);
899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
901bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::TailCallBytecodeDispatch(
902bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    const CallInterfaceDescriptor& interface_descriptor,
903bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Node* code_target_address, Node** args) {
904bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* descriptor = Linkage::GetBytecodeDispatchCallDescriptor(
905bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate(), zone(), interface_descriptor,
906bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      interface_descriptor.GetStackParameterCount());
907bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->TailCallN(descriptor, code_target_address, args);
908bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
909bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
91013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* CodeAssembler::CallJS(Callable const& callable, Node* context,
91113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            Node* function, Node* receiver,
91213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            size_t result_size) {
91313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const int argc = 0;
91413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* target = HeapConstant(callable.code());
91513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
91613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node** args = zone()->NewArray<Node*>(argc + 4);
91713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[0] = function;
91813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[1] = Int32Constant(argc);
91913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[2] = receiver;
92013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[3] = context;
92113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return CallStubN(callable.descriptor(), argc + 1, target, args, result_size);
92313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
92413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
92513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* CodeAssembler::CallJS(Callable const& callable, Node* context,
92613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            Node* function, Node* receiver, Node* arg1,
92713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            size_t result_size) {
92813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const int argc = 1;
92913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* target = HeapConstant(callable.code());
93013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
93113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node** args = zone()->NewArray<Node*>(argc + 4);
93213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[0] = function;
93313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[1] = Int32Constant(argc);
93413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[2] = receiver;
93513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[3] = arg1;
93613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[4] = context;
93713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
938f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return CallStubN(callable.descriptor(), argc + 1, target, args, result_size);
93913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
94013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
94113e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* CodeAssembler::CallJS(Callable const& callable, Node* context,
94213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            Node* function, Node* receiver, Node* arg1,
94313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            Node* arg2, size_t result_size) {
94413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const int argc = 2;
94513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* target = HeapConstant(callable.code());
94613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
94713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node** args = zone()->NewArray<Node*>(argc + 4);
94813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[0] = function;
94913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[1] = Int32Constant(argc);
95013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[2] = receiver;
95113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[3] = arg1;
95213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[4] = arg2;
95313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  args[5] = context;
95413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
955f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return CallStubN(callable.descriptor(), argc + 1, target, args, result_size);
956f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
957f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
958c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochNode* CodeAssembler::CallJS(Callable const& callable, Node* context,
959c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                            Node* function, Node* receiver, Node* arg1,
960c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                            Node* arg2, Node* arg3, size_t result_size) {
961c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const int argc = 3;
962c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* target = HeapConstant(callable.code());
963c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
964c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node** args = zone()->NewArray<Node*>(argc + 4);
965c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[0] = function;
966c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[1] = Int32Constant(argc);
967c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[2] = receiver;
968c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[3] = arg1;
969c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[4] = arg2;
970c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[5] = arg3;
971c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  args[6] = context;
972c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
973c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return CallStubN(callable.descriptor(), argc + 1, target, args, result_size);
974c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
975c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
976f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochNode* CodeAssembler::CallCFunction2(MachineType return_type,
977f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    MachineType arg0_type,
978f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    MachineType arg1_type, Node* function,
979f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    Node* arg0, Node* arg1) {
980f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return raw_assembler_->CallCFunction2(return_type, arg0_type, arg1_type,
981f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                        function, arg0, arg1);
98213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
98313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
984bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::Goto(CodeAssembler::Label* label) {
985bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  label->MergeVariables();
986bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  raw_assembler_->Goto(label->label_);
987bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
988bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
989bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::GotoIf(Node* condition, Label* true_label) {
990bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Label false_label(this);
991bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Branch(condition, true_label, &false_label);
992bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Bind(&false_label);
993bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
994bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
995bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::GotoUnless(Node* condition, Label* false_label) {
996bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Label true_label(this);
997bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Branch(condition, &true_label, false_label);
998bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Bind(&true_label);
999bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1000bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1001bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::Branch(Node* condition, CodeAssembler::Label* true_label,
1002bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           CodeAssembler::Label* false_label) {
1003bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  true_label->MergeVariables();
1004bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  false_label->MergeVariables();
1005bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Branch(condition, true_label->label_,
1006bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                false_label->label_);
1007bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1008bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1009bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::Switch(Node* index, Label* default_label,
1010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           const int32_t* case_values, Label** case_labels,
1011bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           size_t case_count) {
1012bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RawMachineLabel** labels =
1013bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      new (zone()->New(sizeof(RawMachineLabel*) * case_count))
1014bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          RawMachineLabel*[case_count];
1015bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  for (size_t i = 0; i < case_count; ++i) {
1016bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    labels[i] = case_labels[i]->label_;
1017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case_labels[i]->MergeVariables();
1018bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    default_label->MergeVariables();
1019bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1020bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return raw_assembler_->Switch(index, default_label->label_, case_values,
1021bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                labels, case_count);
1022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1023bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* CodeAssembler::Select(Node* condition, Node* true_value,
1025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                            Node* false_value, MachineRepresentation rep) {
1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Variable value(this, rep);
1027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Label vtrue(this), vfalse(this), end(this);
1028f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Branch(condition, &vtrue, &vfalse);
1029f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1030f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Bind(&vtrue);
1031f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  {
1032f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    value.Bind(true_value);
1033f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Goto(&end);
1034f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1035f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Bind(&vfalse);
1036f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  {
1037f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    value.Bind(false_value);
1038f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Goto(&end);
1039f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1040f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1041f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Bind(&end);
1042f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return value.value();
1043f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1044f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1045bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// RawMachineAssembler delegate helpers:
1046bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochIsolate* CodeAssembler::isolate() const { return raw_assembler_->isolate(); }
1047bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1048bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochFactory* CodeAssembler::factory() const { return isolate()->factory(); }
1049bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1050bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochZone* CodeAssembler::zone() const { return raw_assembler_->zone(); }
1051bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1052bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// The core implementation of Variable is stored through an indirection so
1053bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// that it can outlive the often block-scoped Variable declarations. This is
1054bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// needed to ensure that variable binding and merging through phis can
1055bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// properly be verified.
1056bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass CodeAssembler::Variable::Impl : public ZoneObject {
1057bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch public:
1058bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  explicit Impl(MachineRepresentation rep) : value_(nullptr), rep_(rep) {}
1059bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* value_;
1060bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  MachineRepresentation rep_;
1061bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch};
1062bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1063bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeAssembler::Variable::Variable(CodeAssembler* assembler,
1064bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  MachineRepresentation rep)
106513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    : impl_(new (assembler->zone()) Impl(rep)), assembler_(assembler) {
106613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  assembler->variables_.insert(impl_);
1067bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1068bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
106913e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochCodeAssembler::Variable::~Variable() { assembler_->variables_.erase(impl_); }
107013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1071bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::Variable::Bind(Node* value) { impl_->value_ = value; }
1072bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1073bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochNode* CodeAssembler::Variable::value() const {
1074bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK_NOT_NULL(impl_->value_);
1075bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return impl_->value_;
1076bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1077bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1078bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochMachineRepresentation CodeAssembler::Variable::rep() const {
1079bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return impl_->rep_;
1080bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1081bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1082bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool CodeAssembler::Variable::IsBound() const {
1083bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return impl_->value_ != nullptr;
1084bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1085bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1086c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochCodeAssembler::Label::Label(CodeAssembler* assembler, size_t vars_count,
1087c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                            Variable** vars, CodeAssembler::Label::Type type)
1088bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    : bound_(false), merge_count_(0), assembler_(assembler), label_(nullptr) {
1089bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void* buffer = assembler->zone()->New(sizeof(RawMachineLabel));
1090bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  label_ = new (buffer)
1091bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      RawMachineLabel(type == kDeferred ? RawMachineLabel::kDeferred
1092bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                        : RawMachineLabel::kNonDeferred);
1093c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  for (size_t i = 0; i < vars_count; ++i) {
1094c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    variable_phis_[vars[i]->impl_] = nullptr;
1095bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1096bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1097bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1098bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::Label::MergeVariables() {
1099bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ++merge_count_;
1100bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  for (auto var : assembler_->variables_) {
1101bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    size_t count = 0;
1102bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Node* node = var->value_;
1103bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (node != nullptr) {
1104bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      auto i = variable_merges_.find(var);
1105bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (i != variable_merges_.end()) {
1106bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        i->second.push_back(node);
1107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        count = i->second.size();
1108bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      } else {
1109bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        count = 1;
1110bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        variable_merges_[var] = std::vector<Node*>(1, node);
1111bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
1112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1113bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // If the following asserts, then you've jumped to a label without a bound
1114bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // variable along that path that expects to merge its value into a phi.
1115bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(variable_phis_.find(var) == variable_phis_.end() ||
1116bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           count == merge_count_);
1117bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    USE(count);
1118bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1119bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // If the label is already bound, we already know the set of variables to
1120bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // merge and phi nodes have already been created.
1121bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (bound_) {
1122bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      auto phi = variable_phis_.find(var);
1123bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (phi != variable_phis_.end()) {
1124bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK_NOT_NULL(phi->second);
1125bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        assembler_->raw_assembler_->AppendPhiInput(phi->second, node);
1126bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      } else {
1127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        auto i = variable_merges_.find(var);
1128bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (i != variable_merges_.end()) {
1129bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          // If the following assert fires, then you've declared a variable that
1130bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          // has the same bound value along all paths up until the point you
1131bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          // bound this label, but then later merged a path with a new value for
1132bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          // the variable after the label bind (it's not possible to add phis to
1133bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          // the bound label after the fact, just make sure to list the variable
1134bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          // in the label's constructor's list of merged variables).
1135bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          DCHECK(find_if(i->second.begin(), i->second.end(),
1136bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         [node](Node* e) -> bool { return node != e; }) ==
1137bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                 i->second.end());
1138bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        }
1139bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
1140bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1141bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1142bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1143bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1144bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeAssembler::Label::Bind() {
1145bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(!bound_);
1146bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  assembler_->raw_assembler_->Bind(label_);
1147bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1148bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Make sure that all variables that have changed along any path up to this
1149bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // point are marked as merge variables.
1150bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  for (auto var : assembler_->variables_) {
1151bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Node* shared_value = nullptr;
1152bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    auto i = variable_merges_.find(var);
1153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (i != variable_merges_.end()) {
1154bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      for (auto value : i->second) {
1155bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(value != nullptr);
1156bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (value != shared_value) {
1157bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          if (shared_value == nullptr) {
1158bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            shared_value = value;
1159bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          } else {
1160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            variable_phis_[var] = nullptr;
1161bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          }
1162bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        }
1163bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
1164bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1165bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1166bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1167bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  for (auto var : variable_phis_) {
1168bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    CodeAssembler::Variable::Impl* var_impl = var.first;
1169bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    auto i = variable_merges_.find(var_impl);
1170bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // If the following assert fires, then a variable that has been marked as
1171bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // being merged at the label--either by explicitly marking it so in the
1172bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // label constructor or by having seen different bound values at branches
1173bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // into the label--doesn't have a bound value along all of the paths that
1174bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // have been merged into the label up to this point.
1175bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(i != variable_merges_.end() && i->second.size() == merge_count_);
1176bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Node* phi = assembler_->raw_assembler_->Phi(
1177bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        var.first->rep_, static_cast<int>(merge_count_), &(i->second[0]));
1178bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    variable_phis_[var_impl] = phi;
1179bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1180bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1181bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Bind all variables to a merge phi, the common value along all paths or
1182bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // null.
1183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  for (auto var : assembler_->variables_) {
1184bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    auto i = variable_phis_.find(var);
1185bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (i != variable_phis_.end()) {
1186bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      var->value_ = i->second;
1187bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    } else {
1188bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      auto j = variable_merges_.find(var);
1189bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (j != variable_merges_.end() && j->second.size() == merge_count_) {
1190bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        var->value_ = j->second.back();
1191bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      } else {
1192bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        var->value_ = nullptr;
1193bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
1194bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1195bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1196bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bound_ = true;
1198bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1199bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1200bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}  // namespace compiler
1201bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}  // namespace internal
1202bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}  // namespace v8
1203