1 // Copyright 2014 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_JS_GRAPH_H_
6 #define V8_COMPILER_JS_GRAPH_H_
7 
8 #include "src/base/compiler-specific.h"
9 #include "src/compiler/common-node-cache.h"
10 #include "src/compiler/common-operator.h"
11 #include "src/compiler/graph.h"
12 #include "src/compiler/js-operator.h"
13 #include "src/compiler/machine-operator.h"
14 #include "src/compiler/node-properties.h"
15 #include "src/globals.h"
16 #include "src/isolate.h"
17 
18 namespace v8 {
19 namespace internal {
20 namespace compiler {
21 
22 class SimplifiedOperatorBuilder;
23 class Typer;
24 
25 // Implements a facade on a Graph, enhancing the graph with JS-specific
26 // notions, including various builders for operators, canonicalized global
27 // constants, and various helper methods.
NON_EXPORTED_BASE(ZoneObject)28 class V8_EXPORT_PRIVATE JSGraph : public NON_EXPORTED_BASE(ZoneObject) {
29  public:
30   JSGraph(Isolate* isolate, Graph* graph, CommonOperatorBuilder* common,
31           JSOperatorBuilder* javascript, SimplifiedOperatorBuilder* simplified,
32           MachineOperatorBuilder* machine)
33       : isolate_(isolate),
34         graph_(graph),
35         common_(common),
36         javascript_(javascript),
37         simplified_(simplified),
38         machine_(machine),
39         cache_(zone()) {
40     for (int i = 0; i < kNumCachedNodes; i++) cached_nodes_[i] = nullptr;
41   }
42 
43   // Canonicalized global constants.
44   Node* AllocateInNewSpaceStubConstant();
45   Node* AllocateInOldSpaceStubConstant();
46   Node* ToNumberBuiltinConstant();
47   Node* CEntryStubConstant(int result_size,
48                            SaveFPRegsMode save_doubles = kDontSaveFPRegs,
49                            ArgvMode argv_mode = kArgvOnStack,
50                            bool builtin_exit_frame = false);
51   Node* EmptyFixedArrayConstant();
52   Node* EmptyLiteralsArrayConstant();
53   Node* EmptyStringConstant();
54   Node* FixedArrayMapConstant();
55   Node* FixedDoubleArrayMapConstant();
56   Node* HeapNumberMapConstant();
57   Node* OptimizedOutConstant();
58   Node* StaleRegisterConstant();
59   Node* UndefinedConstant();
60   Node* TheHoleConstant();
61   Node* TrueConstant();
62   Node* FalseConstant();
63   Node* NullConstant();
64   Node* ZeroConstant();
65   Node* OneConstant();
66   Node* NaNConstant();
67 
68   // Creates a HeapConstant node, possibly canonicalized, and may access the
69   // heap to inspect the object.
70   Node* HeapConstant(Handle<HeapObject> value);
71 
72   // Creates a Constant node of the appropriate type for the given object.
73   // Accesses the heap to inspect the object and determine whether one of the
74   // canonicalized globals or a number constant should be returned.
75   Node* Constant(Handle<Object> value);
76 
77   // Creates a NumberConstant node, usually canonicalized.
78   Node* Constant(double value);
79 
80   // Creates a NumberConstant node, usually canonicalized.
81   Node* Constant(int32_t value);
82 
83   // Creates a NumberConstant node, usually canonicalized.
84   Node* Constant(uint32_t value);
85 
86   // Creates a Int32Constant node, usually canonicalized.
87   Node* Int32Constant(int32_t value);
88   Node* Uint32Constant(uint32_t value) {
89     return Int32Constant(bit_cast<int32_t>(value));
90   }
91 
92   // Creates a HeapConstant node for either true or false.
93   Node* BooleanConstant(bool is_true) {
94     return is_true ? TrueConstant() : FalseConstant();
95   }
96 
97   // Creates a Int64Constant node, usually canonicalized.
98   Node* Int64Constant(int64_t value);
99   Node* Uint64Constant(uint64_t value) {
100     return Int64Constant(bit_cast<int64_t>(value));
101   }
102 
103   // Creates a Int32Constant/Int64Constant node, depending on the word size of
104   // the target machine.
105   // TODO(turbofan): Code using Int32Constant/Int64Constant to store pointer
106   // constants is probably not serializable.
107   Node* IntPtrConstant(intptr_t value) {
108     return machine()->Is32() ? Int32Constant(static_cast<int32_t>(value))
109                              : Int64Constant(static_cast<int64_t>(value));
110   }
111 
112   Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode);
113   Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode);
114   Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);
115 
116   // Creates a Float32Constant node, usually canonicalized.
117   Node* Float32Constant(float value);
118 
119   // Creates a Float64Constant node, usually canonicalized.
120   Node* Float64Constant(double value);
121 
122   // Creates a PointerConstant node (asm.js only).
123   Node* PointerConstant(intptr_t value);
124   template <typename T>
125   Node* PointerConstant(T* value) {
126     return PointerConstant(bit_cast<intptr_t>(value));
127   }
128 
129   // Creates an ExternalConstant node, usually canonicalized.
130   Node* ExternalConstant(ExternalReference ref);
131   Node* ExternalConstant(Runtime::FunctionId function_id);
132 
133   Node* SmiConstant(int32_t immediate) {
134     DCHECK(Smi::IsValid(immediate));
135     return Constant(immediate);
136   }
137 
138   // Creates a dummy Constant node, used to satisfy calling conventions of
139   // stubs and runtime functions that do not require a context.
140   Node* NoContextConstant() { return ZeroConstant(); }
141 
142   // Creates an empty StateValues node, used when we don't have any concrete
143   // values for a certain part of the frame state.
144   Node* EmptyStateValues();
145 
146   // Create a control node that serves as dependency for dead nodes.
147   Node* Dead();
148 
149   CommonOperatorBuilder* common() const { return common_; }
150   JSOperatorBuilder* javascript() const { return javascript_; }
151   SimplifiedOperatorBuilder* simplified() const { return simplified_; }
152   MachineOperatorBuilder* machine() const { return machine_; }
153   Graph* graph() const { return graph_; }
154   Zone* zone() const { return graph()->zone(); }
155   Isolate* isolate() const { return isolate_; }
156   Factory* factory() const { return isolate()->factory(); }
157 
158   void GetCachedNodes(NodeVector* nodes);
159 
160  private:
161   enum CachedNode {
162     kAllocateInNewSpaceStubConstant,
163     kAllocateInOldSpaceStubConstant,
164     kToNumberBuiltinConstant,
165     kCEntryStubConstant,
166     kCEntryStubWithBuiltinExitFrameConstant,
167     kEmptyFixedArrayConstant,
168     kEmptyLiteralsArrayConstant,
169     kEmptyStringConstant,
170     kFixedArrayMapConstant,
171     kFixedDoubleArrayMapConstant,
172     kHeapNumberMapConstant,
173     kOptimizedOutConstant,
174     kStaleRegisterConstant,
175     kUndefinedConstant,
176     kTheHoleConstant,
177     kTrueConstant,
178     kFalseConstant,
179     kNullConstant,
180     kZeroConstant,
181     kOneConstant,
182     kNaNConstant,
183     kEmptyStateValues,
184     kDead,
185     kNumCachedNodes  // Must remain last.
186   };
187 
188   Isolate* isolate_;
189   Graph* graph_;
190   CommonOperatorBuilder* common_;
191   JSOperatorBuilder* javascript_;
192   SimplifiedOperatorBuilder* simplified_;
193   MachineOperatorBuilder* machine_;
194   CommonNodeCache cache_;
195   Node* cached_nodes_[kNumCachedNodes];
196 
197   Node* NumberConstant(double value);
198 
199   DISALLOW_COPY_AND_ASSIGN(JSGraph);
200 };
201 
202 }  // namespace compiler
203 }  // namespace internal
204 }  // namespace v8
205 
206 #endif
207