OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-assembler.h" | 5 #include "src/compiler/code-assembler.h" |
6 | 6 |
7 #include <ostream> | 7 #include <ostream> |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
11 #include "src/compiler/instruction-selector.h" | 11 #include "src/compiler/instruction-selector.h" |
12 #include "src/compiler/linkage.h" | 12 #include "src/compiler/linkage.h" |
13 #include "src/compiler/node-matchers.h" | 13 #include "src/compiler/node-matchers.h" |
14 #include "src/compiler/pipeline.h" | 14 #include "src/compiler/pipeline.h" |
15 #include "src/compiler/raw-machine-assembler.h" | 15 #include "src/compiler/raw-machine-assembler.h" |
16 #include "src/compiler/schedule.h" | 16 #include "src/compiler/schedule.h" |
17 #include "src/frames.h" | 17 #include "src/frames.h" |
18 #include "src/interface-descriptors.h" | 18 #include "src/interface-descriptors.h" |
19 #include "src/interpreter/bytecodes.h" | 19 #include "src/interpreter/bytecodes.h" |
20 #include "src/machine-type.h" | 20 #include "src/machine-type.h" |
21 #include "src/macro-assembler.h" | 21 #include "src/macro-assembler.h" |
22 #include "src/utils.h" | 22 #include "src/utils.h" |
23 #include "src/zone/zone.h" | 23 #include "src/zone/zone.h" |
24 | 24 |
25 namespace v8 { | 25 namespace v8 { |
26 namespace internal { | 26 namespace internal { |
27 namespace compiler { | 27 namespace compiler { |
28 | 28 |
29 CodeAssemblerState::CodeAssemblerState( | 29 CodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone, |
30 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, | 30 const CallInterfaceDescriptor& descriptor, |
31 Code::Flags flags, const char* name, size_t result_size) | 31 Code::Flags flags, const char* name, |
32 : CodeAssemblerState( | 32 size_t result_size) |
| 33 : CodeAssembler( |
33 isolate, zone, | 34 isolate, zone, |
34 Linkage::GetStubCallDescriptor( | 35 Linkage::GetStubCallDescriptor( |
35 isolate, zone, descriptor, descriptor.GetStackParameterCount(), | 36 isolate, zone, descriptor, descriptor.GetStackParameterCount(), |
36 CallDescriptor::kNoFlags, Operator::kNoProperties, | 37 CallDescriptor::kNoFlags, Operator::kNoProperties, |
37 MachineType::AnyTagged(), result_size), | 38 MachineType::AnyTagged(), result_size), |
38 flags, name) {} | 39 flags, name) {} |
39 | 40 |
40 CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone, | 41 CodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone, int parameter_count, |
41 int parameter_count, Code::Flags flags, | 42 Code::Flags flags, const char* name) |
42 const char* name) | 43 : CodeAssembler(isolate, zone, |
43 : CodeAssemblerState(isolate, zone, | 44 Linkage::GetJSCallDescriptor( |
44 Linkage::GetJSCallDescriptor( | 45 zone, false, parameter_count, |
45 zone, false, parameter_count, | 46 Code::ExtractKindFromFlags(flags) == Code::BUILTIN |
46 Code::ExtractKindFromFlags(flags) == Code::BUILTIN | 47 ? CallDescriptor::kPushArgumentCount |
47 ? CallDescriptor::kPushArgumentCount | 48 : CallDescriptor::kNoFlags), |
48 : CallDescriptor::kNoFlags), | 49 flags, name) {} |
49 flags, name) {} | |
50 | 50 |
51 CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone, | 51 CodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone, |
52 CallDescriptor* call_descriptor, | 52 CallDescriptor* call_descriptor, Code::Flags flags, |
53 Code::Flags flags, const char* name) | 53 const char* name) |
54 : raw_assembler_(new RawMachineAssembler( | 54 : raw_assembler_(new RawMachineAssembler( |
55 isolate, new (zone) Graph(zone), call_descriptor, | 55 isolate, new (zone) Graph(zone), call_descriptor, |
56 MachineType::PointerRepresentation(), | 56 MachineType::PointerRepresentation(), |
57 InstructionSelector::SupportedMachineOperatorFlags(), | 57 InstructionSelector::SupportedMachineOperatorFlags(), |
58 InstructionSelector::AlignmentRequirements())), | 58 InstructionSelector::AlignmentRequirements())), |
59 flags_(flags), | 59 flags_(flags), |
60 name_(name), | 60 name_(name), |
61 code_generated_(false), | 61 code_generated_(false), |
62 variables_(zone) {} | 62 variables_(zone) {} |
63 | 63 |
64 CodeAssemblerState::~CodeAssemblerState() {} | |
65 | |
66 CodeAssembler::~CodeAssembler() {} | 64 CodeAssembler::~CodeAssembler() {} |
67 | 65 |
68 void CodeAssembler::CallPrologue() {} | 66 void CodeAssembler::CallPrologue() {} |
69 | 67 |
70 void CodeAssembler::CallEpilogue() {} | 68 void CodeAssembler::CallEpilogue() {} |
71 | 69 |
72 // static | 70 Handle<Code> CodeAssembler::GenerateCode() { |
73 Handle<Code> CodeAssembler::GenerateCode(CodeAssemblerState* state) { | 71 DCHECK(!code_generated_); |
74 DCHECK(!state->code_generated_); | |
75 | 72 |
76 RawMachineAssembler* rasm = state->raw_assembler_.get(); | 73 Schedule* schedule = raw_assembler_->Export(); |
77 Schedule* schedule = rasm->Export(); | |
78 Handle<Code> code = Pipeline::GenerateCodeForCodeStub( | 74 Handle<Code> code = Pipeline::GenerateCodeForCodeStub( |
79 rasm->isolate(), rasm->call_descriptor(), rasm->graph(), schedule, | 75 isolate(), raw_assembler_->call_descriptor(), raw_assembler_->graph(), |
80 state->flags_, state->name_); | 76 schedule, flags_, name_); |
81 | 77 |
82 state->code_generated_ = true; | 78 code_generated_ = true; |
83 return code; | 79 return code; |
84 } | 80 } |
85 | 81 |
86 bool CodeAssembler::Is64() const { return raw_assembler()->machine()->Is64(); } | 82 bool CodeAssembler::Is64() const { return raw_assembler_->machine()->Is64(); } |
87 | 83 |
88 bool CodeAssembler::IsFloat64RoundUpSupported() const { | 84 bool CodeAssembler::IsFloat64RoundUpSupported() const { |
89 return raw_assembler()->machine()->Float64RoundUp().IsSupported(); | 85 return raw_assembler_->machine()->Float64RoundUp().IsSupported(); |
90 } | 86 } |
91 | 87 |
92 bool CodeAssembler::IsFloat64RoundDownSupported() const { | 88 bool CodeAssembler::IsFloat64RoundDownSupported() const { |
93 return raw_assembler()->machine()->Float64RoundDown().IsSupported(); | 89 return raw_assembler_->machine()->Float64RoundDown().IsSupported(); |
94 } | 90 } |
95 | 91 |
96 bool CodeAssembler::IsFloat64RoundTruncateSupported() const { | 92 bool CodeAssembler::IsFloat64RoundTruncateSupported() const { |
97 return raw_assembler()->machine()->Float64RoundTruncate().IsSupported(); | 93 return raw_assembler_->machine()->Float64RoundTruncate().IsSupported(); |
98 } | 94 } |
99 | 95 |
100 Node* CodeAssembler::Int32Constant(int32_t value) { | 96 Node* CodeAssembler::Int32Constant(int32_t value) { |
101 return raw_assembler()->Int32Constant(value); | 97 return raw_assembler_->Int32Constant(value); |
102 } | 98 } |
103 | 99 |
104 Node* CodeAssembler::Int64Constant(int64_t value) { | 100 Node* CodeAssembler::Int64Constant(int64_t value) { |
105 return raw_assembler()->Int64Constant(value); | 101 return raw_assembler_->Int64Constant(value); |
106 } | 102 } |
107 | 103 |
108 Node* CodeAssembler::IntPtrConstant(intptr_t value) { | 104 Node* CodeAssembler::IntPtrConstant(intptr_t value) { |
109 return raw_assembler()->IntPtrConstant(value); | 105 return raw_assembler_->IntPtrConstant(value); |
110 } | 106 } |
111 | 107 |
112 Node* CodeAssembler::NumberConstant(double value) { | 108 Node* CodeAssembler::NumberConstant(double value) { |
113 return raw_assembler()->NumberConstant(value); | 109 return raw_assembler_->NumberConstant(value); |
114 } | 110 } |
115 | 111 |
116 Node* CodeAssembler::SmiConstant(Smi* value) { | 112 Node* CodeAssembler::SmiConstant(Smi* value) { |
117 return BitcastWordToTaggedSigned(IntPtrConstant(bit_cast<intptr_t>(value))); | 113 return BitcastWordToTaggedSigned(IntPtrConstant(bit_cast<intptr_t>(value))); |
118 } | 114 } |
119 | 115 |
120 Node* CodeAssembler::SmiConstant(int value) { | 116 Node* CodeAssembler::SmiConstant(int value) { |
121 return SmiConstant(Smi::FromInt(value)); | 117 return SmiConstant(Smi::FromInt(value)); |
122 } | 118 } |
123 | 119 |
124 Node* CodeAssembler::HeapConstant(Handle<HeapObject> object) { | 120 Node* CodeAssembler::HeapConstant(Handle<HeapObject> object) { |
125 return raw_assembler()->HeapConstant(object); | 121 return raw_assembler_->HeapConstant(object); |
126 } | 122 } |
127 | 123 |
128 Node* CodeAssembler::BooleanConstant(bool value) { | 124 Node* CodeAssembler::BooleanConstant(bool value) { |
129 return raw_assembler()->BooleanConstant(value); | 125 return raw_assembler_->BooleanConstant(value); |
130 } | 126 } |
131 | 127 |
132 Node* CodeAssembler::ExternalConstant(ExternalReference address) { | 128 Node* CodeAssembler::ExternalConstant(ExternalReference address) { |
133 return raw_assembler()->ExternalConstant(address); | 129 return raw_assembler_->ExternalConstant(address); |
134 } | 130 } |
135 | 131 |
136 Node* CodeAssembler::Float64Constant(double value) { | 132 Node* CodeAssembler::Float64Constant(double value) { |
137 return raw_assembler()->Float64Constant(value); | 133 return raw_assembler_->Float64Constant(value); |
138 } | 134 } |
139 | 135 |
140 Node* CodeAssembler::NaNConstant() { | 136 Node* CodeAssembler::NaNConstant() { |
141 return LoadRoot(Heap::kNanValueRootIndex); | 137 return LoadRoot(Heap::kNanValueRootIndex); |
142 } | 138 } |
143 | 139 |
144 bool CodeAssembler::ToInt32Constant(Node* node, int32_t& out_value) { | 140 bool CodeAssembler::ToInt32Constant(Node* node, int32_t& out_value) { |
145 Int64Matcher m(node); | 141 Int64Matcher m(node); |
146 if (m.HasValue() && | 142 if (m.HasValue() && |
147 m.IsInRange(std::numeric_limits<int32_t>::min(), | 143 m.IsInRange(std::numeric_limits<int32_t>::min(), |
(...skipping 25 matching lines...) Expand all Loading... |
173 return false; | 169 return false; |
174 } | 170 } |
175 | 171 |
176 bool CodeAssembler::ToIntPtrConstant(Node* node, intptr_t& out_value) { | 172 bool CodeAssembler::ToIntPtrConstant(Node* node, intptr_t& out_value) { |
177 IntPtrMatcher m(node); | 173 IntPtrMatcher m(node); |
178 if (m.HasValue()) out_value = m.Value(); | 174 if (m.HasValue()) out_value = m.Value(); |
179 return m.HasValue(); | 175 return m.HasValue(); |
180 } | 176 } |
181 | 177 |
182 Node* CodeAssembler::Parameter(int value) { | 178 Node* CodeAssembler::Parameter(int value) { |
183 return raw_assembler()->Parameter(value); | 179 return raw_assembler_->Parameter(value); |
184 } | 180 } |
185 | 181 |
186 void CodeAssembler::Return(Node* value) { | 182 void CodeAssembler::Return(Node* value) { |
187 return raw_assembler()->Return(value); | 183 return raw_assembler_->Return(value); |
188 } | 184 } |
189 | 185 |
190 void CodeAssembler::PopAndReturn(Node* pop, Node* value) { | 186 void CodeAssembler::PopAndReturn(Node* pop, Node* value) { |
191 return raw_assembler()->PopAndReturn(pop, value); | 187 return raw_assembler_->PopAndReturn(pop, value); |
192 } | 188 } |
193 | 189 |
194 void CodeAssembler::DebugBreak() { raw_assembler()->DebugBreak(); } | 190 void CodeAssembler::DebugBreak() { raw_assembler_->DebugBreak(); } |
195 | 191 |
196 void CodeAssembler::Comment(const char* format, ...) { | 192 void CodeAssembler::Comment(const char* format, ...) { |
197 if (!FLAG_code_comments) return; | 193 if (!FLAG_code_comments) return; |
198 char buffer[4 * KB]; | 194 char buffer[4 * KB]; |
199 StringBuilder builder(buffer, arraysize(buffer)); | 195 StringBuilder builder(buffer, arraysize(buffer)); |
200 va_list arguments; | 196 va_list arguments; |
201 va_start(arguments, format); | 197 va_start(arguments, format); |
202 builder.AddFormattedList(format, arguments); | 198 builder.AddFormattedList(format, arguments); |
203 va_end(arguments); | 199 va_end(arguments); |
204 | 200 |
205 // Copy the string before recording it in the assembler to avoid | 201 // Copy the string before recording it in the assembler to avoid |
206 // issues when the stack allocated buffer goes out of scope. | 202 // issues when the stack allocated buffer goes out of scope. |
207 const int prefix_len = 2; | 203 const int prefix_len = 2; |
208 int length = builder.position() + 1; | 204 int length = builder.position() + 1; |
209 char* copy = reinterpret_cast<char*>(malloc(length + prefix_len)); | 205 char* copy = reinterpret_cast<char*>(malloc(length + prefix_len)); |
210 MemCopy(copy + prefix_len, builder.Finalize(), length); | 206 MemCopy(copy + prefix_len, builder.Finalize(), length); |
211 copy[0] = ';'; | 207 copy[0] = ';'; |
212 copy[1] = ' '; | 208 copy[1] = ' '; |
213 raw_assembler()->Comment(copy); | 209 raw_assembler_->Comment(copy); |
214 } | 210 } |
215 | 211 |
216 void CodeAssembler::Bind(CodeAssembler::Label* label) { return label->Bind(); } | 212 void CodeAssembler::Bind(CodeAssembler::Label* label) { return label->Bind(); } |
217 | 213 |
218 Node* CodeAssembler::LoadFramePointer() { | 214 Node* CodeAssembler::LoadFramePointer() { |
219 return raw_assembler()->LoadFramePointer(); | 215 return raw_assembler_->LoadFramePointer(); |
220 } | 216 } |
221 | 217 |
222 Node* CodeAssembler::LoadParentFramePointer() { | 218 Node* CodeAssembler::LoadParentFramePointer() { |
223 return raw_assembler()->LoadParentFramePointer(); | 219 return raw_assembler_->LoadParentFramePointer(); |
224 } | 220 } |
225 | 221 |
226 Node* CodeAssembler::LoadStackPointer() { | 222 Node* CodeAssembler::LoadStackPointer() { |
227 return raw_assembler()->LoadStackPointer(); | 223 return raw_assembler_->LoadStackPointer(); |
228 } | 224 } |
229 | 225 |
230 #define DEFINE_CODE_ASSEMBLER_BINARY_OP(name) \ | 226 #define DEFINE_CODE_ASSEMBLER_BINARY_OP(name) \ |
231 Node* CodeAssembler::name(Node* a, Node* b) { \ | 227 Node* CodeAssembler::name(Node* a, Node* b) { \ |
232 return raw_assembler()->name(a, b); \ | 228 return raw_assembler_->name(a, b); \ |
233 } | 229 } |
234 CODE_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_ASSEMBLER_BINARY_OP) | 230 CODE_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_ASSEMBLER_BINARY_OP) |
235 #undef DEFINE_CODE_ASSEMBLER_BINARY_OP | 231 #undef DEFINE_CODE_ASSEMBLER_BINARY_OP |
236 | 232 |
237 Node* CodeAssembler::WordShl(Node* value, int shift) { | 233 Node* CodeAssembler::WordShl(Node* value, int shift) { |
238 return (shift != 0) ? raw_assembler()->WordShl(value, IntPtrConstant(shift)) | 234 return (shift != 0) ? raw_assembler_->WordShl(value, IntPtrConstant(shift)) |
239 : value; | 235 : value; |
240 } | 236 } |
241 | 237 |
242 Node* CodeAssembler::WordShr(Node* value, int shift) { | 238 Node* CodeAssembler::WordShr(Node* value, int shift) { |
243 return (shift != 0) ? raw_assembler()->WordShr(value, IntPtrConstant(shift)) | 239 return (shift != 0) ? raw_assembler_->WordShr(value, IntPtrConstant(shift)) |
244 : value; | 240 : value; |
245 } | 241 } |
246 | 242 |
247 Node* CodeAssembler::Word32Shr(Node* value, int shift) { | 243 Node* CodeAssembler::Word32Shr(Node* value, int shift) { |
248 return (shift != 0) ? raw_assembler()->Word32Shr(value, Int32Constant(shift)) | 244 return (shift != 0) ? raw_assembler_->Word32Shr(value, Int32Constant(shift)) |
249 : value; | 245 : value; |
250 } | 246 } |
251 | 247 |
252 Node* CodeAssembler::ChangeUint32ToWord(Node* value) { | 248 Node* CodeAssembler::ChangeUint32ToWord(Node* value) { |
253 if (raw_assembler()->machine()->Is64()) { | 249 if (raw_assembler_->machine()->Is64()) { |
254 value = raw_assembler()->ChangeUint32ToUint64(value); | 250 value = raw_assembler_->ChangeUint32ToUint64(value); |
255 } | 251 } |
256 return value; | 252 return value; |
257 } | 253 } |
258 | 254 |
259 Node* CodeAssembler::ChangeInt32ToIntPtr(Node* value) { | 255 Node* CodeAssembler::ChangeInt32ToIntPtr(Node* value) { |
260 if (raw_assembler()->machine()->Is64()) { | 256 if (raw_assembler_->machine()->Is64()) { |
261 value = raw_assembler()->ChangeInt32ToInt64(value); | 257 value = raw_assembler_->ChangeInt32ToInt64(value); |
262 } | 258 } |
263 return value; | 259 return value; |
264 } | 260 } |
265 | 261 |
266 Node* CodeAssembler::RoundIntPtrToFloat64(Node* value) { | 262 Node* CodeAssembler::RoundIntPtrToFloat64(Node* value) { |
267 if (raw_assembler()->machine()->Is64()) { | 263 if (raw_assembler_->machine()->Is64()) { |
268 return raw_assembler()->RoundInt64ToFloat64(value); | 264 return raw_assembler_->RoundInt64ToFloat64(value); |
269 } | 265 } |
270 return raw_assembler()->ChangeInt32ToFloat64(value); | 266 return raw_assembler_->ChangeInt32ToFloat64(value); |
271 } | 267 } |
272 | 268 |
273 #define DEFINE_CODE_ASSEMBLER_UNARY_OP(name) \ | 269 #define DEFINE_CODE_ASSEMBLER_UNARY_OP(name) \ |
274 Node* CodeAssembler::name(Node* a) { return raw_assembler()->name(a); } | 270 Node* CodeAssembler::name(Node* a) { return raw_assembler_->name(a); } |
275 CODE_ASSEMBLER_UNARY_OP_LIST(DEFINE_CODE_ASSEMBLER_UNARY_OP) | 271 CODE_ASSEMBLER_UNARY_OP_LIST(DEFINE_CODE_ASSEMBLER_UNARY_OP) |
276 #undef DEFINE_CODE_ASSEMBLER_UNARY_OP | 272 #undef DEFINE_CODE_ASSEMBLER_UNARY_OP |
277 | 273 |
278 Node* CodeAssembler::Load(MachineType rep, Node* base) { | 274 Node* CodeAssembler::Load(MachineType rep, Node* base) { |
279 return raw_assembler()->Load(rep, base); | 275 return raw_assembler_->Load(rep, base); |
280 } | 276 } |
281 | 277 |
282 Node* CodeAssembler::Load(MachineType rep, Node* base, Node* index) { | 278 Node* CodeAssembler::Load(MachineType rep, Node* base, Node* index) { |
283 return raw_assembler()->Load(rep, base, index); | 279 return raw_assembler_->Load(rep, base, index); |
284 } | 280 } |
285 | 281 |
286 Node* CodeAssembler::AtomicLoad(MachineType rep, Node* base, Node* index) { | 282 Node* CodeAssembler::AtomicLoad(MachineType rep, Node* base, Node* index) { |
287 return raw_assembler()->AtomicLoad(rep, base, index); | 283 return raw_assembler_->AtomicLoad(rep, base, index); |
288 } | 284 } |
289 | 285 |
290 Node* CodeAssembler::LoadRoot(Heap::RootListIndex root_index) { | 286 Node* CodeAssembler::LoadRoot(Heap::RootListIndex root_index) { |
291 if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) { | 287 if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) { |
292 Handle<Object> root = isolate()->heap()->root_handle(root_index); | 288 Handle<Object> root = isolate()->heap()->root_handle(root_index); |
293 if (root->IsSmi()) { | 289 if (root->IsSmi()) { |
294 return SmiConstant(Smi::cast(*root)); | 290 return SmiConstant(Smi::cast(*root)); |
295 } else { | 291 } else { |
296 return HeapConstant(Handle<HeapObject>::cast(root)); | 292 return HeapConstant(Handle<HeapObject>::cast(root)); |
297 } | 293 } |
298 } | 294 } |
299 | 295 |
300 Node* roots_array_start = | 296 Node* roots_array_start = |
301 ExternalConstant(ExternalReference::roots_array_start(isolate())); | 297 ExternalConstant(ExternalReference::roots_array_start(isolate())); |
302 return Load(MachineType::AnyTagged(), roots_array_start, | 298 return Load(MachineType::AnyTagged(), roots_array_start, |
303 IntPtrConstant(root_index * kPointerSize)); | 299 IntPtrConstant(root_index * kPointerSize)); |
304 } | 300 } |
305 | 301 |
306 Node* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* value) { | 302 Node* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* value) { |
307 return raw_assembler()->Store(rep, base, value, kFullWriteBarrier); | 303 return raw_assembler_->Store(rep, base, value, kFullWriteBarrier); |
308 } | 304 } |
309 | 305 |
310 Node* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* index, | 306 Node* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* index, |
311 Node* value) { | 307 Node* value) { |
312 return raw_assembler()->Store(rep, base, index, value, kFullWriteBarrier); | 308 return raw_assembler_->Store(rep, base, index, value, kFullWriteBarrier); |
313 } | 309 } |
314 | 310 |
315 Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base, | 311 Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base, |
316 Node* value) { | 312 Node* value) { |
317 return raw_assembler()->Store(rep, base, value, kNoWriteBarrier); | 313 return raw_assembler_->Store(rep, base, value, kNoWriteBarrier); |
318 } | 314 } |
319 | 315 |
320 Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base, | 316 Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base, |
321 Node* index, Node* value) { | 317 Node* index, Node* value) { |
322 return raw_assembler()->Store(rep, base, index, value, kNoWriteBarrier); | 318 return raw_assembler_->Store(rep, base, index, value, kNoWriteBarrier); |
323 } | 319 } |
324 | 320 |
325 Node* CodeAssembler::AtomicStore(MachineRepresentation rep, Node* base, | 321 Node* CodeAssembler::AtomicStore(MachineRepresentation rep, Node* base, |
326 Node* index, Node* value) { | 322 Node* index, Node* value) { |
327 return raw_assembler()->AtomicStore(rep, base, index, value); | 323 return raw_assembler_->AtomicStore(rep, base, index, value); |
328 } | 324 } |
329 | 325 |
330 Node* CodeAssembler::StoreRoot(Heap::RootListIndex root_index, Node* value) { | 326 Node* CodeAssembler::StoreRoot(Heap::RootListIndex root_index, Node* value) { |
331 DCHECK(Heap::RootCanBeWrittenAfterInitialization(root_index)); | 327 DCHECK(Heap::RootCanBeWrittenAfterInitialization(root_index)); |
332 Node* roots_array_start = | 328 Node* roots_array_start = |
333 ExternalConstant(ExternalReference::roots_array_start(isolate())); | 329 ExternalConstant(ExternalReference::roots_array_start(isolate())); |
334 return StoreNoWriteBarrier(MachineRepresentation::kTagged, roots_array_start, | 330 return StoreNoWriteBarrier(MachineRepresentation::kTagged, roots_array_start, |
335 IntPtrConstant(root_index * kPointerSize), value); | 331 IntPtrConstant(root_index * kPointerSize), value); |
336 } | 332 } |
337 | 333 |
338 Node* CodeAssembler::Retain(Node* value) { | 334 Node* CodeAssembler::Retain(Node* value) { |
339 return raw_assembler()->Retain(value); | 335 return raw_assembler_->Retain(value); |
340 } | 336 } |
341 | 337 |
342 Node* CodeAssembler::Projection(int index, Node* value) { | 338 Node* CodeAssembler::Projection(int index, Node* value) { |
343 return raw_assembler()->Projection(index, value); | 339 return raw_assembler_->Projection(index, value); |
344 } | 340 } |
345 | 341 |
346 void CodeAssembler::GotoIfException(Node* node, Label* if_exception, | 342 void CodeAssembler::GotoIfException(Node* node, Label* if_exception, |
347 Variable* exception_var) { | 343 Variable* exception_var) { |
348 Label success(this), exception(this, Label::kDeferred); | 344 Label success(this), exception(this, Label::kDeferred); |
349 success.MergeVariables(); | 345 success.MergeVariables(); |
350 exception.MergeVariables(); | 346 exception.MergeVariables(); |
351 DCHECK(!node->op()->HasProperty(Operator::kNoThrow)); | 347 DCHECK(!node->op()->HasProperty(Operator::kNoThrow)); |
352 | 348 |
353 raw_assembler()->Continuations(node, success.label_, exception.label_); | 349 raw_assembler_->Continuations(node, success.label_, exception.label_); |
354 | 350 |
355 Bind(&exception); | 351 Bind(&exception); |
356 const Operator* op = raw_assembler()->common()->IfException(); | 352 const Operator* op = raw_assembler_->common()->IfException(); |
357 Node* exception_value = raw_assembler()->AddNode(op, node, node); | 353 Node* exception_value = raw_assembler_->AddNode(op, node, node); |
358 if (exception_var != nullptr) { | 354 if (exception_var != nullptr) { |
359 exception_var->Bind(exception_value); | 355 exception_var->Bind(exception_value); |
360 } | 356 } |
361 Goto(if_exception); | 357 Goto(if_exception); |
362 | 358 |
363 Bind(&success); | 359 Bind(&success); |
364 } | 360 } |
365 | 361 |
366 Node* CodeAssembler::CallN(CallDescriptor* descriptor, Node* code_target, | 362 Node* CodeAssembler::CallN(CallDescriptor* descriptor, Node* code_target, |
367 Node** args) { | 363 Node** args) { |
368 CallPrologue(); | 364 CallPrologue(); |
369 Node* return_value = raw_assembler()->CallN(descriptor, code_target, args); | 365 Node* return_value = raw_assembler_->CallN(descriptor, code_target, args); |
370 CallEpilogue(); | 366 CallEpilogue(); |
371 return return_value; | 367 return return_value; |
372 } | 368 } |
373 | 369 |
374 Node* CodeAssembler::TailCallN(CallDescriptor* descriptor, Node* code_target, | 370 Node* CodeAssembler::TailCallN(CallDescriptor* descriptor, Node* code_target, |
375 Node** args) { | 371 Node** args) { |
376 return raw_assembler()->TailCallN(descriptor, code_target, args); | 372 return raw_assembler_->TailCallN(descriptor, code_target, args); |
377 } | 373 } |
378 | 374 |
379 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, | 375 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, |
380 Node* context) { | 376 Node* context) { |
381 CallPrologue(); | 377 CallPrologue(); |
382 Node* return_value = raw_assembler()->CallRuntime0(function_id, context); | 378 Node* return_value = raw_assembler_->CallRuntime0(function_id, context); |
383 CallEpilogue(); | 379 CallEpilogue(); |
384 return return_value; | 380 return return_value; |
385 } | 381 } |
386 | 382 |
387 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 383 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
388 Node* arg1) { | 384 Node* arg1) { |
389 CallPrologue(); | 385 CallPrologue(); |
390 Node* return_value = | 386 Node* return_value = raw_assembler_->CallRuntime1(function_id, arg1, context); |
391 raw_assembler()->CallRuntime1(function_id, arg1, context); | |
392 CallEpilogue(); | 387 CallEpilogue(); |
393 return return_value; | 388 return return_value; |
394 } | 389 } |
395 | 390 |
396 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 391 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
397 Node* arg1, Node* arg2) { | 392 Node* arg1, Node* arg2) { |
398 CallPrologue(); | 393 CallPrologue(); |
399 Node* return_value = | 394 Node* return_value = |
400 raw_assembler()->CallRuntime2(function_id, arg1, arg2, context); | 395 raw_assembler_->CallRuntime2(function_id, arg1, arg2, context); |
401 CallEpilogue(); | 396 CallEpilogue(); |
402 return return_value; | 397 return return_value; |
403 } | 398 } |
404 | 399 |
405 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 400 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
406 Node* arg1, Node* arg2, Node* arg3) { | 401 Node* arg1, Node* arg2, Node* arg3) { |
407 CallPrologue(); | 402 CallPrologue(); |
408 Node* return_value = | 403 Node* return_value = |
409 raw_assembler()->CallRuntime3(function_id, arg1, arg2, arg3, context); | 404 raw_assembler_->CallRuntime3(function_id, arg1, arg2, arg3, context); |
410 CallEpilogue(); | 405 CallEpilogue(); |
411 return return_value; | 406 return return_value; |
412 } | 407 } |
413 | 408 |
414 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 409 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
415 Node* arg1, Node* arg2, Node* arg3, | 410 Node* arg1, Node* arg2, Node* arg3, |
416 Node* arg4) { | 411 Node* arg4) { |
417 CallPrologue(); | 412 CallPrologue(); |
418 Node* return_value = raw_assembler()->CallRuntime4(function_id, arg1, arg2, | 413 Node* return_value = raw_assembler_->CallRuntime4(function_id, arg1, arg2, |
419 arg3, arg4, context); | 414 arg3, arg4, context); |
420 CallEpilogue(); | 415 CallEpilogue(); |
421 return return_value; | 416 return return_value; |
422 } | 417 } |
423 | 418 |
424 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 419 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
425 Node* arg1, Node* arg2, Node* arg3, Node* arg4, | 420 Node* arg1, Node* arg2, Node* arg3, Node* arg4, |
426 Node* arg5) { | 421 Node* arg5) { |
427 CallPrologue(); | 422 CallPrologue(); |
428 Node* return_value = raw_assembler()->CallRuntime5(function_id, arg1, arg2, | 423 Node* return_value = raw_assembler_->CallRuntime5(function_id, arg1, arg2, |
429 arg3, arg4, arg5, context); | 424 arg3, arg4, arg5, context); |
430 CallEpilogue(); | 425 CallEpilogue(); |
431 return return_value; | 426 return return_value; |
432 } | 427 } |
433 | 428 |
434 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 429 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
435 Node* context) { | 430 Node* context) { |
436 return raw_assembler()->TailCallRuntime0(function_id, context); | 431 return raw_assembler_->TailCallRuntime0(function_id, context); |
437 } | 432 } |
438 | 433 |
439 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 434 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
440 Node* context, Node* arg1) { | 435 Node* context, Node* arg1) { |
441 return raw_assembler()->TailCallRuntime1(function_id, arg1, context); | 436 return raw_assembler_->TailCallRuntime1(function_id, arg1, context); |
442 } | 437 } |
443 | 438 |
444 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 439 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
445 Node* context, Node* arg1, Node* arg2) { | 440 Node* context, Node* arg1, Node* arg2) { |
446 return raw_assembler()->TailCallRuntime2(function_id, arg1, arg2, context); | 441 return raw_assembler_->TailCallRuntime2(function_id, arg1, arg2, context); |
447 } | 442 } |
448 | 443 |
449 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 444 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
450 Node* context, Node* arg1, Node* arg2, | 445 Node* context, Node* arg1, Node* arg2, |
451 Node* arg3) { | 446 Node* arg3) { |
452 return raw_assembler()->TailCallRuntime3(function_id, arg1, arg2, arg3, | 447 return raw_assembler_->TailCallRuntime3(function_id, arg1, arg2, arg3, |
453 context); | 448 context); |
454 } | 449 } |
455 | 450 |
456 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 451 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
457 Node* context, Node* arg1, Node* arg2, | 452 Node* context, Node* arg1, Node* arg2, |
458 Node* arg3, Node* arg4) { | 453 Node* arg3, Node* arg4) { |
459 return raw_assembler()->TailCallRuntime4(function_id, arg1, arg2, arg3, arg4, | 454 return raw_assembler_->TailCallRuntime4(function_id, arg1, arg2, arg3, arg4, |
460 context); | 455 context); |
461 } | 456 } |
462 | 457 |
463 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 458 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
464 Node* context, Node* arg1, Node* arg2, | 459 Node* context, Node* arg1, Node* arg2, |
465 Node* arg3, Node* arg4, Node* arg5) { | 460 Node* arg3, Node* arg4, Node* arg5) { |
466 return raw_assembler()->TailCallRuntime5(function_id, arg1, arg2, arg3, arg4, | 461 return raw_assembler_->TailCallRuntime5(function_id, arg1, arg2, arg3, arg4, |
467 arg5, context); | 462 arg5, context); |
468 } | 463 } |
469 | 464 |
470 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 465 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
471 Node* context, Node* arg1, Node* arg2, | 466 Node* context, Node* arg1, Node* arg2, |
472 Node* arg3, Node* arg4, Node* arg5, | 467 Node* arg3, Node* arg4, Node* arg5, |
473 Node* arg6) { | 468 Node* arg6) { |
474 return raw_assembler()->TailCallRuntime6(function_id, arg1, arg2, arg3, arg4, | 469 return raw_assembler_->TailCallRuntime6(function_id, arg1, arg2, arg3, arg4, |
475 arg5, arg6, context); | 470 arg5, arg6, context); |
476 } | 471 } |
477 | 472 |
478 Node* CodeAssembler::CallStub(Callable const& callable, Node* context, | 473 Node* CodeAssembler::CallStub(Callable const& callable, Node* context, |
479 Node* arg1, size_t result_size) { | 474 Node* arg1, size_t result_size) { |
480 Node* target = HeapConstant(callable.code()); | 475 Node* target = HeapConstant(callable.code()); |
481 return CallStub(callable.descriptor(), target, context, arg1, result_size); | 476 return CallStub(callable.descriptor(), target, context, arg1, result_size); |
482 } | 477 } |
483 | 478 |
484 Node* CodeAssembler::CallStub(Callable const& callable, Node* context, | 479 Node* CodeAssembler::CallStub(Callable const& callable, Node* context, |
485 Node* arg1, Node* arg2, size_t result_size) { | 480 Node* arg1, Node* arg2, size_t result_size) { |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 size_t result_size) { | 745 size_t result_size) { |
751 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 746 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
752 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 747 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
753 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 748 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
754 MachineType::AnyTagged(), result_size); | 749 MachineType::AnyTagged(), result_size); |
755 | 750 |
756 Node** args = zone()->NewArray<Node*>(2); | 751 Node** args = zone()->NewArray<Node*>(2); |
757 args[0] = arg1; | 752 args[0] = arg1; |
758 args[1] = context; | 753 args[1] = context; |
759 | 754 |
760 return raw_assembler()->TailCallN(call_descriptor, target, args); | 755 return raw_assembler_->TailCallN(call_descriptor, target, args); |
761 } | 756 } |
762 | 757 |
763 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 758 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
764 Node* target, Node* context, Node* arg1, | 759 Node* target, Node* context, Node* arg1, |
765 Node* arg2, size_t result_size) { | 760 Node* arg2, size_t result_size) { |
766 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 761 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
767 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 762 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
768 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 763 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
769 MachineType::AnyTagged(), result_size); | 764 MachineType::AnyTagged(), result_size); |
770 | 765 |
771 Node** args = zone()->NewArray<Node*>(3); | 766 Node** args = zone()->NewArray<Node*>(3); |
772 args[0] = arg1; | 767 args[0] = arg1; |
773 args[1] = arg2; | 768 args[1] = arg2; |
774 args[2] = context; | 769 args[2] = context; |
775 | 770 |
776 return raw_assembler()->TailCallN(call_descriptor, target, args); | 771 return raw_assembler_->TailCallN(call_descriptor, target, args); |
777 } | 772 } |
778 | 773 |
779 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 774 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
780 Node* target, Node* context, Node* arg1, | 775 Node* target, Node* context, Node* arg1, |
781 Node* arg2, Node* arg3, size_t result_size) { | 776 Node* arg2, Node* arg3, size_t result_size) { |
782 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 777 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
783 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 778 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
784 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 779 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
785 MachineType::AnyTagged(), result_size); | 780 MachineType::AnyTagged(), result_size); |
786 | 781 |
787 Node** args = zone()->NewArray<Node*>(4); | 782 Node** args = zone()->NewArray<Node*>(4); |
788 args[0] = arg1; | 783 args[0] = arg1; |
789 args[1] = arg2; | 784 args[1] = arg2; |
790 args[2] = arg3; | 785 args[2] = arg3; |
791 args[3] = context; | 786 args[3] = context; |
792 | 787 |
793 return raw_assembler()->TailCallN(call_descriptor, target, args); | 788 return raw_assembler_->TailCallN(call_descriptor, target, args); |
794 } | 789 } |
795 | 790 |
796 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 791 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
797 Node* target, Node* context, Node* arg1, | 792 Node* target, Node* context, Node* arg1, |
798 Node* arg2, Node* arg3, Node* arg4, | 793 Node* arg2, Node* arg3, Node* arg4, |
799 size_t result_size) { | 794 size_t result_size) { |
800 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 795 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
801 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 796 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
802 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 797 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
803 MachineType::AnyTagged(), result_size); | 798 MachineType::AnyTagged(), result_size); |
804 | 799 |
805 Node** args = zone()->NewArray<Node*>(5); | 800 Node** args = zone()->NewArray<Node*>(5); |
806 args[0] = arg1; | 801 args[0] = arg1; |
807 args[1] = arg2; | 802 args[1] = arg2; |
808 args[2] = arg3; | 803 args[2] = arg3; |
809 args[3] = arg4; | 804 args[3] = arg4; |
810 args[4] = context; | 805 args[4] = context; |
811 | 806 |
812 return raw_assembler()->TailCallN(call_descriptor, target, args); | 807 return raw_assembler_->TailCallN(call_descriptor, target, args); |
813 } | 808 } |
814 | 809 |
815 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 810 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
816 Node* target, Node* context, Node* arg1, | 811 Node* target, Node* context, Node* arg1, |
817 Node* arg2, Node* arg3, Node* arg4, | 812 Node* arg2, Node* arg3, Node* arg4, |
818 Node* arg5, size_t result_size) { | 813 Node* arg5, size_t result_size) { |
819 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 814 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
820 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 815 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
821 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 816 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
822 MachineType::AnyTagged(), result_size); | 817 MachineType::AnyTagged(), result_size); |
823 | 818 |
824 Node** args = zone()->NewArray<Node*>(6); | 819 Node** args = zone()->NewArray<Node*>(6); |
825 args[0] = arg1; | 820 args[0] = arg1; |
826 args[1] = arg2; | 821 args[1] = arg2; |
827 args[2] = arg3; | 822 args[2] = arg3; |
828 args[3] = arg4; | 823 args[3] = arg4; |
829 args[4] = arg5; | 824 args[4] = arg5; |
830 args[5] = context; | 825 args[5] = context; |
831 | 826 |
832 return raw_assembler()->TailCallN(call_descriptor, target, args); | 827 return raw_assembler_->TailCallN(call_descriptor, target, args); |
833 } | 828 } |
834 | 829 |
835 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 830 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
836 Node* target, Node* context, Node* arg1, | 831 Node* target, Node* context, Node* arg1, |
837 Node* arg2, Node* arg3, Node* arg4, | 832 Node* arg2, Node* arg3, Node* arg4, |
838 Node* arg5, Node* arg6, size_t result_size) { | 833 Node* arg5, Node* arg6, size_t result_size) { |
839 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 834 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
840 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 835 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
841 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 836 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
842 MachineType::AnyTagged(), result_size); | 837 MachineType::AnyTagged(), result_size); |
843 | 838 |
844 Node** args = zone()->NewArray<Node*>(7); | 839 Node** args = zone()->NewArray<Node*>(7); |
845 args[0] = arg1; | 840 args[0] = arg1; |
846 args[1] = arg2; | 841 args[1] = arg2; |
847 args[2] = arg3; | 842 args[2] = arg3; |
848 args[3] = arg4; | 843 args[3] = arg4; |
849 args[4] = arg5; | 844 args[4] = arg5; |
850 args[5] = arg6; | 845 args[5] = arg6; |
851 args[6] = context; | 846 args[6] = context; |
852 | 847 |
853 return raw_assembler()->TailCallN(call_descriptor, target, args); | 848 return raw_assembler_->TailCallN(call_descriptor, target, args); |
854 } | 849 } |
855 | 850 |
856 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 851 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
857 Node* target, Node* context, const Arg& arg1, | 852 Node* target, Node* context, const Arg& arg1, |
858 const Arg& arg2, const Arg& arg3, | 853 const Arg& arg2, const Arg& arg3, |
859 const Arg& arg4, size_t result_size) { | 854 const Arg& arg4, size_t result_size) { |
860 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 855 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
861 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 856 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
862 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 857 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
863 MachineType::AnyTagged(), result_size); | 858 MachineType::AnyTagged(), result_size); |
864 | 859 |
865 const int kArgsCount = 5; | 860 const int kArgsCount = 5; |
866 Node** args = zone()->NewArray<Node*>(kArgsCount); | 861 Node** args = zone()->NewArray<Node*>(kArgsCount); |
867 DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true)); | 862 DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true)); |
868 args[arg1.index] = arg1.value; | 863 args[arg1.index] = arg1.value; |
869 args[arg2.index] = arg2.value; | 864 args[arg2.index] = arg2.value; |
870 args[arg3.index] = arg3.value; | 865 args[arg3.index] = arg3.value; |
871 args[arg4.index] = arg4.value; | 866 args[arg4.index] = arg4.value; |
872 args[kArgsCount - 1] = context; | 867 args[kArgsCount - 1] = context; |
873 DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr)); | 868 DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr)); |
874 | 869 |
875 return raw_assembler()->TailCallN(call_descriptor, target, args); | 870 return raw_assembler_->TailCallN(call_descriptor, target, args); |
876 } | 871 } |
877 | 872 |
878 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 873 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
879 Node* target, Node* context, const Arg& arg1, | 874 Node* target, Node* context, const Arg& arg1, |
880 const Arg& arg2, const Arg& arg3, | 875 const Arg& arg2, const Arg& arg3, |
881 const Arg& arg4, const Arg& arg5, | 876 const Arg& arg4, const Arg& arg5, |
882 size_t result_size) { | 877 size_t result_size) { |
883 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 878 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
884 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 879 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
885 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 880 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
886 MachineType::AnyTagged(), result_size); | 881 MachineType::AnyTagged(), result_size); |
887 | 882 |
888 const int kArgsCount = 6; | 883 const int kArgsCount = 6; |
889 Node** args = zone()->NewArray<Node*>(kArgsCount); | 884 Node** args = zone()->NewArray<Node*>(kArgsCount); |
890 DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true)); | 885 DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true)); |
891 args[arg1.index] = arg1.value; | 886 args[arg1.index] = arg1.value; |
892 args[arg2.index] = arg2.value; | 887 args[arg2.index] = arg2.value; |
893 args[arg3.index] = arg3.value; | 888 args[arg3.index] = arg3.value; |
894 args[arg4.index] = arg4.value; | 889 args[arg4.index] = arg4.value; |
895 args[arg5.index] = arg5.value; | 890 args[arg5.index] = arg5.value; |
896 args[kArgsCount - 1] = context; | 891 args[kArgsCount - 1] = context; |
897 DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr)); | 892 DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr)); |
898 | 893 |
899 return raw_assembler()->TailCallN(call_descriptor, target, args); | 894 return raw_assembler_->TailCallN(call_descriptor, target, args); |
900 } | 895 } |
901 | 896 |
902 Node* CodeAssembler::TailCallBytecodeDispatch( | 897 Node* CodeAssembler::TailCallBytecodeDispatch( |
903 const CallInterfaceDescriptor& interface_descriptor, | 898 const CallInterfaceDescriptor& interface_descriptor, |
904 Node* code_target_address, Node** args) { | 899 Node* code_target_address, Node** args) { |
905 CallDescriptor* descriptor = Linkage::GetBytecodeDispatchCallDescriptor( | 900 CallDescriptor* descriptor = Linkage::GetBytecodeDispatchCallDescriptor( |
906 isolate(), zone(), interface_descriptor, | 901 isolate(), zone(), interface_descriptor, |
907 interface_descriptor.GetStackParameterCount()); | 902 interface_descriptor.GetStackParameterCount()); |
908 return raw_assembler()->TailCallN(descriptor, code_target_address, args); | 903 return raw_assembler_->TailCallN(descriptor, code_target_address, args); |
909 } | 904 } |
910 | 905 |
911 Node* CodeAssembler::CallJS(Callable const& callable, Node* context, | 906 Node* CodeAssembler::CallJS(Callable const& callable, Node* context, |
912 Node* function, Node* receiver, | 907 Node* function, Node* receiver, |
913 size_t result_size) { | 908 size_t result_size) { |
914 const int argc = 0; | 909 const int argc = 0; |
915 Node* target = HeapConstant(callable.code()); | 910 Node* target = HeapConstant(callable.code()); |
916 | 911 |
917 Node** args = zone()->NewArray<Node*>(argc + 4); | 912 Node** args = zone()->NewArray<Node*>(argc + 4); |
918 args[0] = function; | 913 args[0] = function; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 args[5] = arg3; | 966 args[5] = arg3; |
972 args[6] = context; | 967 args[6] = context; |
973 | 968 |
974 return CallStubN(callable.descriptor(), argc + 1, target, args, result_size); | 969 return CallStubN(callable.descriptor(), argc + 1, target, args, result_size); |
975 } | 970 } |
976 | 971 |
977 Node* CodeAssembler::CallCFunction2(MachineType return_type, | 972 Node* CodeAssembler::CallCFunction2(MachineType return_type, |
978 MachineType arg0_type, | 973 MachineType arg0_type, |
979 MachineType arg1_type, Node* function, | 974 MachineType arg1_type, Node* function, |
980 Node* arg0, Node* arg1) { | 975 Node* arg0, Node* arg1) { |
981 return raw_assembler()->CallCFunction2(return_type, arg0_type, arg1_type, | 976 return raw_assembler_->CallCFunction2(return_type, arg0_type, arg1_type, |
982 function, arg0, arg1); | 977 function, arg0, arg1); |
983 } | 978 } |
984 | 979 |
985 void CodeAssembler::Goto(CodeAssembler::Label* label) { | 980 void CodeAssembler::Goto(CodeAssembler::Label* label) { |
986 label->MergeVariables(); | 981 label->MergeVariables(); |
987 raw_assembler()->Goto(label->label_); | 982 raw_assembler_->Goto(label->label_); |
988 } | 983 } |
989 | 984 |
990 void CodeAssembler::GotoIf(Node* condition, Label* true_label) { | 985 void CodeAssembler::GotoIf(Node* condition, Label* true_label) { |
991 Label false_label(this); | 986 Label false_label(this); |
992 Branch(condition, true_label, &false_label); | 987 Branch(condition, true_label, &false_label); |
993 Bind(&false_label); | 988 Bind(&false_label); |
994 } | 989 } |
995 | 990 |
996 void CodeAssembler::GotoUnless(Node* condition, Label* false_label) { | 991 void CodeAssembler::GotoUnless(Node* condition, Label* false_label) { |
997 Label true_label(this); | 992 Label true_label(this); |
998 Branch(condition, &true_label, false_label); | 993 Branch(condition, &true_label, false_label); |
999 Bind(&true_label); | 994 Bind(&true_label); |
1000 } | 995 } |
1001 | 996 |
1002 void CodeAssembler::Branch(Node* condition, CodeAssembler::Label* true_label, | 997 void CodeAssembler::Branch(Node* condition, CodeAssembler::Label* true_label, |
1003 CodeAssembler::Label* false_label) { | 998 CodeAssembler::Label* false_label) { |
1004 true_label->MergeVariables(); | 999 true_label->MergeVariables(); |
1005 false_label->MergeVariables(); | 1000 false_label->MergeVariables(); |
1006 return raw_assembler()->Branch(condition, true_label->label_, | 1001 return raw_assembler_->Branch(condition, true_label->label_, |
1007 false_label->label_); | 1002 false_label->label_); |
1008 } | 1003 } |
1009 | 1004 |
1010 void CodeAssembler::Switch(Node* index, Label* default_label, | 1005 void CodeAssembler::Switch(Node* index, Label* default_label, |
1011 const int32_t* case_values, Label** case_labels, | 1006 const int32_t* case_values, Label** case_labels, |
1012 size_t case_count) { | 1007 size_t case_count) { |
1013 RawMachineLabel** labels = | 1008 RawMachineLabel** labels = |
1014 new (zone()->New(sizeof(RawMachineLabel*) * case_count)) | 1009 new (zone()->New(sizeof(RawMachineLabel*) * case_count)) |
1015 RawMachineLabel*[case_count]; | 1010 RawMachineLabel*[case_count]; |
1016 for (size_t i = 0; i < case_count; ++i) { | 1011 for (size_t i = 0; i < case_count; ++i) { |
1017 labels[i] = case_labels[i]->label_; | 1012 labels[i] = case_labels[i]->label_; |
1018 case_labels[i]->MergeVariables(); | 1013 case_labels[i]->MergeVariables(); |
1019 default_label->MergeVariables(); | 1014 default_label->MergeVariables(); |
1020 } | 1015 } |
1021 return raw_assembler()->Switch(index, default_label->label_, case_values, | 1016 return raw_assembler_->Switch(index, default_label->label_, case_values, |
1022 labels, case_count); | 1017 labels, case_count); |
1023 } | 1018 } |
1024 | 1019 |
1025 Node* CodeAssembler::Select(Node* condition, Node* true_value, | 1020 Node* CodeAssembler::Select(Node* condition, Node* true_value, |
1026 Node* false_value, MachineRepresentation rep) { | 1021 Node* false_value, MachineRepresentation rep) { |
1027 Variable value(this, rep); | 1022 Variable value(this, rep); |
1028 Label vtrue(this), vfalse(this), end(this); | 1023 Label vtrue(this), vfalse(this), end(this); |
1029 Branch(condition, &vtrue, &vfalse); | 1024 Branch(condition, &vtrue, &vfalse); |
1030 | 1025 |
1031 Bind(&vtrue); | 1026 Bind(&vtrue); |
1032 { | 1027 { |
1033 value.Bind(true_value); | 1028 value.Bind(true_value); |
1034 Goto(&end); | 1029 Goto(&end); |
1035 } | 1030 } |
1036 Bind(&vfalse); | 1031 Bind(&vfalse); |
1037 { | 1032 { |
1038 value.Bind(false_value); | 1033 value.Bind(false_value); |
1039 Goto(&end); | 1034 Goto(&end); |
1040 } | 1035 } |
1041 | 1036 |
1042 Bind(&end); | 1037 Bind(&end); |
1043 return value.value(); | 1038 return value.value(); |
1044 } | 1039 } |
1045 | 1040 |
1046 // RawMachineAssembler delegate helpers: | 1041 // RawMachineAssembler delegate helpers: |
1047 Isolate* CodeAssembler::isolate() const { return raw_assembler()->isolate(); } | 1042 Isolate* CodeAssembler::isolate() const { return raw_assembler_->isolate(); } |
1048 | 1043 |
1049 Factory* CodeAssembler::factory() const { return isolate()->factory(); } | 1044 Factory* CodeAssembler::factory() const { return isolate()->factory(); } |
1050 | 1045 |
1051 Zone* CodeAssembler::zone() const { return raw_assembler()->zone(); } | 1046 Zone* CodeAssembler::zone() const { return raw_assembler_->zone(); } |
1052 | |
1053 RawMachineAssembler* CodeAssembler::raw_assembler() const { | |
1054 return state_->raw_assembler_.get(); | |
1055 } | |
1056 | 1047 |
1057 // The core implementation of Variable is stored through an indirection so | 1048 // The core implementation of Variable is stored through an indirection so |
1058 // that it can outlive the often block-scoped Variable declarations. This is | 1049 // that it can outlive the often block-scoped Variable declarations. This is |
1059 // needed to ensure that variable binding and merging through phis can | 1050 // needed to ensure that variable binding and merging through phis can |
1060 // properly be verified. | 1051 // properly be verified. |
1061 class CodeAssembler::Variable::Impl : public ZoneObject { | 1052 class CodeAssembler::Variable::Impl : public ZoneObject { |
1062 public: | 1053 public: |
1063 explicit Impl(MachineRepresentation rep) : value_(nullptr), rep_(rep) {} | 1054 explicit Impl(MachineRepresentation rep) : value_(nullptr), rep_(rep) {} |
1064 Node* value_; | 1055 Node* value_; |
1065 MachineRepresentation rep_; | 1056 MachineRepresentation rep_; |
1066 }; | 1057 }; |
1067 | 1058 |
1068 CodeAssembler::Variable::Variable(CodeAssembler* assembler, | 1059 CodeAssembler::Variable::Variable(CodeAssembler* assembler, |
1069 MachineRepresentation rep) | 1060 MachineRepresentation rep) |
1070 : impl_(new (assembler->zone()) Impl(rep)), state_(assembler->state_) { | 1061 : impl_(new (assembler->zone()) Impl(rep)), assembler_(assembler) { |
1071 state_->variables_.insert(impl_); | 1062 assembler->variables_.insert(impl_); |
1072 } | 1063 } |
1073 | 1064 |
1074 CodeAssembler::Variable::~Variable() { state_->variables_.erase(impl_); } | 1065 CodeAssembler::Variable::~Variable() { assembler_->variables_.erase(impl_); } |
1075 | 1066 |
1076 void CodeAssembler::Variable::Bind(Node* value) { impl_->value_ = value; } | 1067 void CodeAssembler::Variable::Bind(Node* value) { impl_->value_ = value; } |
1077 | 1068 |
1078 Node* CodeAssembler::Variable::value() const { | 1069 Node* CodeAssembler::Variable::value() const { |
1079 DCHECK_NOT_NULL(impl_->value_); | 1070 DCHECK_NOT_NULL(impl_->value_); |
1080 return impl_->value_; | 1071 return impl_->value_; |
1081 } | 1072 } |
1082 | 1073 |
1083 MachineRepresentation CodeAssembler::Variable::rep() const { | 1074 MachineRepresentation CodeAssembler::Variable::rep() const { |
1084 return impl_->rep_; | 1075 return impl_->rep_; |
1085 } | 1076 } |
1086 | 1077 |
1087 bool CodeAssembler::Variable::IsBound() const { | 1078 bool CodeAssembler::Variable::IsBound() const { |
1088 return impl_->value_ != nullptr; | 1079 return impl_->value_ != nullptr; |
1089 } | 1080 } |
1090 | 1081 |
1091 CodeAssembler::Label::Label(CodeAssembler* assembler, size_t vars_count, | 1082 CodeAssembler::Label::Label(CodeAssembler* assembler, size_t vars_count, |
1092 Variable** vars, CodeAssembler::Label::Type type) | 1083 Variable** vars, CodeAssembler::Label::Type type) |
1093 : bound_(false), | 1084 : bound_(false), merge_count_(0), assembler_(assembler), label_(nullptr) { |
1094 merge_count_(0), | |
1095 state_(assembler->state_), | |
1096 label_(nullptr) { | |
1097 void* buffer = assembler->zone()->New(sizeof(RawMachineLabel)); | 1085 void* buffer = assembler->zone()->New(sizeof(RawMachineLabel)); |
1098 label_ = new (buffer) | 1086 label_ = new (buffer) |
1099 RawMachineLabel(type == kDeferred ? RawMachineLabel::kDeferred | 1087 RawMachineLabel(type == kDeferred ? RawMachineLabel::kDeferred |
1100 : RawMachineLabel::kNonDeferred); | 1088 : RawMachineLabel::kNonDeferred); |
1101 for (size_t i = 0; i < vars_count; ++i) { | 1089 for (size_t i = 0; i < vars_count; ++i) { |
1102 variable_phis_[vars[i]->impl_] = nullptr; | 1090 variable_phis_[vars[i]->impl_] = nullptr; |
1103 } | 1091 } |
1104 } | 1092 } |
1105 | 1093 |
1106 void CodeAssembler::Label::MergeVariables() { | 1094 void CodeAssembler::Label::MergeVariables() { |
1107 ++merge_count_; | 1095 ++merge_count_; |
1108 for (auto var : state_->variables_) { | 1096 for (auto var : assembler_->variables_) { |
1109 size_t count = 0; | 1097 size_t count = 0; |
1110 Node* node = var->value_; | 1098 Node* node = var->value_; |
1111 if (node != nullptr) { | 1099 if (node != nullptr) { |
1112 auto i = variable_merges_.find(var); | 1100 auto i = variable_merges_.find(var); |
1113 if (i != variable_merges_.end()) { | 1101 if (i != variable_merges_.end()) { |
1114 i->second.push_back(node); | 1102 i->second.push_back(node); |
1115 count = i->second.size(); | 1103 count = i->second.size(); |
1116 } else { | 1104 } else { |
1117 count = 1; | 1105 count = 1; |
1118 variable_merges_[var] = std::vector<Node*>(1, node); | 1106 variable_merges_[var] = std::vector<Node*>(1, node); |
1119 } | 1107 } |
1120 } | 1108 } |
1121 // If the following asserts, then you've jumped to a label without a bound | 1109 // If the following asserts, then you've jumped to a label without a bound |
1122 // variable along that path that expects to merge its value into a phi. | 1110 // variable along that path that expects to merge its value into a phi. |
1123 DCHECK(variable_phis_.find(var) == variable_phis_.end() || | 1111 DCHECK(variable_phis_.find(var) == variable_phis_.end() || |
1124 count == merge_count_); | 1112 count == merge_count_); |
1125 USE(count); | 1113 USE(count); |
1126 | 1114 |
1127 // If the label is already bound, we already know the set of variables to | 1115 // If the label is already bound, we already know the set of variables to |
1128 // merge and phi nodes have already been created. | 1116 // merge and phi nodes have already been created. |
1129 if (bound_) { | 1117 if (bound_) { |
1130 auto phi = variable_phis_.find(var); | 1118 auto phi = variable_phis_.find(var); |
1131 if (phi != variable_phis_.end()) { | 1119 if (phi != variable_phis_.end()) { |
1132 DCHECK_NOT_NULL(phi->second); | 1120 DCHECK_NOT_NULL(phi->second); |
1133 state_->raw_assembler_->AppendPhiInput(phi->second, node); | 1121 assembler_->raw_assembler_->AppendPhiInput(phi->second, node); |
1134 } else { | 1122 } else { |
1135 auto i = variable_merges_.find(var); | 1123 auto i = variable_merges_.find(var); |
1136 if (i != variable_merges_.end()) { | 1124 if (i != variable_merges_.end()) { |
1137 // If the following assert fires, then you've declared a variable that | 1125 // If the following assert fires, then you've declared a variable that |
1138 // has the same bound value along all paths up until the point you | 1126 // has the same bound value along all paths up until the point you |
1139 // bound this label, but then later merged a path with a new value for | 1127 // bound this label, but then later merged a path with a new value for |
1140 // the variable after the label bind (it's not possible to add phis to | 1128 // the variable after the label bind (it's not possible to add phis to |
1141 // the bound label after the fact, just make sure to list the variable | 1129 // the bound label after the fact, just make sure to list the variable |
1142 // in the label's constructor's list of merged variables). | 1130 // in the label's constructor's list of merged variables). |
1143 DCHECK(find_if(i->second.begin(), i->second.end(), | 1131 DCHECK(find_if(i->second.begin(), i->second.end(), |
1144 [node](Node* e) -> bool { return node != e; }) == | 1132 [node](Node* e) -> bool { return node != e; }) == |
1145 i->second.end()); | 1133 i->second.end()); |
1146 } | 1134 } |
1147 } | 1135 } |
1148 } | 1136 } |
1149 } | 1137 } |
1150 } | 1138 } |
1151 | 1139 |
1152 void CodeAssembler::Label::Bind() { | 1140 void CodeAssembler::Label::Bind() { |
1153 DCHECK(!bound_); | 1141 DCHECK(!bound_); |
1154 state_->raw_assembler_->Bind(label_); | 1142 assembler_->raw_assembler_->Bind(label_); |
1155 | 1143 |
1156 // Make sure that all variables that have changed along any path up to this | 1144 // Make sure that all variables that have changed along any path up to this |
1157 // point are marked as merge variables. | 1145 // point are marked as merge variables. |
1158 for (auto var : state_->variables_) { | 1146 for (auto var : assembler_->variables_) { |
1159 Node* shared_value = nullptr; | 1147 Node* shared_value = nullptr; |
1160 auto i = variable_merges_.find(var); | 1148 auto i = variable_merges_.find(var); |
1161 if (i != variable_merges_.end()) { | 1149 if (i != variable_merges_.end()) { |
1162 for (auto value : i->second) { | 1150 for (auto value : i->second) { |
1163 DCHECK(value != nullptr); | 1151 DCHECK(value != nullptr); |
1164 if (value != shared_value) { | 1152 if (value != shared_value) { |
1165 if (shared_value == nullptr) { | 1153 if (shared_value == nullptr) { |
1166 shared_value = value; | 1154 shared_value = value; |
1167 } else { | 1155 } else { |
1168 variable_phis_[var] = nullptr; | 1156 variable_phis_[var] = nullptr; |
1169 } | 1157 } |
1170 } | 1158 } |
1171 } | 1159 } |
1172 } | 1160 } |
1173 } | 1161 } |
1174 | 1162 |
1175 for (auto var : variable_phis_) { | 1163 for (auto var : variable_phis_) { |
1176 CodeAssembler::Variable::Impl* var_impl = var.first; | 1164 CodeAssembler::Variable::Impl* var_impl = var.first; |
1177 auto i = variable_merges_.find(var_impl); | 1165 auto i = variable_merges_.find(var_impl); |
1178 // If the following assert fires, then a variable that has been marked as | 1166 // If the following assert fires, then a variable that has been marked as |
1179 // being merged at the label--either by explicitly marking it so in the | 1167 // being merged at the label--either by explicitly marking it so in the |
1180 // label constructor or by having seen different bound values at branches | 1168 // label constructor or by having seen different bound values at branches |
1181 // into the label--doesn't have a bound value along all of the paths that | 1169 // into the label--doesn't have a bound value along all of the paths that |
1182 // have been merged into the label up to this point. | 1170 // have been merged into the label up to this point. |
1183 DCHECK(i != variable_merges_.end() && i->second.size() == merge_count_); | 1171 DCHECK(i != variable_merges_.end() && i->second.size() == merge_count_); |
1184 Node* phi = state_->raw_assembler_->Phi( | 1172 Node* phi = assembler_->raw_assembler_->Phi( |
1185 var.first->rep_, static_cast<int>(merge_count_), &(i->second[0])); | 1173 var.first->rep_, static_cast<int>(merge_count_), &(i->second[0])); |
1186 variable_phis_[var_impl] = phi; | 1174 variable_phis_[var_impl] = phi; |
1187 } | 1175 } |
1188 | 1176 |
1189 // Bind all variables to a merge phi, the common value along all paths or | 1177 // Bind all variables to a merge phi, the common value along all paths or |
1190 // null. | 1178 // null. |
1191 for (auto var : state_->variables_) { | 1179 for (auto var : assembler_->variables_) { |
1192 auto i = variable_phis_.find(var); | 1180 auto i = variable_phis_.find(var); |
1193 if (i != variable_phis_.end()) { | 1181 if (i != variable_phis_.end()) { |
1194 var->value_ = i->second; | 1182 var->value_ = i->second; |
1195 } else { | 1183 } else { |
1196 auto j = variable_merges_.find(var); | 1184 auto j = variable_merges_.find(var); |
1197 if (j != variable_merges_.end() && j->second.size() == merge_count_) { | 1185 if (j != variable_merges_.end() && j->second.size() == merge_count_) { |
1198 var->value_ = j->second.back(); | 1186 var->value_ = j->second.back(); |
1199 } else { | 1187 } else { |
1200 var->value_ = nullptr; | 1188 var->value_ = nullptr; |
1201 } | 1189 } |
1202 } | 1190 } |
1203 } | 1191 } |
1204 | 1192 |
1205 bound_ = true; | 1193 bound_ = true; |
1206 } | 1194 } |
1207 | 1195 |
1208 } // namespace compiler | 1196 } // namespace compiler |
1209 } // namespace internal | 1197 } // namespace internal |
1210 } // namespace v8 | 1198 } // namespace v8 |
OLD | NEW |