blob: 9fcb8906069e3895040575e2e5a1a3ce13a8377a [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_CODE_STUB_ASSEMBLER_H_
6#define V8_COMPILER_CODE_STUB_ASSEMBLER_H_
7
Ben Murdoch097c5b22016-05-18 11:27:45 +01008#include <map>
9
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010// Clients of this interface shouldn't depend on lots of compiler internals.
11// Do not include anything from src/compiler here!
12#include "src/allocation.h"
13#include "src/builtins.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010014#include "src/heap/heap.h"
15#include "src/machine-type.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000016#include "src/runtime/runtime.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010017#include "src/zone-containers.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018
19namespace v8 {
20namespace internal {
21
Ben Murdochda12d292016-06-02 14:46:10 +010022class Callable;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023class CallInterfaceDescriptor;
24class Isolate;
Ben Murdochda12d292016-06-02 14:46:10 +010025class Factory;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026class Zone;
27
28namespace compiler {
29
30class CallDescriptor;
31class Graph;
32class Node;
33class Operator;
34class RawMachineAssembler;
Ben Murdoch097c5b22016-05-18 11:27:45 +010035class RawMachineLabel;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036class Schedule;
37
Ben Murdochda12d292016-06-02 14:46:10 +010038#define CODE_STUB_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
39 V(Float32Equal) \
40 V(Float32LessThan) \
41 V(Float32LessThanOrEqual) \
42 V(Float32GreaterThan) \
43 V(Float32GreaterThanOrEqual) \
44 V(Float64Equal) \
45 V(Float64LessThan) \
46 V(Float64LessThanOrEqual) \
47 V(Float64GreaterThan) \
48 V(Float64GreaterThanOrEqual) \
49 V(Int32GreaterThan) \
50 V(Int32GreaterThanOrEqual) \
51 V(Int32LessThan) \
52 V(Int32LessThanOrEqual) \
53 V(IntPtrLessThan) \
54 V(IntPtrLessThanOrEqual) \
55 V(Uint32LessThan) \
56 V(UintPtrGreaterThanOrEqual) \
57 V(WordEqual) \
58 V(WordNotEqual) \
59 V(Word32Equal) \
60 V(Word32NotEqual) \
61 V(Word64Equal) \
62 V(Word64NotEqual)
63
64#define CODE_STUB_ASSEMBLER_BINARY_OP_LIST(V) \
65 CODE_STUB_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
66 V(Float64Add) \
67 V(Float64Sub) \
68 V(Float64InsertLowWord32) \
69 V(Float64InsertHighWord32) \
70 V(IntPtrAdd) \
71 V(IntPtrAddWithOverflow) \
72 V(IntPtrSub) \
73 V(IntPtrSubWithOverflow) \
74 V(Int32Add) \
75 V(Int32AddWithOverflow) \
76 V(Int32Sub) \
77 V(Int32Mul) \
78 V(WordOr) \
79 V(WordAnd) \
80 V(WordXor) \
81 V(WordShl) \
82 V(WordShr) \
83 V(WordSar) \
84 V(WordRor) \
85 V(Word32Or) \
86 V(Word32And) \
87 V(Word32Xor) \
88 V(Word32Shl) \
89 V(Word32Shr) \
90 V(Word32Sar) \
91 V(Word32Ror) \
92 V(Word64Or) \
93 V(Word64And) \
94 V(Word64Xor) \
95 V(Word64Shr) \
96 V(Word64Sar) \
97 V(Word64Ror)
98
99#define CODE_STUB_ASSEMBLER_UNARY_OP_LIST(V) \
100 V(Float64Neg) \
101 V(Float64Sqrt) \
102 V(ChangeFloat64ToUint32) \
103 V(ChangeInt32ToFloat64) \
104 V(ChangeInt32ToInt64) \
105 V(ChangeUint32ToFloat64) \
106 V(ChangeUint32ToUint64) \
107 V(Word32Clz)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100108
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000109class CodeStubAssembler {
110 public:
Ben Murdochda12d292016-06-02 14:46:10 +0100111 // Create with CallStub linkage.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100112 // |result_size| specifies the number of results returned by the stub.
113 // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114 CodeStubAssembler(Isolate* isolate, Zone* zone,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100115 const CallInterfaceDescriptor& descriptor,
116 Code::Flags flags, const char* name,
117 size_t result_size = 1);
Ben Murdochda12d292016-06-02 14:46:10 +0100118
119 // Create with JSCall linkage.
120 CodeStubAssembler(Isolate* isolate, Zone* zone, int parameter_count,
121 Code::Flags flags, const char* name);
122
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 virtual ~CodeStubAssembler();
124
125 Handle<Code> GenerateCode();
126
Ben Murdoch097c5b22016-05-18 11:27:45 +0100127 class Label;
128 class Variable {
129 public:
130 explicit Variable(CodeStubAssembler* assembler, MachineRepresentation rep);
131 void Bind(Node* value);
132 Node* value() const;
133 MachineRepresentation rep() const;
134 bool IsBound() const;
135
136 private:
137 friend class CodeStubAssembler;
138 class Impl;
139 Impl* impl_;
140 };
141
Ben Murdochda12d292016-06-02 14:46:10 +0100142 enum AllocationFlag : uint8_t {
143 kNone = 0,
144 kDoubleAlignment = 1,
145 kPretenured = 1 << 1
146 };
147
148 typedef base::Flags<AllocationFlag> AllocationFlags;
149
Ben Murdoch097c5b22016-05-18 11:27:45 +0100150 // ===========================================================================
151 // Base Assembler
152 // ===========================================================================
153
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 // Constants.
155 Node* Int32Constant(int value);
156 Node* IntPtrConstant(intptr_t value);
157 Node* NumberConstant(double value);
Ben Murdochda12d292016-06-02 14:46:10 +0100158 Node* SmiConstant(Smi* value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159 Node* HeapConstant(Handle<HeapObject> object);
160 Node* BooleanConstant(bool value);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100161 Node* ExternalConstant(ExternalReference address);
Ben Murdochda12d292016-06-02 14:46:10 +0100162 Node* Float64Constant(double value);
163 Node* BooleanMapConstant();
164 Node* HeapNumberMapConstant();
165 Node* NullConstant();
166 Node* UndefinedConstant();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000167
168 Node* Parameter(int value);
169 void Return(Node* value);
170
Ben Murdoch097c5b22016-05-18 11:27:45 +0100171 void Bind(Label* label);
172 void Goto(Label* label);
Ben Murdochda12d292016-06-02 14:46:10 +0100173 void GotoIf(Node* condition, Label* true_label);
174 void GotoUnless(Node* condition, Label* false_label);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100175 void Branch(Node* condition, Label* true_label, Label* false_label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176
Ben Murdoch097c5b22016-05-18 11:27:45 +0100177 void Switch(Node* index, Label* default_label, int32_t* case_values,
178 Label** case_labels, size_t case_count);
179
180 // Access to the frame pointer
181 Node* LoadFramePointer();
182 Node* LoadParentFramePointer();
183
184 // Access to the stack pointer
185 Node* LoadStackPointer();
186
187 // Load raw memory location.
188 Node* Load(MachineType rep, Node* base);
189 Node* Load(MachineType rep, Node* base, Node* index);
190
191 // Store value to raw memory location.
192 Node* Store(MachineRepresentation rep, Node* base, Node* value);
193 Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value);
194 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
195 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* index,
196 Node* value);
197
198// Basic arithmetic operations.
199#define DECLARE_CODE_STUB_ASSEMBER_BINARY_OP(name) Node* name(Node* a, Node* b);
200 CODE_STUB_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_STUB_ASSEMBER_BINARY_OP)
201#undef DECLARE_CODE_STUB_ASSEMBER_BINARY_OP
202
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203 Node* WordShl(Node* value, int shift);
204
Ben Murdochda12d292016-06-02 14:46:10 +0100205// Unary
206#define DECLARE_CODE_STUB_ASSEMBER_UNARY_OP(name) Node* name(Node* a);
207 CODE_STUB_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_STUB_ASSEMBER_UNARY_OP)
208#undef DECLARE_CODE_STUB_ASSEMBER_UNARY_OP
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209
Ben Murdoch097c5b22016-05-18 11:27:45 +0100210 // Projections
211 Node* Projection(int index, Node* value);
212
213 // Calls
214 Node* CallRuntime(Runtime::FunctionId function_id, Node* context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000215 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1);
216 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
217 Node* arg2);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100218 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
219 Node* arg2, Node* arg3);
220 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
221 Node* arg2, Node* arg3, Node* arg4);
222 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
223 Node* arg2, Node* arg3, Node* arg4, Node* arg5);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224
Ben Murdochda12d292016-06-02 14:46:10 +0100225 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000226 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
227 Node* arg1);
228 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
229 Node* arg1, Node* arg2);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100230 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
231 Node* arg1, Node* arg2, Node* arg3);
232 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
233 Node* arg1, Node* arg2, Node* arg3, Node* arg4);
234
Ben Murdochda12d292016-06-02 14:46:10 +0100235 Node* CallStub(Callable const& callable, Node* context, Node* arg1,
236 size_t result_size = 1);
237
Ben Murdoch097c5b22016-05-18 11:27:45 +0100238 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
239 Node* context, Node* arg1, size_t result_size = 1);
240 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
241 Node* context, Node* arg1, Node* arg2, size_t result_size = 1);
242 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
243 Node* context, Node* arg1, Node* arg2, Node* arg3,
244 size_t result_size = 1);
245 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
246 Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
247 size_t result_size = 1);
248 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
249 Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
250 Node* arg5, size_t result_size = 1);
251
Ben Murdochda12d292016-06-02 14:46:10 +0100252 Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
253 Node* arg2, size_t result_size = 1);
254
255 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
256 Node* context, Node* arg1, Node* arg2,
257 size_t result_size = 1);
258
Ben Murdoch097c5b22016-05-18 11:27:45 +0100259 Node* TailCall(const CallInterfaceDescriptor& descriptor, Node* target,
260 Node** args, size_t result_size = 1);
261
262 // ===========================================================================
263 // Macros
264 // ===========================================================================
265
Ben Murdochda12d292016-06-02 14:46:10 +0100266 // Float64 operations.
267 Node* Float64Ceil(Node* x);
268 Node* Float64Floor(Node* x);
269 Node* Float64Round(Node* x);
270 Node* Float64Trunc(Node* x);
271
272 // Tag a Word as a Smi value.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100273 Node* SmiTag(Node* value);
Ben Murdochda12d292016-06-02 14:46:10 +0100274 // Untag a Smi value as a Word.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100275 Node* SmiUntag(Node* value);
276
Ben Murdochda12d292016-06-02 14:46:10 +0100277 // Smi conversions.
278 Node* SmiToFloat64(Node* value);
279 Node* SmiToWord32(Node* value);
280
281 // Smi operations.
282 Node* SmiAdd(Node* a, Node* b);
283 Node* SmiAddWithOverflow(Node* a, Node* b);
284 Node* SmiSub(Node* a, Node* b);
285 Node* SmiSubWithOverflow(Node* a, Node* b);
286 Node* SmiEqual(Node* a, Node* b);
287 Node* SmiLessThan(Node* a, Node* b);
288 Node* SmiLessThanOrEqual(Node* a, Node* b);
289 Node* SmiMin(Node* a, Node* b);
290
Ben Murdoch097c5b22016-05-18 11:27:45 +0100291 // Load a value from the root array.
292 Node* LoadRoot(Heap::RootListIndex root_index);
293
294 // Check a value for smi-ness
295 Node* WordIsSmi(Node* a);
296
Ben Murdochda12d292016-06-02 14:46:10 +0100297 // Check that the value is a positive smi.
298 Node* WordIsPositiveSmi(Node* a);
299
Ben Murdoch097c5b22016-05-18 11:27:45 +0100300 // Load an object pointer from a buffer that isn't in the heap.
Ben Murdochda12d292016-06-02 14:46:10 +0100301 Node* LoadBufferObject(Node* buffer, int offset,
302 MachineType rep = MachineType::AnyTagged());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100303 // Load a field from an object on the heap.
Ben Murdochda12d292016-06-02 14:46:10 +0100304 Node* LoadObjectField(Node* object, int offset,
305 MachineType rep = MachineType::AnyTagged());
306 // Load the floating point value of a HeapNumber.
307 Node* LoadHeapNumberValue(Node* object);
308 // Store the floating point value of a HeapNumber.
309 Node* StoreHeapNumberValue(Node* object, Node* value);
310 // Truncate the floating point value of a HeapNumber to an Int32.
311 Node* TruncateHeapNumberValueToWord32(Node* object);
312 // Load the bit field of a Map.
313 Node* LoadMapBitField(Node* map);
314 // Load bit field 2 of a map.
315 Node* LoadMapBitField2(Node* map);
316 // Load bit field 3 of a map.
317 Node* LoadMapBitField3(Node* map);
318 // Load the instance type of a map.
319 Node* LoadMapInstanceType(Node* map);
320 // Load the instance descriptors of a map.
321 Node* LoadMapDescriptors(Node* map);
322
323 // Load the hash field of a name.
324 Node* LoadNameHash(Node* name);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100325
326 // Load an array element from a FixedArray.
Ben Murdochda12d292016-06-02 14:46:10 +0100327 Node* LoadFixedArrayElementInt32Index(Node* object, Node* int32_index,
328 int additional_offset = 0);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100329 Node* LoadFixedArrayElementSmiIndex(Node* object, Node* smi_index,
330 int additional_offset = 0);
331 Node* LoadFixedArrayElementConstantIndex(Node* object, int index);
332
Ben Murdochda12d292016-06-02 14:46:10 +0100333 // Allocate an object of the given size.
334 Node* Allocate(int size, AllocationFlags flags = kNone);
335 // Allocate a HeapNumber without initializing its value.
336 Node* AllocateHeapNumber();
337 // Allocate a HeapNumber with a specific value.
338 Node* AllocateHeapNumberWithValue(Node* value);
339
340 // Store an array element to a FixedArray.
341 Node* StoreFixedArrayElementNoWriteBarrier(Node* object, Node* index,
342 Node* value);
343 // Load the Map of an HeapObject.
344 Node* LoadMap(Node* object);
345 // Store the Map of an HeapObject.
346 Node* StoreMapNoWriteBarrier(Node* object, Node* map);
347 // Load the instance type of an HeapObject.
348 Node* LoadInstanceType(Node* object);
349
350 // Load the elements backing store of a JSObject.
351 Node* LoadElements(Node* object);
352 // Load the length of a fixed array base instance.
353 Node* LoadFixedArrayBaseLength(Node* array);
354
355 // Returns a node that is true if the given bit is set in |word32|.
356 template <typename T>
357 Node* BitFieldDecode(Node* word32) {
358 return BitFieldDecode(word32, T::kShift, T::kMask);
359 }
360
361 Node* BitFieldDecode(Node* word32, uint32_t shift, uint32_t mask);
362
363 // Conversions.
364 Node* ChangeFloat64ToTagged(Node* value);
365 Node* ChangeInt32ToTagged(Node* value);
366 Node* TruncateTaggedToFloat64(Node* context, Node* value);
367 Node* TruncateTaggedToWord32(Node* context, Node* value);
368
369 // Branching helpers.
370 // TODO(danno): Can we be more cleverish wrt. edge-split?
371 void BranchIf(Node* condition, Label* if_true, Label* if_false);
372
373#define BRANCH_HELPER(name) \
374 void BranchIf##name(Node* a, Node* b, Label* if_true, Label* if_false) { \
375 BranchIf(name(a, b), if_true, if_false); \
376 }
377 CODE_STUB_ASSEMBLER_COMPARE_BINARY_OP_LIST(BRANCH_HELPER)
378#undef BRANCH_HELPER
379
380 void BranchIfSmiLessThan(Node* a, Node* b, Label* if_true, Label* if_false) {
381 BranchIf(SmiLessThan(a, b), if_true, if_false);
382 }
383
384 void BranchIfSmiLessThanOrEqual(Node* a, Node* b, Label* if_true,
385 Label* if_false) {
386 BranchIf(SmiLessThanOrEqual(a, b), if_true, if_false);
387 }
388
389 void BranchIfFloat64IsNaN(Node* value, Label* if_true, Label* if_false) {
390 BranchIfFloat64Equal(value, value, if_false, if_true);
391 }
392
393 // Helpers which delegate to RawMachineAssembler.
394 Factory* factory() const;
395 Isolate* isolate() const;
396 Zone* zone() const;
397
Ben Murdoch097c5b22016-05-18 11:27:45 +0100398 protected:
399 // Protected helpers which delegate to RawMachineAssembler.
Ben Murdochda12d292016-06-02 14:46:10 +0100400 Graph* graph() const;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100401
402 // Enables subclasses to perform operations before and after a call.
403 virtual void CallPrologue();
404 virtual void CallEpilogue();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000405
406 private:
407 friend class CodeStubAssemblerTester;
408
Ben Murdochda12d292016-06-02 14:46:10 +0100409 CodeStubAssembler(Isolate* isolate, Zone* zone,
410 CallDescriptor* call_descriptor, Code::Flags flags,
411 const char* name);
412
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413 Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
414 Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args);
415
416 Node* SmiShiftBitsConstant();
417
Ben Murdochda12d292016-06-02 14:46:10 +0100418 Node* AllocateRawAligned(Node* size_in_bytes, AllocationFlags flags,
419 Node* top_address, Node* limit_address);
420 Node* AllocateRawUnaligned(Node* size_in_bytes, AllocationFlags flags,
421 Node* top_adddress, Node* limit_address);
422
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000423 base::SmartPointer<RawMachineAssembler> raw_assembler_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100424 Code::Flags flags_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425 const char* name_;
426 bool code_generated_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100427 ZoneVector<Variable::Impl*> variables_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000428
429 DISALLOW_COPY_AND_ASSIGN(CodeStubAssembler);
430};
431
Ben Murdochda12d292016-06-02 14:46:10 +0100432DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags);
433
Ben Murdoch097c5b22016-05-18 11:27:45 +0100434class CodeStubAssembler::Label {
435 public:
Ben Murdochda12d292016-06-02 14:46:10 +0100436 enum Type { kDeferred, kNonDeferred };
437
438 explicit Label(CodeStubAssembler* assembler,
439 CodeStubAssembler::Label::Type type =
440 CodeStubAssembler::Label::kNonDeferred)
441 : CodeStubAssembler::Label(assembler, 0, nullptr, type) {}
Ben Murdoch097c5b22016-05-18 11:27:45 +0100442 Label(CodeStubAssembler* assembler,
Ben Murdochda12d292016-06-02 14:46:10 +0100443 CodeStubAssembler::Variable* merged_variable,
444 CodeStubAssembler::Label::Type type =
445 CodeStubAssembler::Label::kNonDeferred)
446 : CodeStubAssembler::Label(assembler, 1, &merged_variable, type) {}
447 Label(CodeStubAssembler* assembler, int merged_variable_count,
448 CodeStubAssembler::Variable** merged_variables,
449 CodeStubAssembler::Label::Type type =
450 CodeStubAssembler::Label::kNonDeferred);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100451 ~Label() {}
452
453 private:
454 friend class CodeStubAssembler;
455
456 void Bind();
457 void MergeVariables();
458
459 bool bound_;
460 size_t merge_count_;
461 CodeStubAssembler* assembler_;
462 RawMachineLabel* label_;
463 // Map of variables that need to be merged to their phi nodes (or placeholders
464 // for those phis).
465 std::map<Variable::Impl*, Node*> variable_phis_;
466 // Map of variables to the list of value nodes that have been added from each
467 // merge path in their order of merging.
468 std::map<Variable::Impl*, std::vector<Node*>> variable_merges_;
469};
470
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000471} // namespace compiler
472} // namespace internal
473} // namespace v8
474
475#endif // V8_COMPILER_CODE_STUB_ASSEMBLER_H_