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 whether tail call optimization is allowed. 55 enum class TailCallMode : unsigned { kAllow, kDisallow }; 56 57 size_t hash_value(TailCallMode); 58 59 std::ostream& operator<<(std::ostream&, TailCallMode); 60 61 62 // Defines the language mode and hints for a JavaScript binary operations. 63 // This is used as parameter by JSAdd, JSSubtract, etc. operators. 64 class BinaryOperationParameters final { 65 public: BinaryOperationParameters(LanguageMode language_mode,BinaryOperationHints hints)66 BinaryOperationParameters(LanguageMode language_mode, 67 BinaryOperationHints hints) 68 : language_mode_(language_mode), hints_(hints) {} 69 language_mode()70 LanguageMode language_mode() const { return language_mode_; } hints()71 BinaryOperationHints hints() const { return hints_; } 72 73 private: 74 LanguageMode const language_mode_; 75 BinaryOperationHints const hints_; 76 }; 77 78 bool operator==(BinaryOperationParameters const&, 79 BinaryOperationParameters const&); 80 bool operator!=(BinaryOperationParameters const&, 81 BinaryOperationParameters const&); 82 83 size_t hash_value(BinaryOperationParameters const&); 84 85 std::ostream& operator<<(std::ostream&, BinaryOperationParameters const&); 86 87 BinaryOperationParameters const& BinaryOperationParametersOf(Operator const*); 88 89 90 // Defines the arity and the feedback for a JavaScript constructor call. This is 91 // used as a parameter by JSCallConstruct operators. 92 class CallConstructParameters final { 93 public: CallConstructParameters(size_t arity,VectorSlotPair const & feedback)94 CallConstructParameters(size_t arity, VectorSlotPair const& feedback) 95 : arity_(arity), feedback_(feedback) {} 96 arity()97 size_t arity() const { return arity_; } feedback()98 VectorSlotPair const& feedback() const { return feedback_; } 99 100 private: 101 size_t const arity_; 102 VectorSlotPair const feedback_; 103 }; 104 105 bool operator==(CallConstructParameters const&, CallConstructParameters const&); 106 bool operator!=(CallConstructParameters const&, CallConstructParameters const&); 107 108 size_t hash_value(CallConstructParameters const&); 109 110 std::ostream& operator<<(std::ostream&, CallConstructParameters const&); 111 112 CallConstructParameters const& CallConstructParametersOf(Operator const*); 113 114 115 // Defines the arity and the call flags for a JavaScript function call. This is 116 // used as a parameter by JSCallFunction operators. 117 class CallFunctionParameters final { 118 public: CallFunctionParameters(size_t arity,LanguageMode language_mode,VectorSlotPair const & feedback,TailCallMode tail_call_mode,ConvertReceiverMode convert_mode)119 CallFunctionParameters(size_t arity, LanguageMode language_mode, 120 VectorSlotPair const& feedback, 121 TailCallMode tail_call_mode, 122 ConvertReceiverMode convert_mode) 123 : bit_field_(ArityField::encode(arity) | 124 ConvertReceiverModeField::encode(convert_mode) | 125 LanguageModeField::encode(language_mode) | 126 TailCallModeField::encode(tail_call_mode)), 127 feedback_(feedback) {} 128 arity()129 size_t arity() const { return ArityField::decode(bit_field_); } language_mode()130 LanguageMode language_mode() const { 131 return LanguageModeField::decode(bit_field_); 132 } convert_mode()133 ConvertReceiverMode convert_mode() const { 134 return ConvertReceiverModeField::decode(bit_field_); 135 } tail_call_mode()136 TailCallMode tail_call_mode() const { 137 return TailCallModeField::decode(bit_field_); 138 } feedback()139 VectorSlotPair const& feedback() const { return feedback_; } 140 141 bool operator==(CallFunctionParameters const& that) const { 142 return this->bit_field_ == that.bit_field_ && 143 this->feedback_ == that.feedback_; 144 } 145 bool operator!=(CallFunctionParameters const& that) const { 146 return !(*this == that); 147 } 148 149 private: hash_value(CallFunctionParameters const & p)150 friend size_t hash_value(CallFunctionParameters const& p) { 151 return base::hash_combine(p.bit_field_, p.feedback_); 152 } 153 154 typedef BitField<size_t, 0, 27> ArityField; 155 typedef BitField<ConvertReceiverMode, 27, 2> ConvertReceiverModeField; 156 typedef BitField<LanguageMode, 29, 2> LanguageModeField; 157 typedef BitField<TailCallMode, 31, 1> TailCallModeField; 158 159 const uint32_t bit_field_; 160 const VectorSlotPair feedback_; 161 }; 162 163 size_t hash_value(CallFunctionParameters const&); 164 165 std::ostream& operator<<(std::ostream&, CallFunctionParameters const&); 166 167 const CallFunctionParameters& CallFunctionParametersOf(const Operator* op); 168 169 170 // Defines the arity and the ID for a runtime function call. This is used as a 171 // parameter by JSCallRuntime operators. 172 class CallRuntimeParameters final { 173 public: CallRuntimeParameters(Runtime::FunctionId id,size_t arity)174 CallRuntimeParameters(Runtime::FunctionId id, size_t arity) 175 : id_(id), arity_(arity) {} 176 id()177 Runtime::FunctionId id() const { return id_; } arity()178 size_t arity() const { return arity_; } 179 180 private: 181 const Runtime::FunctionId id_; 182 const size_t arity_; 183 }; 184 185 bool operator==(CallRuntimeParameters const&, CallRuntimeParameters const&); 186 bool operator!=(CallRuntimeParameters const&, CallRuntimeParameters const&); 187 188 size_t hash_value(CallRuntimeParameters const&); 189 190 std::ostream& operator<<(std::ostream&, CallRuntimeParameters const&); 191 192 const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op); 193 194 195 // Defines the location of a context slot relative to a specific scope. This is 196 // used as a parameter by JSLoadContext and JSStoreContext operators and allows 197 // accessing a context-allocated variable without keeping track of the scope. 198 class ContextAccess final { 199 public: 200 ContextAccess(size_t depth, size_t index, bool immutable); 201 depth()202 size_t depth() const { return depth_; } index()203 size_t index() const { return index_; } immutable()204 bool immutable() const { return immutable_; } 205 206 private: 207 // For space reasons, we keep this tightly packed, otherwise we could just use 208 // a simple int/int/bool POD. 209 const bool immutable_; 210 const uint16_t depth_; 211 const uint32_t index_; 212 }; 213 214 bool operator==(ContextAccess const&, ContextAccess const&); 215 bool operator!=(ContextAccess const&, ContextAccess const&); 216 217 size_t hash_value(ContextAccess const&); 218 219 std::ostream& operator<<(std::ostream&, ContextAccess const&); 220 221 ContextAccess const& ContextAccessOf(Operator const*); 222 223 224 // Defines the name for a dynamic variable lookup. This is used as a parameter 225 // by JSLoadDynamic and JSStoreDynamic operators. 226 class DynamicAccess final { 227 public: 228 DynamicAccess(const Handle<String>& name, TypeofMode typeof_mode); 229 name()230 const Handle<String>& name() const { return name_; } typeof_mode()231 TypeofMode typeof_mode() const { return typeof_mode_; } 232 233 private: 234 const Handle<String> name_; 235 const TypeofMode typeof_mode_; 236 }; 237 238 size_t hash_value(DynamicAccess const&); 239 240 bool operator==(DynamicAccess const&, DynamicAccess const&); 241 bool operator!=(DynamicAccess const&, DynamicAccess const&); 242 243 std::ostream& operator<<(std::ostream&, DynamicAccess const&); 244 245 DynamicAccess const& DynamicAccessOf(Operator const*); 246 247 248 // Defines the property of an object for a named access. This is 249 // used as a parameter by the JSLoadNamed and JSStoreNamed operators. 250 class NamedAccess final { 251 public: NamedAccess(LanguageMode language_mode,Handle<Name> name,VectorSlotPair const & feedback)252 NamedAccess(LanguageMode language_mode, Handle<Name> name, 253 VectorSlotPair const& feedback) 254 : name_(name), feedback_(feedback), language_mode_(language_mode) {} 255 name()256 Handle<Name> name() const { return name_; } language_mode()257 LanguageMode language_mode() const { return language_mode_; } feedback()258 VectorSlotPair const& feedback() const { return feedback_; } 259 260 private: 261 Handle<Name> const name_; 262 VectorSlotPair const feedback_; 263 LanguageMode const language_mode_; 264 }; 265 266 bool operator==(NamedAccess const&, NamedAccess const&); 267 bool operator!=(NamedAccess const&, NamedAccess const&); 268 269 size_t hash_value(NamedAccess const&); 270 271 std::ostream& operator<<(std::ostream&, NamedAccess const&); 272 273 const NamedAccess& NamedAccessOf(const Operator* op); 274 275 276 // Defines the property being loaded from an object by a named load. This is 277 // used as a parameter by JSLoadGlobal operator. 278 class LoadGlobalParameters final { 279 public: LoadGlobalParameters(const Handle<Name> & name,const VectorSlotPair & feedback,TypeofMode typeof_mode)280 LoadGlobalParameters(const Handle<Name>& name, const VectorSlotPair& feedback, 281 TypeofMode typeof_mode) 282 : name_(name), feedback_(feedback), typeof_mode_(typeof_mode) {} 283 name()284 const Handle<Name>& name() const { return name_; } typeof_mode()285 TypeofMode typeof_mode() const { return typeof_mode_; } 286 feedback()287 const VectorSlotPair& feedback() const { return feedback_; } 288 289 private: 290 const Handle<Name> name_; 291 const VectorSlotPair feedback_; 292 const TypeofMode typeof_mode_; 293 }; 294 295 bool operator==(LoadGlobalParameters const&, LoadGlobalParameters const&); 296 bool operator!=(LoadGlobalParameters const&, LoadGlobalParameters const&); 297 298 size_t hash_value(LoadGlobalParameters const&); 299 300 std::ostream& operator<<(std::ostream&, LoadGlobalParameters const&); 301 302 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op); 303 304 305 // Defines the property being stored to an object by a named store. This is 306 // used as a parameter by JSStoreGlobal operator. 307 class StoreGlobalParameters final { 308 public: StoreGlobalParameters(LanguageMode language_mode,const VectorSlotPair & feedback,const Handle<Name> & name)309 StoreGlobalParameters(LanguageMode language_mode, 310 const VectorSlotPair& feedback, 311 const Handle<Name>& name) 312 : language_mode_(language_mode), name_(name), feedback_(feedback) {} 313 language_mode()314 LanguageMode language_mode() const { return language_mode_; } feedback()315 const VectorSlotPair& feedback() const { return feedback_; } name()316 const Handle<Name>& name() const { return name_; } 317 318 private: 319 const LanguageMode language_mode_; 320 const Handle<Name> name_; 321 const VectorSlotPair feedback_; 322 }; 323 324 bool operator==(StoreGlobalParameters const&, StoreGlobalParameters const&); 325 bool operator!=(StoreGlobalParameters const&, StoreGlobalParameters const&); 326 327 size_t hash_value(StoreGlobalParameters const&); 328 329 std::ostream& operator<<(std::ostream&, StoreGlobalParameters const&); 330 331 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op); 332 333 334 // Defines the property of an object for a keyed access. This is used 335 // as a parameter by the JSLoadProperty and JSStoreProperty operators. 336 class PropertyAccess final { 337 public: PropertyAccess(LanguageMode language_mode,VectorSlotPair const & feedback)338 PropertyAccess(LanguageMode language_mode, VectorSlotPair const& feedback) 339 : feedback_(feedback), language_mode_(language_mode) {} 340 language_mode()341 LanguageMode language_mode() const { return language_mode_; } feedback()342 VectorSlotPair const& feedback() const { return feedback_; } 343 344 private: 345 VectorSlotPair const feedback_; 346 LanguageMode const language_mode_; 347 }; 348 349 bool operator==(PropertyAccess const&, PropertyAccess const&); 350 bool operator!=(PropertyAccess const&, PropertyAccess const&); 351 352 size_t hash_value(PropertyAccess const&); 353 354 std::ostream& operator<<(std::ostream&, PropertyAccess const&); 355 356 PropertyAccess const& PropertyAccessOf(const Operator* op); 357 358 359 // Defines specifics about arguments object or rest parameter creation. This is 360 // used as a parameter by JSCreateArguments operators. 361 class CreateArgumentsParameters final { 362 public: 363 enum Type { kMappedArguments, kUnmappedArguments, kRestArray }; CreateArgumentsParameters(Type type,int start_index)364 CreateArgumentsParameters(Type type, int start_index) 365 : type_(type), start_index_(start_index) {} 366 type()367 Type type() const { return type_; } start_index()368 int start_index() const { return start_index_; } 369 370 private: 371 const Type type_; 372 const int start_index_; 373 }; 374 375 bool operator==(CreateArgumentsParameters const&, 376 CreateArgumentsParameters const&); 377 bool operator!=(CreateArgumentsParameters const&, 378 CreateArgumentsParameters const&); 379 380 size_t hash_value(CreateArgumentsParameters const&); 381 382 std::ostream& operator<<(std::ostream&, CreateArgumentsParameters const&); 383 384 const CreateArgumentsParameters& CreateArgumentsParametersOf( 385 const Operator* op); 386 387 388 // Defines shared information for the array that should be created. This is 389 // used as parameter by JSCreateArray operators. 390 class CreateArrayParameters final { 391 public: CreateArrayParameters(size_t arity,Handle<AllocationSite> site)392 explicit CreateArrayParameters(size_t arity, Handle<AllocationSite> site) 393 : arity_(arity), site_(site) {} 394 arity()395 size_t arity() const { return arity_; } site()396 Handle<AllocationSite> site() const { return site_; } 397 398 private: 399 size_t const arity_; 400 Handle<AllocationSite> const site_; 401 }; 402 403 bool operator==(CreateArrayParameters const&, CreateArrayParameters const&); 404 bool operator!=(CreateArrayParameters const&, CreateArrayParameters const&); 405 406 size_t hash_value(CreateArrayParameters const&); 407 408 std::ostream& operator<<(std::ostream&, CreateArrayParameters const&); 409 410 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op); 411 412 413 // Defines shared information for the closure that should be created. This is 414 // used as a parameter by JSCreateClosure operators. 415 class CreateClosureParameters final { 416 public: CreateClosureParameters(Handle<SharedFunctionInfo> shared_info,PretenureFlag pretenure)417 CreateClosureParameters(Handle<SharedFunctionInfo> shared_info, 418 PretenureFlag pretenure) 419 : shared_info_(shared_info), pretenure_(pretenure) {} 420 shared_info()421 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } pretenure()422 PretenureFlag pretenure() const { return pretenure_; } 423 424 private: 425 const Handle<SharedFunctionInfo> shared_info_; 426 const PretenureFlag pretenure_; 427 }; 428 429 bool operator==(CreateClosureParameters const&, CreateClosureParameters const&); 430 bool operator!=(CreateClosureParameters const&, CreateClosureParameters const&); 431 432 size_t hash_value(CreateClosureParameters const&); 433 434 std::ostream& operator<<(std::ostream&, CreateClosureParameters const&); 435 436 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op); 437 438 439 // Defines shared information for the literal that should be created. This is 440 // used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and 441 // JSCreateLiteralRegExp operators. 442 class CreateLiteralParameters final { 443 public: CreateLiteralParameters(Handle<HeapObject> constant,int flags,int index)444 CreateLiteralParameters(Handle<HeapObject> constant, int flags, int index) 445 : constant_(constant), flags_(flags), index_(index) {} 446 constant()447 Handle<HeapObject> constant() const { return constant_; } flags()448 int flags() const { return flags_; } index()449 int index() const { return index_; } 450 451 private: 452 Handle<HeapObject> const constant_; 453 int const flags_; 454 int const index_; 455 }; 456 457 bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&); 458 bool operator!=(CreateLiteralParameters const&, CreateLiteralParameters const&); 459 460 size_t hash_value(CreateLiteralParameters const&); 461 462 std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&); 463 464 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op); 465 466 467 // Interface for building JavaScript-level operators, e.g. directly from the 468 // AST. Most operators have no parameters, thus can be globally shared for all 469 // graphs. 470 class JSOperatorBuilder final : public ZoneObject { 471 public: 472 explicit JSOperatorBuilder(Zone* zone); 473 474 const Operator* Equal(); 475 const Operator* NotEqual(); 476 const Operator* StrictEqual(); 477 const Operator* StrictNotEqual(); 478 const Operator* LessThan(LanguageMode language_mode); 479 const Operator* GreaterThan(LanguageMode language_mode); 480 const Operator* LessThanOrEqual(LanguageMode language_mode); 481 const Operator* GreaterThanOrEqual(LanguageMode language_mode); 482 const Operator* BitwiseOr(LanguageMode language_mode, 483 BinaryOperationHints hints); 484 const Operator* BitwiseXor(LanguageMode language_mode, 485 BinaryOperationHints hints); 486 const Operator* BitwiseAnd(LanguageMode language_mode, 487 BinaryOperationHints hints); 488 const Operator* ShiftLeft(LanguageMode language_mode, 489 BinaryOperationHints hints); 490 const Operator* ShiftRight(LanguageMode language_mode, 491 BinaryOperationHints hints); 492 const Operator* ShiftRightLogical(LanguageMode language_mode, 493 BinaryOperationHints hints); 494 const Operator* Add(LanguageMode language_mode, BinaryOperationHints hints); 495 const Operator* Subtract(LanguageMode language_mode, 496 BinaryOperationHints hints); 497 const Operator* Multiply(LanguageMode language_mode, 498 BinaryOperationHints hints); 499 const Operator* Divide(LanguageMode language_mode, 500 BinaryOperationHints hints); 501 const Operator* Modulus(LanguageMode language_mode, 502 BinaryOperationHints hints); 503 504 const Operator* ToBoolean(ToBooleanHints hints); 505 const Operator* ToNumber(); 506 const Operator* ToString(); 507 const Operator* ToName(); 508 const Operator* ToObject(); 509 const Operator* Yield(); 510 511 const Operator* Create(); 512 const Operator* CreateArguments(CreateArgumentsParameters::Type type, 513 int start_index); 514 const Operator* CreateArray(size_t arity, Handle<AllocationSite> site); 515 const Operator* CreateClosure(Handle<SharedFunctionInfo> shared_info, 516 PretenureFlag pretenure); 517 const Operator* CreateIterResultObject(); 518 const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements, 519 int literal_flags, int literal_index); 520 const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties, 521 int literal_flags, int literal_index); 522 const Operator* CreateLiteralRegExp(Handle<String> constant_pattern, 523 int literal_flags, int literal_index); 524 525 const Operator* CallFunction( 526 size_t arity, LanguageMode language_mode, 527 VectorSlotPair const& feedback = VectorSlotPair(), 528 ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny, 529 TailCallMode tail_call_mode = TailCallMode::kDisallow); 530 const Operator* CallRuntime(Runtime::FunctionId id, size_t arity); 531 const Operator* CallConstruct(size_t arity, VectorSlotPair const& feedback); 532 533 const Operator* ConvertReceiver(ConvertReceiverMode convert_mode); 534 535 const Operator* LoadProperty(LanguageMode language_mode, 536 VectorSlotPair const& feedback); 537 const Operator* LoadNamed(LanguageMode language_mode, Handle<Name> name, 538 VectorSlotPair const& feedback); 539 540 const Operator* StoreProperty(LanguageMode language_mode, 541 VectorSlotPair const& feedback); 542 const Operator* StoreNamed(LanguageMode language_mode, Handle<Name> name, 543 VectorSlotPair const& feedback); 544 545 const Operator* DeleteProperty(LanguageMode language_mode); 546 547 const Operator* HasProperty(); 548 549 const Operator* LoadGlobal(const Handle<Name>& name, 550 const VectorSlotPair& feedback, 551 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF); 552 const Operator* StoreGlobal(LanguageMode language_mode, 553 const Handle<Name>& name, 554 const VectorSlotPair& feedback); 555 556 const Operator* LoadContext(size_t depth, size_t index, bool immutable); 557 const Operator* StoreContext(size_t depth, size_t index); 558 559 const Operator* LoadDynamic(const Handle<String>& name, 560 TypeofMode typeof_mode); 561 562 const Operator* TypeOf(); 563 const Operator* InstanceOf(); 564 565 const Operator* ForInDone(); 566 const Operator* ForInNext(); 567 const Operator* ForInPrepare(); 568 const Operator* ForInStep(); 569 570 const Operator* LoadMessage(); 571 const Operator* StoreMessage(); 572 573 const Operator* StackCheck(); 574 575 const Operator* CreateFunctionContext(int slot_count); 576 const Operator* CreateCatchContext(const Handle<String>& name); 577 const Operator* CreateWithContext(); 578 const Operator* CreateBlockContext(const Handle<ScopeInfo>& scpope_info); 579 const Operator* CreateModuleContext(); 580 const Operator* CreateScriptContext(const Handle<ScopeInfo>& scpope_info); 581 582 private: zone()583 Zone* zone() const { return zone_; } 584 585 const JSOperatorGlobalCache& cache_; 586 Zone* const zone_; 587 588 DISALLOW_COPY_AND_ASSIGN(JSOperatorBuilder); 589 }; 590 591 } // namespace compiler 592 } // namespace internal 593 } // namespace v8 594 595 #endif // V8_COMPILER_JS_OPERATOR_H_ 596