Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_COMPILER_CODE_ASSEMBLER_H_
6 : #define V8_COMPILER_CODE_ASSEMBLER_H_
7 :
8 : #include <map>
9 : #include <memory>
10 :
11 : // Clients of this interface shouldn't depend on lots of compiler internals.
12 : // Do not include anything from src/compiler here!
13 : #include "src/allocation.h"
14 : #include "src/builtins/builtins.h"
15 : #include "src/code-factory.h"
16 : #include "src/globals.h"
17 : #include "src/heap/heap.h"
18 : #include "src/machine-type.h"
19 : #include "src/runtime/runtime.h"
20 : #include "src/zone/zone-containers.h"
21 :
22 : namespace v8 {
23 : namespace internal {
24 :
25 : class Callable;
26 : class CallInterfaceDescriptor;
27 : class Isolate;
28 : class Factory;
29 : class Zone;
30 :
31 : namespace compiler {
32 :
33 : class CallDescriptor;
34 : class CodeAssemblerLabel;
35 : class CodeAssemblerVariable;
36 : class CodeAssemblerState;
37 : class Node;
38 : class RawMachineAssembler;
39 : class RawMachineLabel;
40 :
41 : typedef ZoneList<CodeAssemblerVariable*> CodeAssemblerVariableList;
42 :
43 : typedef std::function<void()> CodeAssemblerCallback;
44 :
45 : #define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
46 : V(Float32Equal) \
47 : V(Float32LessThan) \
48 : V(Float32LessThanOrEqual) \
49 : V(Float32GreaterThan) \
50 : V(Float32GreaterThanOrEqual) \
51 : V(Float64Equal) \
52 : V(Float64LessThan) \
53 : V(Float64LessThanOrEqual) \
54 : V(Float64GreaterThan) \
55 : V(Float64GreaterThanOrEqual) \
56 : V(Int32GreaterThan) \
57 : V(Int32GreaterThanOrEqual) \
58 : V(Int32LessThan) \
59 : V(Int32LessThanOrEqual) \
60 : V(IntPtrLessThan) \
61 : V(IntPtrLessThanOrEqual) \
62 : V(IntPtrGreaterThan) \
63 : V(IntPtrGreaterThanOrEqual) \
64 : V(IntPtrEqual) \
65 : V(Uint32LessThan) \
66 : V(Uint32LessThanOrEqual) \
67 : V(Uint32GreaterThanOrEqual) \
68 : V(UintPtrLessThan) \
69 : V(UintPtrLessThanOrEqual) \
70 : V(UintPtrGreaterThan) \
71 : V(UintPtrGreaterThanOrEqual) \
72 : V(WordEqual) \
73 : V(WordNotEqual) \
74 : V(Word32Equal) \
75 : V(Word32NotEqual) \
76 : V(Word64Equal) \
77 : V(Word64NotEqual)
78 :
79 : #define CODE_ASSEMBLER_BINARY_OP_LIST(V) \
80 : CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
81 : V(Float64Add) \
82 : V(Float64Sub) \
83 : V(Float64Mul) \
84 : V(Float64Div) \
85 : V(Float64Mod) \
86 : V(Float64Atan2) \
87 : V(Float64Pow) \
88 : V(Float64Max) \
89 : V(Float64Min) \
90 : V(Float64InsertLowWord32) \
91 : V(Float64InsertHighWord32) \
92 : V(IntPtrAddWithOverflow) \
93 : V(IntPtrSubWithOverflow) \
94 : V(IntPtrMul) \
95 : V(Int32Add) \
96 : V(Int32AddWithOverflow) \
97 : V(Int32Sub) \
98 : V(Int32Mul) \
99 : V(Int32MulWithOverflow) \
100 : V(Int32Div) \
101 : V(Int32Mod) \
102 : V(WordOr) \
103 : V(WordAnd) \
104 : V(WordXor) \
105 : V(WordShl) \
106 : V(WordShr) \
107 : V(WordSar) \
108 : V(WordRor) \
109 : V(Word32Or) \
110 : V(Word32And) \
111 : V(Word32Xor) \
112 : V(Word32Shl) \
113 : V(Word32Shr) \
114 : V(Word32Sar) \
115 : V(Word32Ror) \
116 : V(Word64Or) \
117 : V(Word64And) \
118 : V(Word64Xor) \
119 : V(Word64Shr) \
120 : V(Word64Sar) \
121 : V(Word64Ror)
122 :
123 : #define CODE_ASSEMBLER_UNARY_OP_LIST(V) \
124 : V(Float64Abs) \
125 : V(Float64Acos) \
126 : V(Float64Acosh) \
127 : V(Float64Asin) \
128 : V(Float64Asinh) \
129 : V(Float64Atan) \
130 : V(Float64Atanh) \
131 : V(Float64Cos) \
132 : V(Float64Cosh) \
133 : V(Float64Exp) \
134 : V(Float64Expm1) \
135 : V(Float64Log) \
136 : V(Float64Log1p) \
137 : V(Float64Log2) \
138 : V(Float64Log10) \
139 : V(Float64Cbrt) \
140 : V(Float64Neg) \
141 : V(Float64Sin) \
142 : V(Float64Sinh) \
143 : V(Float64Sqrt) \
144 : V(Float64Tan) \
145 : V(Float64Tanh) \
146 : V(Float64ExtractLowWord32) \
147 : V(Float64ExtractHighWord32) \
148 : V(BitcastTaggedToWord) \
149 : V(BitcastWordToTagged) \
150 : V(BitcastWordToTaggedSigned) \
151 : V(TruncateFloat64ToFloat32) \
152 : V(TruncateFloat64ToWord32) \
153 : V(TruncateInt64ToInt32) \
154 : V(ChangeFloat32ToFloat64) \
155 : V(ChangeFloat64ToUint32) \
156 : V(ChangeFloat64ToUint64) \
157 : V(ChangeInt32ToFloat64) \
158 : V(ChangeInt32ToInt64) \
159 : V(ChangeUint32ToFloat64) \
160 : V(ChangeUint32ToUint64) \
161 : V(RoundFloat64ToInt32) \
162 : V(RoundInt32ToFloat32) \
163 : V(Float64SilenceNaN) \
164 : V(Float64RoundDown) \
165 : V(Float64RoundUp) \
166 : V(Float64RoundTiesEven) \
167 : V(Float64RoundTruncate) \
168 : V(Word32Clz) \
169 : V(Word32Not) \
170 : V(Int32AbsWithOverflow) \
171 : V(Int64AbsWithOverflow) \
172 : V(IntPtrAbsWithOverflow) \
173 : V(Word32BinaryNot)
174 :
175 : // A "public" interface used by components outside of compiler directory to
176 : // create code objects with TurboFan's backend. This class is mostly a thin shim
177 : // around the RawMachineAssembler, and its primary job is to ensure that the
178 : // innards of the RawMachineAssembler and other compiler implementation details
179 : // don't leak outside of the the compiler directory..
180 : //
181 : // V8 components that need to generate low-level code using this interface
182 : // should include this header--and this header only--from the compiler directory
183 : // (this is actually enforced). Since all interesting data structures are
184 : // forward declared, it's not possible for clients to peek inside the compiler
185 : // internals.
186 : //
187 : // In addition to providing isolation between TurboFan and code generation
188 : // clients, CodeAssembler also provides an abstraction for creating variables
189 : // and enhanced Label functionality to merge variable values along paths where
190 : // they have differing values, including loops.
191 : //
192 : // The CodeAssembler itself is stateless (and instances are expected to be
193 : // temporary-scoped and short-lived); all its state is encapsulated into
194 : // a CodeAssemblerState instance.
195 : class V8_EXPORT_PRIVATE CodeAssembler {
196 : public:
197 119506 : explicit CodeAssembler(CodeAssemblerState* state) : state_(state) {}
198 : ~CodeAssembler();
199 :
200 : static Handle<Code> GenerateCode(CodeAssemblerState* state);
201 :
202 : bool Is64() const;
203 : bool IsFloat64RoundUpSupported() const;
204 : bool IsFloat64RoundDownSupported() const;
205 : bool IsFloat64RoundTiesEvenSupported() const;
206 : bool IsFloat64RoundTruncateSupported() const;
207 : bool IsInt32AbsWithOverflowSupported() const;
208 : bool IsInt64AbsWithOverflowSupported() const;
209 : bool IsIntPtrAbsWithOverflowSupported() const;
210 :
211 : // Shortened aliases for use in CodeAssembler subclasses.
212 : typedef CodeAssemblerLabel Label;
213 : typedef CodeAssemblerVariable Variable;
214 : typedef CodeAssemblerVariableList VariableList;
215 :
216 : // ===========================================================================
217 : // Base Assembler
218 : // ===========================================================================
219 :
220 : // Constants.
221 : Node* Int32Constant(int32_t value);
222 : Node* Int64Constant(int64_t value);
223 : Node* IntPtrConstant(intptr_t value);
224 : Node* NumberConstant(double value);
225 : Node* SmiConstant(Smi* value);
226 : Node* SmiConstant(int value);
227 : Node* HeapConstant(Handle<HeapObject> object);
228 : Node* CStringConstant(const char* str);
229 : Node* BooleanConstant(bool value);
230 : Node* ExternalConstant(ExternalReference address);
231 : Node* Float64Constant(double value);
232 : Node* NaNConstant();
233 :
234 : bool ToInt32Constant(Node* node, int32_t& out_value);
235 : bool ToInt64Constant(Node* node, int64_t& out_value);
236 : bool ToSmiConstant(Node* node, Smi*& out_value);
237 : bool ToIntPtrConstant(Node* node, intptr_t& out_value);
238 :
239 : Node* Parameter(int value);
240 : Node* GetJSContextParameter();
241 : void Return(Node* value);
242 : void Return(Node* value1, Node* value2);
243 : void Return(Node* value1, Node* value2, Node* value3);
244 : void PopAndReturn(Node* pop, Node* value);
245 :
246 : void ReturnIf(Node* condition, Node* value);
247 :
248 : void DebugBreak();
249 : void Unreachable();
250 : void Comment(const char* format, ...);
251 :
252 : void Bind(Label* label);
253 : #if DEBUG
254 : void Bind(Label* label, AssemblerDebugInfo debug_info);
255 : #endif // DEBUG
256 : void Goto(Label* label);
257 : void GotoIf(Node* condition, Label* true_label);
258 : void GotoIfNot(Node* condition, Label* false_label);
259 : void Branch(Node* condition, Label* true_label, Label* false_label);
260 :
261 : void Switch(Node* index, Label* default_label, const int32_t* case_values,
262 : Label** case_labels, size_t case_count);
263 :
264 : // Access to the frame pointer
265 : Node* LoadFramePointer();
266 : Node* LoadParentFramePointer();
267 :
268 : // Access to the stack pointer
269 : Node* LoadStackPointer();
270 :
271 : // Load raw memory location.
272 : Node* Load(MachineType rep, Node* base);
273 : Node* Load(MachineType rep, Node* base, Node* offset);
274 : Node* AtomicLoad(MachineType rep, Node* base, Node* offset);
275 :
276 : // Load a value from the root array.
277 : Node* LoadRoot(Heap::RootListIndex root_index);
278 :
279 : // Store value to raw memory location.
280 : Node* Store(Node* base, Node* value);
281 : Node* Store(Node* base, Node* offset, Node* value);
282 : Node* StoreWithMapWriteBarrier(Node* base, Node* offset, Node* value);
283 : Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
284 : Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* offset,
285 : Node* value);
286 : Node* AtomicStore(MachineRepresentation rep, Node* base, Node* offset,
287 : Node* value);
288 :
289 : // Exchange value at raw memory location
290 : Node* AtomicExchange(MachineType type, Node* base, Node* offset, Node* value);
291 :
292 : // Compare and Exchange value at raw memory location
293 : Node* AtomicCompareExchange(MachineType type, Node* base, Node* offset,
294 : Node* old_value, Node* new_value);
295 :
296 : Node* AtomicAdd(MachineType type, Node* base, Node* offset, Node* value);
297 :
298 : Node* AtomicSub(MachineType type, Node* base, Node* offset, Node* value);
299 :
300 : Node* AtomicAnd(MachineType type, Node* base, Node* offset, Node* value);
301 :
302 : Node* AtomicOr(MachineType type, Node* base, Node* offset, Node* value);
303 :
304 : Node* AtomicXor(MachineType type, Node* base, Node* offset, Node* value);
305 :
306 : // Store a value to the root array.
307 : Node* StoreRoot(Heap::RootListIndex root_index, Node* value);
308 :
309 : // Basic arithmetic operations.
310 : #define DECLARE_CODE_ASSEMBLER_BINARY_OP(name) Node* name(Node* a, Node* b);
311 : CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP)
312 : #undef DECLARE_CODE_ASSEMBLER_BINARY_OP
313 :
314 : Node* IntPtrAdd(Node* left, Node* right);
315 : Node* IntPtrSub(Node* left, Node* right);
316 :
317 : Node* WordShl(Node* value, int shift);
318 : Node* WordShr(Node* value, int shift);
319 : Node* Word32Shr(Node* value, int shift);
320 :
321 : // Unary
322 : #define DECLARE_CODE_ASSEMBLER_UNARY_OP(name) Node* name(Node* a);
323 : CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
324 : #undef DECLARE_CODE_ASSEMBLER_UNARY_OP
325 :
326 : // Changes a double to an inptr_t for pointer arithmetic outside of Smi range.
327 : // Assumes that the double can be exactly represented as an int.
328 : Node* ChangeFloat64ToUintPtr(Node* value);
329 :
330 : // Changes an intptr_t to a double, e.g. for storing an element index
331 : // outside Smi range in a HeapNumber. Lossless on 32-bit,
332 : // rounds on 64-bit (which doesn't affect valid element indices).
333 : Node* RoundIntPtrToFloat64(Node* value);
334 : // No-op on 32-bit, otherwise zero extend.
335 : Node* ChangeUint32ToWord(Node* value);
336 : // No-op on 32-bit, otherwise sign extend.
337 : Node* ChangeInt32ToIntPtr(Node* value);
338 :
339 : // No-op that guarantees that the value is kept alive till this point even
340 : // if GC happens.
341 : Node* Retain(Node* value);
342 :
343 : // Projections
344 : Node* Projection(int index, Node* value);
345 :
346 : // Calls
347 : template <class... TArgs>
348 : Node* CallRuntime(Runtime::FunctionId function, Node* context, TArgs... args);
349 :
350 : template <class... TArgs>
351 : Node* TailCallRuntime(Runtime::FunctionId function, Node* context,
352 : TArgs... args);
353 :
354 : template <class... TArgs>
355 42618 : Node* CallStub(Callable const& callable, Node* context, TArgs... args) {
356 42618 : Node* target = HeapConstant(callable.code());
357 42618 : return CallStub(callable.descriptor(), target, context, args...);
358 : }
359 :
360 : template <class... TArgs>
361 : Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
362 : Node* context, TArgs... args) {
363 46631 : return CallStubR(descriptor, 1, target, context, args...);
364 : }
365 :
366 : template <class... TArgs>
367 : Node* CallStubR(const CallInterfaceDescriptor& descriptor, size_t result_size,
368 : Node* target, Node* context, TArgs... args);
369 :
370 : Node* CallStubN(const CallInterfaceDescriptor& descriptor, size_t result_size,
371 : int input_count, Node* const* inputs);
372 :
373 : template <class... TArgs>
374 112668 : Node* TailCallStub(Callable const& callable, Node* context, TArgs... args) {
375 112668 : Node* target = HeapConstant(callable.code());
376 112668 : return TailCallStub(callable.descriptor(), target, context, args...);
377 : }
378 :
379 : template <class... TArgs>
380 : Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
381 : Node* context, TArgs... args);
382 :
383 : template <class... TArgs>
384 : Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
385 : Node* target, TArgs... args);
386 :
387 : template <class... TArgs>
388 10585 : Node* CallJS(Callable const& callable, Node* context, Node* function,
389 : Node* receiver, TArgs... args) {
390 : int argc = static_cast<int>(sizeof...(args));
391 10585 : Node* arity = Int32Constant(argc);
392 10585 : return CallStub(callable, context, function, arity, receiver, args...);
393 : }
394 :
395 : template <class... TArgs>
396 358 : Node* ConstructJS(Callable const& callable, Node* context, Node* new_target,
397 : TArgs... args) {
398 : int argc = static_cast<int>(sizeof...(args));
399 358 : Node* arity = Int32Constant(argc);
400 358 : Node* receiver = LoadRoot(Heap::kUndefinedValueRootIndex);
401 :
402 : // Construct(target, new_target, arity, receiver, arguments...)
403 : return CallStub(callable, context, new_target, new_target, arity, receiver,
404 358 : args...);
405 : }
406 :
407 : Node* CallCFunctionN(Signature<MachineType>* signature, int input_count,
408 : Node* const* inputs);
409 :
410 : // Call to a C function with one argument.
411 : Node* CallCFunction1(MachineType return_type, MachineType arg0_type,
412 : Node* function, Node* arg0);
413 :
414 : // Call to a C function with two arguments.
415 : Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
416 : MachineType arg1_type, Node* function, Node* arg0,
417 : Node* arg1);
418 :
419 : // Call to a C function with three arguments.
420 : Node* CallCFunction3(MachineType return_type, MachineType arg0_type,
421 : MachineType arg1_type, MachineType arg2_type,
422 : Node* function, Node* arg0, Node* arg1, Node* arg2);
423 :
424 : // Call to a C function with six arguments.
425 : Node* CallCFunction6(MachineType return_type, MachineType arg0_type,
426 : MachineType arg1_type, MachineType arg2_type,
427 : MachineType arg3_type, MachineType arg4_type,
428 : MachineType arg5_type, Node* function, Node* arg0,
429 : Node* arg1, Node* arg2, Node* arg3, Node* arg4,
430 : Node* arg5);
431 :
432 : // Call to a C function with nine arguments.
433 : Node* CallCFunction9(MachineType return_type, MachineType arg0_type,
434 : MachineType arg1_type, MachineType arg2_type,
435 : MachineType arg3_type, MachineType arg4_type,
436 : MachineType arg5_type, MachineType arg6_type,
437 : MachineType arg7_type, MachineType arg8_type,
438 : Node* function, Node* arg0, Node* arg1, Node* arg2,
439 : Node* arg3, Node* arg4, Node* arg5, Node* arg6,
440 : Node* arg7, Node* arg8);
441 :
442 : // Exception handling support.
443 : void GotoIfException(Node* node, Label* if_exception,
444 : Variable* exception_var = nullptr);
445 :
446 : // Helpers which delegate to RawMachineAssembler.
447 : Factory* factory() const;
448 : Isolate* isolate() const;
449 : Zone* zone() const;
450 :
451 2337654 : CodeAssemblerState* state() { return state_; }
452 :
453 : void BreakOnNode(int node_id);
454 :
455 : bool UnalignedLoadSupported(const MachineType& machineType,
456 : uint8_t alignment) const;
457 : bool UnalignedStoreSupported(const MachineType& machineType,
458 : uint8_t alignment) const;
459 :
460 : protected:
461 : void RegisterCallGenerationCallbacks(
462 : const CodeAssemblerCallback& call_prologue,
463 : const CodeAssemblerCallback& call_epilogue);
464 : void UnregisterCallGenerationCallbacks();
465 :
466 : private:
467 : RawMachineAssembler* raw_assembler() const;
468 :
469 : // Calls respective callback registered in the state.
470 : void CallPrologue();
471 : void CallEpilogue();
472 :
473 : CodeAssemblerState* state_;
474 :
475 : DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
476 : };
477 :
478 : class CodeAssemblerVariable {
479 : public:
480 : explicit CodeAssemblerVariable(CodeAssembler* assembler,
481 : MachineRepresentation rep);
482 : CodeAssemblerVariable(CodeAssembler* assembler, MachineRepresentation rep,
483 : Node* initial_value);
484 : #if DEBUG
485 : CodeAssemblerVariable(CodeAssembler* assembler, AssemblerDebugInfo debug_info,
486 : MachineRepresentation rep);
487 : CodeAssemblerVariable(CodeAssembler* assembler, AssemblerDebugInfo debug_info,
488 : MachineRepresentation rep, Node* initial_value);
489 : #endif // DEBUG
490 :
491 : ~CodeAssemblerVariable();
492 : void Bind(Node* value);
493 : Node* value() const;
494 : MachineRepresentation rep() const;
495 : bool IsBound() const;
496 :
497 : private:
498 : class Impl;
499 : friend class CodeAssemblerLabel;
500 : friend class CodeAssemblerState;
501 : friend std::ostream& operator<<(std::ostream&, const Impl&);
502 : friend std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&);
503 : Impl* impl_;
504 : CodeAssemblerState* state_;
505 : };
506 :
507 : std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&);
508 : std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable::Impl&);
509 :
510 8256 : class CodeAssemblerLabel {
511 : public:
512 : enum Type { kDeferred, kNonDeferred };
513 :
514 : explicit CodeAssemblerLabel(
515 : CodeAssembler* assembler,
516 : CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
517 1038274 : : CodeAssemblerLabel(assembler, 0, nullptr, type) {}
518 : CodeAssemblerLabel(
519 : CodeAssembler* assembler,
520 : const CodeAssemblerVariableList& merged_variables,
521 : CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
522 : : CodeAssemblerLabel(assembler, merged_variables.length(),
523 21403 : &(merged_variables[0]), type) {}
524 : CodeAssemblerLabel(
525 : CodeAssembler* assembler, size_t count,
526 : CodeAssemblerVariable* const* vars,
527 : CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred);
528 : CodeAssemblerLabel(
529 : CodeAssembler* assembler,
530 : std::initializer_list<CodeAssemblerVariable*> vars,
531 : CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
532 2107 : : CodeAssemblerLabel(assembler, vars.size(), vars.begin(), type) {}
533 : CodeAssemblerLabel(
534 : CodeAssembler* assembler, CodeAssemblerVariable* merged_variable,
535 : CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
536 135826 : : CodeAssemblerLabel(assembler, 1, &merged_variable, type) {}
537 : ~CodeAssemblerLabel();
538 :
539 : inline bool is_bound() const { return bound_; }
540 :
541 : private:
542 : friend class CodeAssembler;
543 :
544 : void Bind();
545 : #if DEBUG
546 : void Bind(AssemblerDebugInfo debug_info);
547 : #endif // DEBUG
548 : void UpdateVariablesAfterBind();
549 : void MergeVariables();
550 :
551 : bool bound_;
552 : size_t merge_count_;
553 : CodeAssemblerState* state_;
554 : RawMachineLabel* label_;
555 : // Map of variables that need to be merged to their phi nodes (or placeholders
556 : // for those phis).
557 : std::map<CodeAssemblerVariable::Impl*, Node*> variable_phis_;
558 : // Map of variables to the list of value nodes that have been added from each
559 : // merge path in their order of merging.
560 : std::map<CodeAssemblerVariable::Impl*, std::vector<Node*>> variable_merges_;
561 : };
562 :
563 : class V8_EXPORT_PRIVATE CodeAssemblerState {
564 : public:
565 : // Create with CallStub linkage.
566 : // |result_size| specifies the number of results returned by the stub.
567 : // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
568 : CodeAssemblerState(Isolate* isolate, Zone* zone,
569 : const CallInterfaceDescriptor& descriptor,
570 : Code::Flags flags, const char* name,
571 : size_t result_size = 1);
572 :
573 : // Create with JSCall linkage.
574 : CodeAssemblerState(Isolate* isolate, Zone* zone, int parameter_count,
575 : Code::Flags flags, const char* name);
576 :
577 : ~CodeAssemblerState();
578 :
579 : const char* name() const { return name_; }
580 : int parameter_count() const;
581 :
582 : #if DEBUG
583 : void PrintCurrentBlock(std::ostream& os);
584 : #endif // DEBUG
585 : void SetInitialDebugInformation(const char* msg, const char* file, int line);
586 :
587 : private:
588 : friend class CodeAssembler;
589 : friend class CodeAssemblerLabel;
590 : friend class CodeAssemblerVariable;
591 :
592 : CodeAssemblerState(Isolate* isolate, Zone* zone,
593 : CallDescriptor* call_descriptor, Code::Flags flags,
594 : const char* name);
595 :
596 : std::unique_ptr<RawMachineAssembler> raw_assembler_;
597 : Code::Flags flags_;
598 : const char* name_;
599 : bool code_generated_;
600 : ZoneSet<CodeAssemblerVariable::Impl*> variables_;
601 : CodeAssemblerCallback call_prologue_;
602 : CodeAssemblerCallback call_epilogue_;
603 :
604 : DISALLOW_COPY_AND_ASSIGN(CodeAssemblerState);
605 : };
606 :
607 : } // namespace compiler
608 : } // namespace internal
609 : } // namespace v8
610 :
611 : #endif // V8_COMPILER_CODE_ASSEMBLER_H_
|