1 // Copyright 2013 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_OPERATOR_H_
6 #define V8_COMPILER_JS_OPERATOR_H_
7 
8 #include "src/base/compiler-specific.h"
9 #include "src/globals.h"
10 #include "src/runtime/runtime.h"
11 #include "src/type-hints.h"
12 
13 namespace v8 {
14 namespace internal {
15 namespace compiler {
16 
17 // Forward declarations.
18 class Operator;
19 struct JSOperatorGlobalCache;
20 
21 
22 // Defines a pair of {TypeFeedbackVector} and {TypeFeedbackVectorSlot}, which
23 // is used to access the type feedback for a certain {Node}.
24 class V8_EXPORT_PRIVATE VectorSlotPair {
25  public:
26   VectorSlotPair();
VectorSlotPair(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)27   VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
28       : vector_(vector), slot_(slot) {}
29 
IsValid()30   bool IsValid() const { return !vector_.is_null() && !slot_.IsInvalid(); }
31 
vector()32   Handle<TypeFeedbackVector> vector() const { return vector_; }
slot()33   FeedbackVectorSlot slot() const { return slot_; }
34 
35   int index() const;
36 
37  private:
38   const Handle<TypeFeedbackVector> vector_;
39   const FeedbackVectorSlot slot_;
40 };
41 
42 bool operator==(VectorSlotPair const&, VectorSlotPair const&);
43 bool operator!=(VectorSlotPair const&, VectorSlotPair const&);
44 
45 size_t hash_value(VectorSlotPair const&);
46 
47 
48 // The ConvertReceiverMode is used as parameter by JSConvertReceiver operators.
49 ConvertReceiverMode ConvertReceiverModeOf(Operator const* op);
50 
51 
52 // The ToBooleanHints are used as parameter by JSToBoolean operators.
53 ToBooleanHints ToBooleanHintsOf(Operator const* op);
54 
55 
56 // Defines the arity and the feedback for a JavaScript constructor call. This is
57 // used as a parameter by JSCallConstruct operators.
58 class CallConstructParameters final {
59  public:
CallConstructParameters(uint32_t arity,float frequency,VectorSlotPair const & feedback)60   CallConstructParameters(uint32_t arity, float frequency,
61                           VectorSlotPair const& feedback)
62       : arity_(arity), frequency_(frequency), feedback_(feedback) {}
63 
arity()64   uint32_t arity() const { return arity_; }
frequency()65   float frequency() const { return frequency_; }
feedback()66   VectorSlotPair const& feedback() const { return feedback_; }
67 
68  private:
69   uint32_t const arity_;
70   float const frequency_;
71   VectorSlotPair const feedback_;
72 };
73 
74 bool operator==(CallConstructParameters const&, CallConstructParameters const&);
75 bool operator!=(CallConstructParameters const&, CallConstructParameters const&);
76 
77 size_t hash_value(CallConstructParameters const&);
78 
79 std::ostream& operator<<(std::ostream&, CallConstructParameters const&);
80 
81 CallConstructParameters const& CallConstructParametersOf(Operator const*);
82 
83 
84 // Defines the arity and the call flags for a JavaScript function call. This is
85 // used as a parameter by JSCallFunction operators.
86 class CallFunctionParameters final {
87  public:
CallFunctionParameters(size_t arity,float frequency,VectorSlotPair const & feedback,TailCallMode tail_call_mode,ConvertReceiverMode convert_mode)88   CallFunctionParameters(size_t arity, float frequency,
89                          VectorSlotPair const& feedback,
90                          TailCallMode tail_call_mode,
91                          ConvertReceiverMode convert_mode)
92       : bit_field_(ArityField::encode(arity) |
93                    ConvertReceiverModeField::encode(convert_mode) |
94                    TailCallModeField::encode(tail_call_mode)),
95         frequency_(frequency),
96         feedback_(feedback) {}
97 
arity()98   size_t arity() const { return ArityField::decode(bit_field_); }
frequency()99   float frequency() const { return frequency_; }
convert_mode()100   ConvertReceiverMode convert_mode() const {
101     return ConvertReceiverModeField::decode(bit_field_);
102   }
tail_call_mode()103   TailCallMode tail_call_mode() const {
104     return TailCallModeField::decode(bit_field_);
105   }
feedback()106   VectorSlotPair const& feedback() const { return feedback_; }
107 
108   bool operator==(CallFunctionParameters const& that) const {
109     return this->bit_field_ == that.bit_field_ &&
110            this->frequency_ == that.frequency_ &&
111            this->feedback_ == that.feedback_;
112   }
113   bool operator!=(CallFunctionParameters const& that) const {
114     return !(*this == that);
115   }
116 
117  private:
hash_value(CallFunctionParameters const & p)118   friend size_t hash_value(CallFunctionParameters const& p) {
119     return base::hash_combine(p.bit_field_, p.frequency_, p.feedback_);
120   }
121 
122   typedef BitField<size_t, 0, 29> ArityField;
123   typedef BitField<ConvertReceiverMode, 29, 2> ConvertReceiverModeField;
124   typedef BitField<TailCallMode, 31, 1> TailCallModeField;
125 
126   uint32_t const bit_field_;
127   float const frequency_;
128   VectorSlotPair const feedback_;
129 };
130 
131 size_t hash_value(CallFunctionParameters const&);
132 
133 std::ostream& operator<<(std::ostream&, CallFunctionParameters const&);
134 
135 const CallFunctionParameters& CallFunctionParametersOf(const Operator* op);
136 
137 
138 // Defines the arity and the ID for a runtime function call. This is used as a
139 // parameter by JSCallRuntime operators.
140 class CallRuntimeParameters final {
141  public:
CallRuntimeParameters(Runtime::FunctionId id,size_t arity)142   CallRuntimeParameters(Runtime::FunctionId id, size_t arity)
143       : id_(id), arity_(arity) {}
144 
id()145   Runtime::FunctionId id() const { return id_; }
arity()146   size_t arity() const { return arity_; }
147 
148  private:
149   const Runtime::FunctionId id_;
150   const size_t arity_;
151 };
152 
153 bool operator==(CallRuntimeParameters const&, CallRuntimeParameters const&);
154 bool operator!=(CallRuntimeParameters const&, CallRuntimeParameters const&);
155 
156 size_t hash_value(CallRuntimeParameters const&);
157 
158 std::ostream& operator<<(std::ostream&, CallRuntimeParameters const&);
159 
160 const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op);
161 
162 
163 // Defines the location of a context slot relative to a specific scope. This is
164 // used as a parameter by JSLoadContext and JSStoreContext operators and allows
165 // accessing a context-allocated variable without keeping track of the scope.
166 class ContextAccess final {
167  public:
168   ContextAccess(size_t depth, size_t index, bool immutable);
169 
depth()170   size_t depth() const { return depth_; }
index()171   size_t index() const { return index_; }
immutable()172   bool immutable() const { return immutable_; }
173 
174  private:
175   // For space reasons, we keep this tightly packed, otherwise we could just use
176   // a simple int/int/bool POD.
177   const bool immutable_;
178   const uint16_t depth_;
179   const uint32_t index_;
180 };
181 
182 bool operator==(ContextAccess const&, ContextAccess const&);
183 bool operator!=(ContextAccess const&, ContextAccess const&);
184 
185 size_t hash_value(ContextAccess const&);
186 
187 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ContextAccess const&);
188 
189 ContextAccess const& ContextAccessOf(Operator const*);
190 
191 // Defines the name and ScopeInfo for a new catch context. This is used as a
192 // parameter by the JSCreateCatchContext operator.
193 class CreateCatchContextParameters final {
194  public:
195   CreateCatchContextParameters(Handle<String> catch_name,
196                                Handle<ScopeInfo> scope_info);
197 
catch_name()198   Handle<String> catch_name() const { return catch_name_; }
scope_info()199   Handle<ScopeInfo> scope_info() const { return scope_info_; }
200 
201  private:
202   Handle<String> const catch_name_;
203   Handle<ScopeInfo> const scope_info_;
204 };
205 
206 bool operator==(CreateCatchContextParameters const& lhs,
207                 CreateCatchContextParameters const& rhs);
208 bool operator!=(CreateCatchContextParameters const& lhs,
209                 CreateCatchContextParameters const& rhs);
210 
211 size_t hash_value(CreateCatchContextParameters const& parameters);
212 
213 std::ostream& operator<<(std::ostream& os,
214                          CreateCatchContextParameters const& parameters);
215 
216 CreateCatchContextParameters const& CreateCatchContextParametersOf(
217     Operator const*);
218 
219 // Defines the property of an object for a named access. This is
220 // used as a parameter by the JSLoadNamed and JSStoreNamed operators.
221 class NamedAccess final {
222  public:
NamedAccess(LanguageMode language_mode,Handle<Name> name,VectorSlotPair const & feedback)223   NamedAccess(LanguageMode language_mode, Handle<Name> name,
224               VectorSlotPair const& feedback)
225       : name_(name), feedback_(feedback), language_mode_(language_mode) {}
226 
name()227   Handle<Name> name() const { return name_; }
language_mode()228   LanguageMode language_mode() const { return language_mode_; }
feedback()229   VectorSlotPair const& feedback() const { return feedback_; }
230 
231  private:
232   Handle<Name> const name_;
233   VectorSlotPair const feedback_;
234   LanguageMode const language_mode_;
235 };
236 
237 bool operator==(NamedAccess const&, NamedAccess const&);
238 bool operator!=(NamedAccess const&, NamedAccess const&);
239 
240 size_t hash_value(NamedAccess const&);
241 
242 std::ostream& operator<<(std::ostream&, NamedAccess const&);
243 
244 const NamedAccess& NamedAccessOf(const Operator* op);
245 
246 
247 // Defines the property being loaded from an object by a named load. This is
248 // used as a parameter by JSLoadGlobal operator.
249 class LoadGlobalParameters final {
250  public:
LoadGlobalParameters(const Handle<Name> & name,const VectorSlotPair & feedback,TypeofMode typeof_mode)251   LoadGlobalParameters(const Handle<Name>& name, const VectorSlotPair& feedback,
252                        TypeofMode typeof_mode)
253       : name_(name), feedback_(feedback), typeof_mode_(typeof_mode) {}
254 
name()255   const Handle<Name>& name() const { return name_; }
typeof_mode()256   TypeofMode typeof_mode() const { return typeof_mode_; }
257 
feedback()258   const VectorSlotPair& feedback() const { return feedback_; }
259 
260  private:
261   const Handle<Name> name_;
262   const VectorSlotPair feedback_;
263   const TypeofMode typeof_mode_;
264 };
265 
266 bool operator==(LoadGlobalParameters const&, LoadGlobalParameters const&);
267 bool operator!=(LoadGlobalParameters const&, LoadGlobalParameters const&);
268 
269 size_t hash_value(LoadGlobalParameters const&);
270 
271 std::ostream& operator<<(std::ostream&, LoadGlobalParameters const&);
272 
273 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op);
274 
275 
276 // Defines the property being stored to an object by a named store. This is
277 // used as a parameter by JSStoreGlobal operator.
278 class StoreGlobalParameters final {
279  public:
StoreGlobalParameters(LanguageMode language_mode,const VectorSlotPair & feedback,const Handle<Name> & name)280   StoreGlobalParameters(LanguageMode language_mode,
281                         const VectorSlotPair& feedback,
282                         const Handle<Name>& name)
283       : language_mode_(language_mode), name_(name), feedback_(feedback) {}
284 
language_mode()285   LanguageMode language_mode() const { return language_mode_; }
feedback()286   const VectorSlotPair& feedback() const { return feedback_; }
name()287   const Handle<Name>& name() const { return name_; }
288 
289  private:
290   const LanguageMode language_mode_;
291   const Handle<Name> name_;
292   const VectorSlotPair feedback_;
293 };
294 
295 bool operator==(StoreGlobalParameters const&, StoreGlobalParameters const&);
296 bool operator!=(StoreGlobalParameters const&, StoreGlobalParameters const&);
297 
298 size_t hash_value(StoreGlobalParameters const&);
299 
300 std::ostream& operator<<(std::ostream&, StoreGlobalParameters const&);
301 
302 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op);
303 
304 
305 // Defines the property of an object for a keyed access. This is used
306 // as a parameter by the JSLoadProperty and JSStoreProperty operators.
307 class PropertyAccess final {
308  public:
PropertyAccess(LanguageMode language_mode,VectorSlotPair const & feedback)309   PropertyAccess(LanguageMode language_mode, VectorSlotPair const& feedback)
310       : feedback_(feedback), language_mode_(language_mode) {}
311 
language_mode()312   LanguageMode language_mode() const { return language_mode_; }
feedback()313   VectorSlotPair const& feedback() const { return feedback_; }
314 
315  private:
316   VectorSlotPair const feedback_;
317   LanguageMode const language_mode_;
318 };
319 
320 bool operator==(PropertyAccess const&, PropertyAccess const&);
321 bool operator!=(PropertyAccess const&, PropertyAccess const&);
322 
323 size_t hash_value(PropertyAccess const&);
324 
325 std::ostream& operator<<(std::ostream&, PropertyAccess const&);
326 
327 PropertyAccess const& PropertyAccessOf(const Operator* op);
328 
329 
330 // CreateArgumentsType is used as parameter to JSCreateArguments nodes.
331 CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op);
332 
333 
334 // Defines shared information for the array that should be created. This is
335 // used as parameter by JSCreateArray operators.
336 class CreateArrayParameters final {
337  public:
CreateArrayParameters(size_t arity,Handle<AllocationSite> site)338   explicit CreateArrayParameters(size_t arity, Handle<AllocationSite> site)
339       : arity_(arity), site_(site) {}
340 
arity()341   size_t arity() const { return arity_; }
site()342   Handle<AllocationSite> site() const { return site_; }
343 
344  private:
345   size_t const arity_;
346   Handle<AllocationSite> const site_;
347 };
348 
349 bool operator==(CreateArrayParameters const&, CreateArrayParameters const&);
350 bool operator!=(CreateArrayParameters const&, CreateArrayParameters const&);
351 
352 size_t hash_value(CreateArrayParameters const&);
353 
354 std::ostream& operator<<(std::ostream&, CreateArrayParameters const&);
355 
356 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op);
357 
358 
359 // Defines shared information for the closure that should be created. This is
360 // used as a parameter by JSCreateClosure operators.
361 class CreateClosureParameters final {
362  public:
CreateClosureParameters(Handle<SharedFunctionInfo> shared_info,PretenureFlag pretenure)363   CreateClosureParameters(Handle<SharedFunctionInfo> shared_info,
364                           PretenureFlag pretenure)
365       : shared_info_(shared_info), pretenure_(pretenure) {}
366 
shared_info()367   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
pretenure()368   PretenureFlag pretenure() const { return pretenure_; }
369 
370  private:
371   const Handle<SharedFunctionInfo> shared_info_;
372   const PretenureFlag pretenure_;
373 };
374 
375 bool operator==(CreateClosureParameters const&, CreateClosureParameters const&);
376 bool operator!=(CreateClosureParameters const&, CreateClosureParameters const&);
377 
378 size_t hash_value(CreateClosureParameters const&);
379 
380 std::ostream& operator<<(std::ostream&, CreateClosureParameters const&);
381 
382 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
383 
384 // Defines shared information for the literal that should be created. This is
385 // used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and
386 // JSCreateLiteralRegExp operators.
387 class CreateLiteralParameters final {
388  public:
CreateLiteralParameters(Handle<HeapObject> constant,int length,int flags,int index)389   CreateLiteralParameters(Handle<HeapObject> constant, int length, int flags,
390                           int index)
391       : constant_(constant), length_(length), flags_(flags), index_(index) {}
392 
constant()393   Handle<HeapObject> constant() const { return constant_; }
length()394   int length() const { return length_; }
flags()395   int flags() const { return flags_; }
index()396   int index() const { return index_; }
397 
398  private:
399   Handle<HeapObject> const constant_;
400   int const length_;
401   int const flags_;
402   int const index_;
403 };
404 
405 bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&);
406 bool operator!=(CreateLiteralParameters const&, CreateLiteralParameters const&);
407 
408 size_t hash_value(CreateLiteralParameters const&);
409 
410 std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&);
411 
412 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op);
413 
414 BinaryOperationHint BinaryOperationHintOf(const Operator* op);
415 
416 CompareOperationHint CompareOperationHintOf(const Operator* op);
417 
418 // Interface for building JavaScript-level operators, e.g. directly from the
419 // AST. Most operators have no parameters, thus can be globally shared for all
420 // graphs.
421 class V8_EXPORT_PRIVATE JSOperatorBuilder final
NON_EXPORTED_BASE(ZoneObject)422     : public NON_EXPORTED_BASE(ZoneObject) {
423  public:
424   explicit JSOperatorBuilder(Zone* zone);
425 
426   const Operator* Equal(CompareOperationHint hint);
427   const Operator* NotEqual(CompareOperationHint hint);
428   const Operator* StrictEqual(CompareOperationHint hint);
429   const Operator* StrictNotEqual(CompareOperationHint hint);
430   const Operator* LessThan(CompareOperationHint hint);
431   const Operator* GreaterThan(CompareOperationHint hint);
432   const Operator* LessThanOrEqual(CompareOperationHint hint);
433   const Operator* GreaterThanOrEqual(CompareOperationHint hint);
434 
435   const Operator* BitwiseOr(BinaryOperationHint hint);
436   const Operator* BitwiseXor(BinaryOperationHint hint);
437   const Operator* BitwiseAnd(BinaryOperationHint hint);
438   const Operator* ShiftLeft(BinaryOperationHint hint);
439   const Operator* ShiftRight(BinaryOperationHint hint);
440   const Operator* ShiftRightLogical(BinaryOperationHint hint);
441   const Operator* Add(BinaryOperationHint hint);
442   const Operator* Subtract(BinaryOperationHint hint);
443   const Operator* Multiply(BinaryOperationHint hint);
444   const Operator* Divide(BinaryOperationHint hint);
445   const Operator* Modulus(BinaryOperationHint hint);
446 
447   const Operator* ToBoolean(ToBooleanHints hints);
448   const Operator* ToInteger();
449   const Operator* ToLength();
450   const Operator* ToName();
451   const Operator* ToNumber();
452   const Operator* ToObject();
453   const Operator* ToString();
454 
455   const Operator* Create();
456   const Operator* CreateArguments(CreateArgumentsType type);
457   const Operator* CreateArray(size_t arity, Handle<AllocationSite> site);
458   const Operator* CreateClosure(Handle<SharedFunctionInfo> shared_info,
459                                 PretenureFlag pretenure);
460   const Operator* CreateIterResultObject();
461   const Operator* CreateKeyValueArray();
462   const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements,
463                                      int literal_flags, int literal_index,
464                                      int number_of_elements);
465   const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties,
466                                       int literal_flags, int literal_index,
467                                       int number_of_properties);
468   const Operator* CreateLiteralRegExp(Handle<String> constant_pattern,
469                                       int literal_flags, int literal_index);
470 
471   const Operator* CallFunction(
472       size_t arity, float frequency = 0.0f,
473       VectorSlotPair const& feedback = VectorSlotPair(),
474       ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny,
475       TailCallMode tail_call_mode = TailCallMode::kDisallow);
476   const Operator* CallRuntime(Runtime::FunctionId id);
477   const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
478   const Operator* CallRuntime(const Runtime::Function* function, size_t arity);
479   const Operator* CallConstruct(uint32_t arity, float frequency,
480                                 VectorSlotPair const& feedback);
481 
482   const Operator* ConvertReceiver(ConvertReceiverMode convert_mode);
483 
484   const Operator* LoadProperty(VectorSlotPair const& feedback);
485   const Operator* LoadNamed(Handle<Name> name, VectorSlotPair const& feedback);
486 
487   const Operator* StoreProperty(LanguageMode language_mode,
488                                 VectorSlotPair const& feedback);
489   const Operator* StoreNamed(LanguageMode language_mode, Handle<Name> name,
490                              VectorSlotPair const& feedback);
491 
492   const Operator* DeleteProperty(LanguageMode language_mode);
493 
494   const Operator* HasProperty();
495 
496   const Operator* LoadGlobal(const Handle<Name>& name,
497                              const VectorSlotPair& feedback,
498                              TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
499   const Operator* StoreGlobal(LanguageMode language_mode,
500                               const Handle<Name>& name,
501                               const VectorSlotPair& feedback);
502 
503   const Operator* LoadContext(size_t depth, size_t index, bool immutable);
504   const Operator* StoreContext(size_t depth, size_t index);
505 
506   const Operator* LoadModule(int32_t cell_index);
507   const Operator* StoreModule(int32_t cell_index);
508 
509   const Operator* TypeOf();
510   const Operator* InstanceOf();
511   const Operator* OrdinaryHasInstance();
512 
513   const Operator* ForInNext();
514   const Operator* ForInPrepare();
515 
516   const Operator* LoadMessage();
517   const Operator* StoreMessage();
518 
519   // Used to implement Ignition's SuspendGenerator bytecode.
520   const Operator* GeneratorStore(int register_count);
521 
522   // Used to implement Ignition's ResumeGenerator bytecode.
523   const Operator* GeneratorRestoreContinuation();
524   const Operator* GeneratorRestoreRegister(int index);
525 
526   const Operator* StackCheck();
527 
528   const Operator* CreateFunctionContext(int slot_count);
529   const Operator* CreateCatchContext(const Handle<String>& name,
530                                      const Handle<ScopeInfo>& scope_info);
531   const Operator* CreateWithContext(const Handle<ScopeInfo>& scope_info);
532   const Operator* CreateBlockContext(const Handle<ScopeInfo>& scpope_info);
533   const Operator* CreateModuleContext();
534   const Operator* CreateScriptContext(const Handle<ScopeInfo>& scpope_info);
535 
536  private:
537   Zone* zone() const { return zone_; }
538 
539   const JSOperatorGlobalCache& cache_;
540   Zone* const zone_;
541 
542   DISALLOW_COPY_AND_ASSIGN(JSOperatorBuilder);
543 };
544 
545 }  // namespace compiler
546 }  // namespace internal
547 }  // namespace v8
548 
549 #endif  // V8_COMPILER_JS_OPERATOR_H_
550