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