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 13namespace v8 { 14namespace internal { 15namespace compiler { 16 17// Forward declarations. 18class Operator; 19struct JSOperatorGlobalCache; 20 21 22// Defines a pair of {TypeFeedbackVector} and {TypeFeedbackVectorSlot}, which 23// is used to access the type feedback for a certain {Node}. 24class V8_EXPORT_PRIVATE VectorSlotPair { 25 public: 26 VectorSlotPair(); 27 VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) 28 : vector_(vector), slot_(slot) {} 29 30 bool IsValid() const { return !vector_.is_null() && !slot_.IsInvalid(); } 31 32 Handle<TypeFeedbackVector> vector() const { return vector_; } 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 42bool operator==(VectorSlotPair const&, VectorSlotPair const&); 43bool operator!=(VectorSlotPair const&, VectorSlotPair const&); 44 45size_t hash_value(VectorSlotPair const&); 46 47 48// The ConvertReceiverMode is used as parameter by JSConvertReceiver operators. 49ConvertReceiverMode ConvertReceiverModeOf(Operator const* op); 50 51 52// The ToBooleanHints are used as parameter by JSToBoolean operators. 53ToBooleanHints 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. 58class CallConstructParameters final { 59 public: 60 CallConstructParameters(uint32_t arity, float frequency, 61 VectorSlotPair const& feedback) 62 : arity_(arity), frequency_(frequency), feedback_(feedback) {} 63 64 uint32_t arity() const { return arity_; } 65 float frequency() const { return frequency_; } 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 74bool operator==(CallConstructParameters const&, CallConstructParameters const&); 75bool operator!=(CallConstructParameters const&, CallConstructParameters const&); 76 77size_t hash_value(CallConstructParameters const&); 78 79std::ostream& operator<<(std::ostream&, CallConstructParameters const&); 80 81CallConstructParameters 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. 86class CallFunctionParameters final { 87 public: 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 98 size_t arity() const { return ArityField::decode(bit_field_); } 99 float frequency() const { return frequency_; } 100 ConvertReceiverMode convert_mode() const { 101 return ConvertReceiverModeField::decode(bit_field_); 102 } 103 TailCallMode tail_call_mode() const { 104 return TailCallModeField::decode(bit_field_); 105 } 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: 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 131size_t hash_value(CallFunctionParameters const&); 132 133std::ostream& operator<<(std::ostream&, CallFunctionParameters const&); 134 135const 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. 140class CallRuntimeParameters final { 141 public: 142 CallRuntimeParameters(Runtime::FunctionId id, size_t arity) 143 : id_(id), arity_(arity) {} 144 145 Runtime::FunctionId id() const { return id_; } 146 size_t arity() const { return arity_; } 147 148 private: 149 const Runtime::FunctionId id_; 150 const size_t arity_; 151}; 152 153bool operator==(CallRuntimeParameters const&, CallRuntimeParameters const&); 154bool operator!=(CallRuntimeParameters const&, CallRuntimeParameters const&); 155 156size_t hash_value(CallRuntimeParameters const&); 157 158std::ostream& operator<<(std::ostream&, CallRuntimeParameters const&); 159 160const 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. 166class ContextAccess final { 167 public: 168 ContextAccess(size_t depth, size_t index, bool immutable); 169 170 size_t depth() const { return depth_; } 171 size_t index() const { return index_; } 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 182bool operator==(ContextAccess const&, ContextAccess const&); 183bool operator!=(ContextAccess const&, ContextAccess const&); 184 185size_t hash_value(ContextAccess const&); 186 187V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ContextAccess const&); 188 189ContextAccess 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. 193class CreateCatchContextParameters final { 194 public: 195 CreateCatchContextParameters(Handle<String> catch_name, 196 Handle<ScopeInfo> scope_info); 197 198 Handle<String> catch_name() const { return catch_name_; } 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 206bool operator==(CreateCatchContextParameters const& lhs, 207 CreateCatchContextParameters const& rhs); 208bool operator!=(CreateCatchContextParameters const& lhs, 209 CreateCatchContextParameters const& rhs); 210 211size_t hash_value(CreateCatchContextParameters const& parameters); 212 213std::ostream& operator<<(std::ostream& os, 214 CreateCatchContextParameters const& parameters); 215 216CreateCatchContextParameters 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. 221class NamedAccess final { 222 public: 223 NamedAccess(LanguageMode language_mode, Handle<Name> name, 224 VectorSlotPair const& feedback) 225 : name_(name), feedback_(feedback), language_mode_(language_mode) {} 226 227 Handle<Name> name() const { return name_; } 228 LanguageMode language_mode() const { return language_mode_; } 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 237bool operator==(NamedAccess const&, NamedAccess const&); 238bool operator!=(NamedAccess const&, NamedAccess const&); 239 240size_t hash_value(NamedAccess const&); 241 242std::ostream& operator<<(std::ostream&, NamedAccess const&); 243 244const 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. 249class LoadGlobalParameters final { 250 public: 251 LoadGlobalParameters(const Handle<Name>& name, const VectorSlotPair& feedback, 252 TypeofMode typeof_mode) 253 : name_(name), feedback_(feedback), typeof_mode_(typeof_mode) {} 254 255 const Handle<Name>& name() const { return name_; } 256 TypeofMode typeof_mode() const { return typeof_mode_; } 257 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 266bool operator==(LoadGlobalParameters const&, LoadGlobalParameters const&); 267bool operator!=(LoadGlobalParameters const&, LoadGlobalParameters const&); 268 269size_t hash_value(LoadGlobalParameters const&); 270 271std::ostream& operator<<(std::ostream&, LoadGlobalParameters const&); 272 273const 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. 278class StoreGlobalParameters final { 279 public: 280 StoreGlobalParameters(LanguageMode language_mode, 281 const VectorSlotPair& feedback, 282 const Handle<Name>& name) 283 : language_mode_(language_mode), name_(name), feedback_(feedback) {} 284 285 LanguageMode language_mode() const { return language_mode_; } 286 const VectorSlotPair& feedback() const { return feedback_; } 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 295bool operator==(StoreGlobalParameters const&, StoreGlobalParameters const&); 296bool operator!=(StoreGlobalParameters const&, StoreGlobalParameters const&); 297 298size_t hash_value(StoreGlobalParameters const&); 299 300std::ostream& operator<<(std::ostream&, StoreGlobalParameters const&); 301 302const 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. 307class PropertyAccess final { 308 public: 309 PropertyAccess(LanguageMode language_mode, VectorSlotPair const& feedback) 310 : feedback_(feedback), language_mode_(language_mode) {} 311 312 LanguageMode language_mode() const { return language_mode_; } 313 VectorSlotPair const& feedback() const { return feedback_; } 314 315 private: 316 VectorSlotPair const feedback_; 317 LanguageMode const language_mode_; 318}; 319 320bool operator==(PropertyAccess const&, PropertyAccess const&); 321bool operator!=(PropertyAccess const&, PropertyAccess const&); 322 323size_t hash_value(PropertyAccess const&); 324 325std::ostream& operator<<(std::ostream&, PropertyAccess const&); 326 327PropertyAccess const& PropertyAccessOf(const Operator* op); 328 329 330// CreateArgumentsType is used as parameter to JSCreateArguments nodes. 331CreateArgumentsType 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. 336class CreateArrayParameters final { 337 public: 338 explicit CreateArrayParameters(size_t arity, Handle<AllocationSite> site) 339 : arity_(arity), site_(site) {} 340 341 size_t arity() const { return arity_; } 342 Handle<AllocationSite> site() const { return site_; } 343 344 private: 345 size_t const arity_; 346 Handle<AllocationSite> const site_; 347}; 348 349bool operator==(CreateArrayParameters const&, CreateArrayParameters const&); 350bool operator!=(CreateArrayParameters const&, CreateArrayParameters const&); 351 352size_t hash_value(CreateArrayParameters const&); 353 354std::ostream& operator<<(std::ostream&, CreateArrayParameters const&); 355 356const 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. 361class CreateClosureParameters final { 362 public: 363 CreateClosureParameters(Handle<SharedFunctionInfo> shared_info, 364 PretenureFlag pretenure) 365 : shared_info_(shared_info), pretenure_(pretenure) {} 366 367 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } 368 PretenureFlag pretenure() const { return pretenure_; } 369 370 private: 371 const Handle<SharedFunctionInfo> shared_info_; 372 const PretenureFlag pretenure_; 373}; 374 375bool operator==(CreateClosureParameters const&, CreateClosureParameters const&); 376bool operator!=(CreateClosureParameters const&, CreateClosureParameters const&); 377 378size_t hash_value(CreateClosureParameters const&); 379 380std::ostream& operator<<(std::ostream&, CreateClosureParameters const&); 381 382const 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. 387class CreateLiteralParameters final { 388 public: 389 CreateLiteralParameters(Handle<HeapObject> constant, int length, int flags, 390 int index) 391 : constant_(constant), length_(length), flags_(flags), index_(index) {} 392 393 Handle<HeapObject> constant() const { return constant_; } 394 int length() const { return length_; } 395 int flags() const { return flags_; } 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 405bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&); 406bool operator!=(CreateLiteralParameters const&, CreateLiteralParameters const&); 407 408size_t hash_value(CreateLiteralParameters const&); 409 410std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&); 411 412const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op); 413 414BinaryOperationHint BinaryOperationHintOf(const Operator* op); 415 416CompareOperationHint 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. 421class V8_EXPORT_PRIVATE JSOperatorBuilder final 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