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