V8 Project
common-operator.cc
Go to the documentation of this file.
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 
6 
7 #include "src/assembler.h"
9 #include "src/compiler/linkage.h"
10 #include "src/unique.h"
11 #include "src/zone.h"
12 
13 namespace v8 {
14 namespace internal {
15 namespace compiler {
16 
17 namespace {
18 
19 // TODO(turbofan): Use size_t instead of int here.
20 class ControlOperator : public Operator1<int> {
21  public:
22  ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs,
23  int outputs, int controls, const char* mnemonic)
24  : Operator1<int>(opcode, properties, inputs, outputs, mnemonic,
25  controls) {}
26 
27  virtual OStream& PrintParameter(OStream& os) const FINAL { return os; }
28 };
29 
30 } // namespace
31 
32 
33 // Specialization for static parameters of type {ExternalReference}.
34 template <>
35 struct StaticParameterTraits<ExternalReference> {
36  static OStream& PrintTo(OStream& os, ExternalReference reference) {
37  os << reference.address();
38  // TODO(bmeurer): Move to operator<<(os, ExternalReference)
39  const Runtime::Function* function =
40  Runtime::FunctionForEntry(reference.address());
41  if (function) {
42  os << " <" << function->name << ".entry>";
43  }
44  return os;
45  }
46  static int HashCode(ExternalReference reference) {
47  return bit_cast<int>(static_cast<uint32_t>(
48  reinterpret_cast<uintptr_t>(reference.address())));
49  }
50  static bool Equals(ExternalReference lhs, ExternalReference rhs) {
51  return lhs == rhs;
52  }
53 };
54 
55 
56 #define SHARED_OP_LIST(V) \
57  V(Dead, Operator::kFoldable, 0, 0) \
58  V(End, Operator::kFoldable, 0, 1) \
59  V(Branch, Operator::kFoldable, 1, 1) \
60  V(IfTrue, Operator::kFoldable, 0, 1) \
61  V(IfFalse, Operator::kFoldable, 0, 1) \
62  V(Throw, Operator::kFoldable, 1, 1) \
63  V(Return, Operator::kNoProperties, 1, 1)
64 
65 
66 struct CommonOperatorBuilderImpl FINAL {
67 #define SHARED(Name, properties, value_input_count, control_input_count) \
68  struct Name##Operator FINAL : public ControlOperator { \
69  Name##Operator() \
70  : ControlOperator(IrOpcode::k##Name, properties, value_input_count, 0, \
71  control_input_count, #Name) {} \
72  }; \
73  Name##Operator k##Name##Operator;
75 #undef SHARED
76 
77  struct ControlEffectOperator FINAL : public SimpleOperator {
79  : SimpleOperator(IrOpcode::kControlEffect, Operator::kPure, 0, 0,
80  "ControlEffect") {}
81  };
82  ControlEffectOperator kControlEffectOperator;
83 };
84 
85 
88 
89 
90 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
91  : impl_(kImpl.Get()), zone_(zone) {}
92 
93 
94 #define SHARED(Name, properties, value_input_count, control_input_count) \
95  const Operator* CommonOperatorBuilder::Name() { \
96  return &impl_.k##Name##Operator; \
97  }
99 #undef SHARED
100 
101 
102 const Operator* CommonOperatorBuilder::Start(int num_formal_parameters) {
103  // Outputs are formal parameters, plus context, receiver, and JSFunction.
104  const int value_output_count = num_formal_parameters + 3;
105  return new (zone()) ControlOperator(IrOpcode::kStart, Operator::kFoldable, 0,
106  value_output_count, 0, "Start");
107 }
108 
109 
110 const Operator* CommonOperatorBuilder::Merge(int controls) {
111  return new (zone()) ControlOperator(IrOpcode::kMerge, Operator::kFoldable, 0,
112  0, controls, "Merge");
113 }
114 
115 
116 const Operator* CommonOperatorBuilder::Loop(int controls) {
117  return new (zone()) ControlOperator(IrOpcode::kLoop, Operator::kFoldable, 0,
118  0, controls, "Loop");
119 }
120 
121 
122 const Operator* CommonOperatorBuilder::Parameter(int index) {
123  return new (zone()) Operator1<int>(IrOpcode::kParameter, Operator::kPure, 1,
124  1, "Parameter", index);
125 }
126 
127 
128 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
129  return new (zone()) Operator1<int32_t>(
130  IrOpcode::kInt32Constant, Operator::kPure, 0, 1, "Int32Constant", value);
131 }
132 
133 
134 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
135  return new (zone()) Operator1<int64_t>(
136  IrOpcode::kInt64Constant, Operator::kPure, 0, 1, "Int64Constant", value);
137 }
138 
139 
140 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
141  return new (zone())
142  Operator1<float>(IrOpcode::kFloat32Constant, Operator::kPure, 0, 1,
143  "Float32Constant", value);
144 }
145 
146 
147 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
148  return new (zone())
149  Operator1<double>(IrOpcode::kFloat64Constant, Operator::kPure, 0, 1,
150  "Float64Constant", value);
151 }
152 
153 
154 const Operator* CommonOperatorBuilder::ExternalConstant(
155  const ExternalReference& value) {
156  return new (zone())
157  Operator1<ExternalReference>(IrOpcode::kExternalConstant, Operator::kPure,
158  0, 1, "ExternalConstant", value);
159 }
160 
161 
162 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
163  return new (zone())
164  Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1,
165  "NumberConstant", value);
166 }
167 
168 
169 const Operator* CommonOperatorBuilder::HeapConstant(
170  const Unique<Object>& value) {
171  return new (zone()) Operator1<Unique<Object> >(
172  IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value);
173 }
174 
175 
176 const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) {
177  DCHECK(arguments > 0); // Disallow empty phis.
178  return new (zone()) Operator1<MachineType>(IrOpcode::kPhi, Operator::kPure,
179  arguments, 1, "Phi", type);
180 }
181 
182 
183 const Operator* CommonOperatorBuilder::EffectPhi(int arguments) {
184  DCHECK(arguments > 0); // Disallow empty phis.
185  return new (zone()) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0,
186  0, "EffectPhi", arguments);
187 }
188 
189 
190 const Operator* CommonOperatorBuilder::ControlEffect() {
191  return &impl_.kControlEffectOperator;
192 }
193 
194 
195 const Operator* CommonOperatorBuilder::ValueEffect(int arguments) {
196  DCHECK(arguments > 0); // Disallow empty value effects.
197  return new (zone()) SimpleOperator(IrOpcode::kValueEffect, Operator::kPure,
198  arguments, 0, "ValueEffect");
199 }
200 
201 
202 const Operator* CommonOperatorBuilder::Finish(int arguments) {
203  DCHECK(arguments > 0); // Disallow empty finishes.
204  return new (zone()) Operator1<int>(IrOpcode::kFinish, Operator::kPure, 1, 1,
205  "Finish", arguments);
206 }
207 
208 
209 const Operator* CommonOperatorBuilder::StateValues(int arguments) {
210  return new (zone()) Operator1<int>(IrOpcode::kStateValues, Operator::kPure,
211  arguments, 1, "StateValues", arguments);
212 }
213 
214 
215 const Operator* CommonOperatorBuilder::FrameState(
216  FrameStateType type, BailoutId bailout_id,
217  OutputFrameStateCombine state_combine, MaybeHandle<JSFunction> jsfunction) {
218  return new (zone()) Operator1<FrameStateCallInfo>(
219  IrOpcode::kFrameState, Operator::kPure, 4, 1, "FrameState",
220  FrameStateCallInfo(type, bailout_id, state_combine, jsfunction));
221 }
222 
223 
224 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
225  class CallOperator FINAL : public Operator1<const CallDescriptor*> {
226  public:
227  // TODO(titzer): Operator still uses int, whereas CallDescriptor uses
228  // size_t.
229  CallOperator(const CallDescriptor* descriptor, const char* mnemonic)
230  : Operator1<const CallDescriptor*>(
231  IrOpcode::kCall, descriptor->properties(),
232  static_cast<int>(descriptor->InputCount() +
233  descriptor->FrameStateCount()),
234  static_cast<int>(descriptor->ReturnCount()), mnemonic,
235  descriptor) {}
236 
237  virtual OStream& PrintParameter(OStream& os) const OVERRIDE {
238  return os << "[" << *parameter() << "]";
239  }
240  };
241  return new (zone()) CallOperator(descriptor, "Call");
242 }
243 
244 
245 const Operator* CommonOperatorBuilder::Projection(size_t index) {
246  return new (zone()) Operator1<size_t>(IrOpcode::kProjection, Operator::kPure,
247  1, 1, "Projection", index);
248 }
249 
250 } // namespace compiler
251 } // namespace internal
252 } // namespace v8
static const Function * FunctionForEntry(Address ref)
Definition: runtime.cc:9302
ControlEffectOperator kControlEffectOperator
base::Flags< Property, uint8_t > Properties
Definition: operator.h:48
ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs, int outputs, int controls, const char *mnemonic)
#define SHARED_OP_LIST(V)
#define SHARED(Name, properties, value_input_count, control_input_count)
#define OVERRIDE
#define FINAL
#define LAZY_INSTANCE_INITIALIZER
Definition: lazy-instance.h:81
#define DCHECK(condition)
Definition: logging.h:205
int int32_t
Definition: unicode.cc:24
static base::LazyInstance< CommonOperatorBuilderImpl >::type kImpl
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
static OStream & PrintTo(OStream &os, ExternalReference reference)
static bool Equals(ExternalReference lhs, ExternalReference rhs)