1// Copyright 2014 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#include "src/compiler/js-operator.h" 6 7#include <limits> 8 9#include "src/base/lazy-instance.h" 10#include "src/compiler/opcodes.h" 11#include "src/compiler/operator.h" 12#include "src/handles-inl.h" 13#include "src/type-feedback-vector.h" 14 15namespace v8 { 16namespace internal { 17namespace compiler { 18 19VectorSlotPair::VectorSlotPair() {} 20 21 22int VectorSlotPair::index() const { 23 return vector_.is_null() ? -1 : vector_->GetIndex(slot_); 24} 25 26 27bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) { 28 return lhs.slot() == rhs.slot() && 29 lhs.vector().location() == rhs.vector().location(); 30} 31 32 33bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) { 34 return !(lhs == rhs); 35} 36 37 38size_t hash_value(VectorSlotPair const& p) { 39 return base::hash_combine(p.slot(), p.vector().location()); 40} 41 42 43ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) { 44 DCHECK_EQ(IrOpcode::kJSConvertReceiver, op->opcode()); 45 return OpParameter<ConvertReceiverMode>(op); 46} 47 48 49ToBooleanHints ToBooleanHintsOf(Operator const* op) { 50 DCHECK_EQ(IrOpcode::kJSToBoolean, op->opcode()); 51 return OpParameter<ToBooleanHints>(op); 52} 53 54 55bool operator==(CallConstructParameters const& lhs, 56 CallConstructParameters const& rhs) { 57 return lhs.arity() == rhs.arity() && lhs.frequency() == rhs.frequency() && 58 lhs.feedback() == rhs.feedback(); 59} 60 61 62bool operator!=(CallConstructParameters const& lhs, 63 CallConstructParameters const& rhs) { 64 return !(lhs == rhs); 65} 66 67 68size_t hash_value(CallConstructParameters const& p) { 69 return base::hash_combine(p.arity(), p.frequency(), p.feedback()); 70} 71 72 73std::ostream& operator<<(std::ostream& os, CallConstructParameters const& p) { 74 return os << p.arity() << ", " << p.frequency(); 75} 76 77 78CallConstructParameters const& CallConstructParametersOf(Operator const* op) { 79 DCHECK_EQ(IrOpcode::kJSCallConstruct, op->opcode()); 80 return OpParameter<CallConstructParameters>(op); 81} 82 83 84std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) { 85 os << p.arity() << ", " << p.frequency() << ", " << p.convert_mode() << ", " 86 << p.tail_call_mode(); 87 return os; 88} 89 90 91const CallFunctionParameters& CallFunctionParametersOf(const Operator* op) { 92 DCHECK_EQ(IrOpcode::kJSCallFunction, op->opcode()); 93 return OpParameter<CallFunctionParameters>(op); 94} 95 96 97bool operator==(CallRuntimeParameters const& lhs, 98 CallRuntimeParameters const& rhs) { 99 return lhs.id() == rhs.id() && lhs.arity() == rhs.arity(); 100} 101 102 103bool operator!=(CallRuntimeParameters const& lhs, 104 CallRuntimeParameters const& rhs) { 105 return !(lhs == rhs); 106} 107 108 109size_t hash_value(CallRuntimeParameters const& p) { 110 return base::hash_combine(p.id(), p.arity()); 111} 112 113 114std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) { 115 return os << p.id() << ", " << p.arity(); 116} 117 118 119const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) { 120 DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode()); 121 return OpParameter<CallRuntimeParameters>(op); 122} 123 124 125ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable) 126 : immutable_(immutable), 127 depth_(static_cast<uint16_t>(depth)), 128 index_(static_cast<uint32_t>(index)) { 129 DCHECK(depth <= std::numeric_limits<uint16_t>::max()); 130 DCHECK(index <= std::numeric_limits<uint32_t>::max()); 131} 132 133 134bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) { 135 return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() && 136 lhs.immutable() == rhs.immutable(); 137} 138 139 140bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) { 141 return !(lhs == rhs); 142} 143 144 145size_t hash_value(ContextAccess const& access) { 146 return base::hash_combine(access.depth(), access.index(), access.immutable()); 147} 148 149 150std::ostream& operator<<(std::ostream& os, ContextAccess const& access) { 151 return os << access.depth() << ", " << access.index() << ", " 152 << access.immutable(); 153} 154 155 156ContextAccess const& ContextAccessOf(Operator const* op) { 157 DCHECK(op->opcode() == IrOpcode::kJSLoadContext || 158 op->opcode() == IrOpcode::kJSStoreContext); 159 return OpParameter<ContextAccess>(op); 160} 161 162CreateCatchContextParameters::CreateCatchContextParameters( 163 Handle<String> catch_name, Handle<ScopeInfo> scope_info) 164 : catch_name_(catch_name), scope_info_(scope_info) {} 165 166bool operator==(CreateCatchContextParameters const& lhs, 167 CreateCatchContextParameters const& rhs) { 168 return lhs.catch_name().location() == rhs.catch_name().location() && 169 lhs.scope_info().location() == rhs.scope_info().location(); 170} 171 172bool operator!=(CreateCatchContextParameters const& lhs, 173 CreateCatchContextParameters const& rhs) { 174 return !(lhs == rhs); 175} 176 177size_t hash_value(CreateCatchContextParameters const& parameters) { 178 return base::hash_combine(parameters.catch_name().location(), 179 parameters.scope_info().location()); 180} 181 182std::ostream& operator<<(std::ostream& os, 183 CreateCatchContextParameters const& parameters) { 184 return os << Brief(*parameters.catch_name()) << ", " 185 << Brief(*parameters.scope_info()); 186} 187 188CreateCatchContextParameters const& CreateCatchContextParametersOf( 189 Operator const* op) { 190 DCHECK_EQ(IrOpcode::kJSCreateCatchContext, op->opcode()); 191 return OpParameter<CreateCatchContextParameters>(op); 192} 193 194bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) { 195 return lhs.name().location() == rhs.name().location() && 196 lhs.language_mode() == rhs.language_mode() && 197 lhs.feedback() == rhs.feedback(); 198} 199 200 201bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) { 202 return !(lhs == rhs); 203} 204 205 206size_t hash_value(NamedAccess const& p) { 207 return base::hash_combine(p.name().location(), p.language_mode(), 208 p.feedback()); 209} 210 211 212std::ostream& operator<<(std::ostream& os, NamedAccess const& p) { 213 return os << Brief(*p.name()) << ", " << p.language_mode(); 214} 215 216 217NamedAccess const& NamedAccessOf(const Operator* op) { 218 DCHECK(op->opcode() == IrOpcode::kJSLoadNamed || 219 op->opcode() == IrOpcode::kJSStoreNamed); 220 return OpParameter<NamedAccess>(op); 221} 222 223 224std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) { 225 return os << p.language_mode(); 226} 227 228 229bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) { 230 return lhs.language_mode() == rhs.language_mode() && 231 lhs.feedback() == rhs.feedback(); 232} 233 234 235bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) { 236 return !(lhs == rhs); 237} 238 239 240PropertyAccess const& PropertyAccessOf(const Operator* op) { 241 DCHECK(op->opcode() == IrOpcode::kJSLoadProperty || 242 op->opcode() == IrOpcode::kJSStoreProperty); 243 return OpParameter<PropertyAccess>(op); 244} 245 246 247size_t hash_value(PropertyAccess const& p) { 248 return base::hash_combine(p.language_mode(), p.feedback()); 249} 250 251 252bool operator==(LoadGlobalParameters const& lhs, 253 LoadGlobalParameters const& rhs) { 254 return lhs.name().location() == rhs.name().location() && 255 lhs.feedback() == rhs.feedback() && 256 lhs.typeof_mode() == rhs.typeof_mode(); 257} 258 259 260bool operator!=(LoadGlobalParameters const& lhs, 261 LoadGlobalParameters const& rhs) { 262 return !(lhs == rhs); 263} 264 265 266size_t hash_value(LoadGlobalParameters const& p) { 267 return base::hash_combine(p.name().location(), p.typeof_mode()); 268} 269 270 271std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) { 272 return os << Brief(*p.name()) << ", " << p.typeof_mode(); 273} 274 275 276const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) { 277 DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode()); 278 return OpParameter<LoadGlobalParameters>(op); 279} 280 281 282bool operator==(StoreGlobalParameters const& lhs, 283 StoreGlobalParameters const& rhs) { 284 return lhs.language_mode() == rhs.language_mode() && 285 lhs.name().location() == rhs.name().location() && 286 lhs.feedback() == rhs.feedback(); 287} 288 289 290bool operator!=(StoreGlobalParameters const& lhs, 291 StoreGlobalParameters const& rhs) { 292 return !(lhs == rhs); 293} 294 295 296size_t hash_value(StoreGlobalParameters const& p) { 297 return base::hash_combine(p.language_mode(), p.name().location(), 298 p.feedback()); 299} 300 301 302std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) { 303 return os << p.language_mode() << ", " << Brief(*p.name()); 304} 305 306 307const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) { 308 DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode()); 309 return OpParameter<StoreGlobalParameters>(op); 310} 311 312 313CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op) { 314 DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode()); 315 return OpParameter<CreateArgumentsType>(op); 316} 317 318 319bool operator==(CreateArrayParameters const& lhs, 320 CreateArrayParameters const& rhs) { 321 return lhs.arity() == rhs.arity() && 322 lhs.site().location() == rhs.site().location(); 323} 324 325 326bool operator!=(CreateArrayParameters const& lhs, 327 CreateArrayParameters const& rhs) { 328 return !(lhs == rhs); 329} 330 331 332size_t hash_value(CreateArrayParameters const& p) { 333 return base::hash_combine(p.arity(), p.site().location()); 334} 335 336 337std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) { 338 os << p.arity(); 339 if (!p.site().is_null()) os << ", " << Brief(*p.site()); 340 return os; 341} 342 343 344const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) { 345 DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode()); 346 return OpParameter<CreateArrayParameters>(op); 347} 348 349 350bool operator==(CreateClosureParameters const& lhs, 351 CreateClosureParameters const& rhs) { 352 return lhs.pretenure() == rhs.pretenure() && 353 lhs.shared_info().location() == rhs.shared_info().location(); 354} 355 356 357bool operator!=(CreateClosureParameters const& lhs, 358 CreateClosureParameters const& rhs) { 359 return !(lhs == rhs); 360} 361 362 363size_t hash_value(CreateClosureParameters const& p) { 364 return base::hash_combine(p.pretenure(), p.shared_info().location()); 365} 366 367 368std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) { 369 return os << p.pretenure() << ", " << Brief(*p.shared_info()); 370} 371 372 373const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) { 374 DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode()); 375 return OpParameter<CreateClosureParameters>(op); 376} 377 378 379bool operator==(CreateLiteralParameters const& lhs, 380 CreateLiteralParameters const& rhs) { 381 return lhs.constant().location() == rhs.constant().location() && 382 lhs.length() == rhs.length() && lhs.flags() == rhs.flags() && 383 lhs.index() == rhs.index(); 384} 385 386 387bool operator!=(CreateLiteralParameters const& lhs, 388 CreateLiteralParameters const& rhs) { 389 return !(lhs == rhs); 390} 391 392 393size_t hash_value(CreateLiteralParameters const& p) { 394 return base::hash_combine(p.constant().location(), p.length(), p.flags(), 395 p.index()); 396} 397 398 399std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) { 400 return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags() 401 << ", " << p.index(); 402} 403 404 405const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) { 406 DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray || 407 op->opcode() == IrOpcode::kJSCreateLiteralObject || 408 op->opcode() == IrOpcode::kJSCreateLiteralRegExp); 409 return OpParameter<CreateLiteralParameters>(op); 410} 411 412BinaryOperationHint BinaryOperationHintOf(const Operator* op) { 413 DCHECK(op->opcode() == IrOpcode::kJSBitwiseOr || 414 op->opcode() == IrOpcode::kJSBitwiseXor || 415 op->opcode() == IrOpcode::kJSBitwiseAnd || 416 op->opcode() == IrOpcode::kJSShiftLeft || 417 op->opcode() == IrOpcode::kJSShiftRight || 418 op->opcode() == IrOpcode::kJSShiftRightLogical || 419 op->opcode() == IrOpcode::kJSAdd || 420 op->opcode() == IrOpcode::kJSSubtract || 421 op->opcode() == IrOpcode::kJSMultiply || 422 op->opcode() == IrOpcode::kJSDivide || 423 op->opcode() == IrOpcode::kJSModulus); 424 return OpParameter<BinaryOperationHint>(op); 425} 426 427CompareOperationHint CompareOperationHintOf(const Operator* op) { 428 DCHECK(op->opcode() == IrOpcode::kJSEqual || 429 op->opcode() == IrOpcode::kJSNotEqual || 430 op->opcode() == IrOpcode::kJSStrictEqual || 431 op->opcode() == IrOpcode::kJSStrictNotEqual || 432 op->opcode() == IrOpcode::kJSLessThan || 433 op->opcode() == IrOpcode::kJSGreaterThan || 434 op->opcode() == IrOpcode::kJSLessThanOrEqual || 435 op->opcode() == IrOpcode::kJSGreaterThanOrEqual); 436 return OpParameter<CompareOperationHint>(op); 437} 438 439#define CACHED_OP_LIST(V) \ 440 V(ToInteger, Operator::kNoProperties, 1, 1) \ 441 V(ToLength, Operator::kNoProperties, 1, 1) \ 442 V(ToName, Operator::kNoProperties, 1, 1) \ 443 V(ToNumber, Operator::kNoProperties, 1, 1) \ 444 V(ToObject, Operator::kFoldable, 1, 1) \ 445 V(ToString, Operator::kNoProperties, 1, 1) \ 446 V(Create, Operator::kEliminatable, 2, 1) \ 447 V(CreateIterResultObject, Operator::kEliminatable, 2, 1) \ 448 V(CreateKeyValueArray, Operator::kEliminatable, 2, 1) \ 449 V(HasProperty, Operator::kNoProperties, 2, 1) \ 450 V(TypeOf, Operator::kPure, 1, 1) \ 451 V(InstanceOf, Operator::kNoProperties, 2, 1) \ 452 V(OrdinaryHasInstance, Operator::kNoProperties, 2, 1) \ 453 V(ForInNext, Operator::kNoProperties, 4, 1) \ 454 V(ForInPrepare, Operator::kNoProperties, 1, 3) \ 455 V(LoadMessage, Operator::kNoThrow, 0, 1) \ 456 V(StoreMessage, Operator::kNoThrow, 1, 0) \ 457 V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \ 458 V(StackCheck, Operator::kNoWrite, 0, 0) 459 460#define BINARY_OP_LIST(V) \ 461 V(BitwiseOr) \ 462 V(BitwiseXor) \ 463 V(BitwiseAnd) \ 464 V(ShiftLeft) \ 465 V(ShiftRight) \ 466 V(ShiftRightLogical) \ 467 V(Add) \ 468 V(Subtract) \ 469 V(Multiply) \ 470 V(Divide) \ 471 V(Modulus) 472 473#define COMPARE_OP_LIST(V) \ 474 V(Equal, Operator::kNoProperties) \ 475 V(NotEqual, Operator::kNoProperties) \ 476 V(StrictEqual, Operator::kPure) \ 477 V(StrictNotEqual, Operator::kPure) \ 478 V(LessThan, Operator::kNoProperties) \ 479 V(GreaterThan, Operator::kNoProperties) \ 480 V(LessThanOrEqual, Operator::kNoProperties) \ 481 V(GreaterThanOrEqual, Operator::kNoProperties) 482 483struct JSOperatorGlobalCache final { 484#define CACHED_OP(Name, properties, value_input_count, value_output_count) \ 485 struct Name##Operator final : public Operator { \ 486 Name##Operator() \ 487 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \ 488 value_input_count, Operator::ZeroIfPure(properties), \ 489 Operator::ZeroIfEliminatable(properties), \ 490 value_output_count, Operator::ZeroIfPure(properties), \ 491 Operator::ZeroIfNoThrow(properties)) {} \ 492 }; \ 493 Name##Operator k##Name##Operator; 494 CACHED_OP_LIST(CACHED_OP) 495#undef CACHED_OP 496 497#define BINARY_OP(Name) \ 498 template <BinaryOperationHint kHint> \ 499 struct Name##Operator final : public Operator1<BinaryOperationHint> { \ 500 Name##Operator() \ 501 : Operator1<BinaryOperationHint>(IrOpcode::kJS##Name, \ 502 Operator::kNoProperties, "JS" #Name, \ 503 2, 1, 1, 1, 1, 2, kHint) {} \ 504 }; \ 505 Name##Operator<BinaryOperationHint::kNone> k##Name##NoneOperator; \ 506 Name##Operator<BinaryOperationHint::kSignedSmall> \ 507 k##Name##SignedSmallOperator; \ 508 Name##Operator<BinaryOperationHint::kSigned32> k##Name##Signed32Operator; \ 509 Name##Operator<BinaryOperationHint::kNumberOrOddball> \ 510 k##Name##NumberOrOddballOperator; \ 511 Name##Operator<BinaryOperationHint::kString> k##Name##StringOperator; \ 512 Name##Operator<BinaryOperationHint::kAny> k##Name##AnyOperator; 513 BINARY_OP_LIST(BINARY_OP) 514#undef BINARY_OP 515 516#define COMPARE_OP(Name, properties) \ 517 template <CompareOperationHint kHint> \ 518 struct Name##Operator final : public Operator1<CompareOperationHint> { \ 519 Name##Operator() \ 520 : Operator1<CompareOperationHint>( \ 521 IrOpcode::kJS##Name, properties, "JS" #Name, 2, 1, 1, 1, 1, \ 522 Operator::ZeroIfNoThrow(properties), kHint) {} \ 523 }; \ 524 Name##Operator<CompareOperationHint::kNone> k##Name##NoneOperator; \ 525 Name##Operator<CompareOperationHint::kSignedSmall> \ 526 k##Name##SignedSmallOperator; \ 527 Name##Operator<CompareOperationHint::kNumber> k##Name##NumberOperator; \ 528 Name##Operator<CompareOperationHint::kNumberOrOddball> \ 529 k##Name##NumberOrOddballOperator; \ 530 Name##Operator<CompareOperationHint::kAny> k##Name##AnyOperator; 531 COMPARE_OP_LIST(COMPARE_OP) 532#undef COMPARE_OP 533}; 534 535static base::LazyInstance<JSOperatorGlobalCache>::type kCache = 536 LAZY_INSTANCE_INITIALIZER; 537 538JSOperatorBuilder::JSOperatorBuilder(Zone* zone) 539 : cache_(kCache.Get()), zone_(zone) {} 540 541#define CACHED_OP(Name, properties, value_input_count, value_output_count) \ 542 const Operator* JSOperatorBuilder::Name() { \ 543 return &cache_.k##Name##Operator; \ 544 } 545CACHED_OP_LIST(CACHED_OP) 546#undef CACHED_OP 547 548#define BINARY_OP(Name) \ 549 const Operator* JSOperatorBuilder::Name(BinaryOperationHint hint) { \ 550 switch (hint) { \ 551 case BinaryOperationHint::kNone: \ 552 return &cache_.k##Name##NoneOperator; \ 553 case BinaryOperationHint::kSignedSmall: \ 554 return &cache_.k##Name##SignedSmallOperator; \ 555 case BinaryOperationHint::kSigned32: \ 556 return &cache_.k##Name##Signed32Operator; \ 557 case BinaryOperationHint::kNumberOrOddball: \ 558 return &cache_.k##Name##NumberOrOddballOperator; \ 559 case BinaryOperationHint::kString: \ 560 return &cache_.k##Name##StringOperator; \ 561 case BinaryOperationHint::kAny: \ 562 return &cache_.k##Name##AnyOperator; \ 563 } \ 564 UNREACHABLE(); \ 565 return nullptr; \ 566 } 567BINARY_OP_LIST(BINARY_OP) 568#undef BINARY_OP 569 570#define COMPARE_OP(Name, ...) \ 571 const Operator* JSOperatorBuilder::Name(CompareOperationHint hint) { \ 572 switch (hint) { \ 573 case CompareOperationHint::kNone: \ 574 return &cache_.k##Name##NoneOperator; \ 575 case CompareOperationHint::kSignedSmall: \ 576 return &cache_.k##Name##SignedSmallOperator; \ 577 case CompareOperationHint::kNumber: \ 578 return &cache_.k##Name##NumberOperator; \ 579 case CompareOperationHint::kNumberOrOddball: \ 580 return &cache_.k##Name##NumberOrOddballOperator; \ 581 case CompareOperationHint::kAny: \ 582 return &cache_.k##Name##AnyOperator; \ 583 } \ 584 UNREACHABLE(); \ 585 return nullptr; \ 586 } 587COMPARE_OP_LIST(COMPARE_OP) 588#undef COMPARE_OP 589 590const Operator* JSOperatorBuilder::ToBoolean(ToBooleanHints hints) { 591 // TODO(turbofan): Cache most important versions of this operator. 592 return new (zone()) Operator1<ToBooleanHints>( //-- 593 IrOpcode::kJSToBoolean, Operator::kPure, // opcode 594 "JSToBoolean", // name 595 1, 0, 0, 1, 0, 0, // inputs/outputs 596 hints); // parameter 597} 598 599const Operator* JSOperatorBuilder::CallFunction( 600 size_t arity, float frequency, VectorSlotPair const& feedback, 601 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) { 602 CallFunctionParameters parameters(arity, frequency, feedback, tail_call_mode, 603 convert_mode); 604 return new (zone()) Operator1<CallFunctionParameters>( // -- 605 IrOpcode::kJSCallFunction, Operator::kNoProperties, // opcode 606 "JSCallFunction", // name 607 parameters.arity(), 1, 1, 1, 1, 2, // inputs/outputs 608 parameters); // parameter 609} 610 611 612const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id) { 613 const Runtime::Function* f = Runtime::FunctionForId(id); 614 return CallRuntime(f, f->nargs); 615} 616 617 618const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, 619 size_t arity) { 620 const Runtime::Function* f = Runtime::FunctionForId(id); 621 return CallRuntime(f, arity); 622} 623 624 625const Operator* JSOperatorBuilder::CallRuntime(const Runtime::Function* f, 626 size_t arity) { 627 CallRuntimeParameters parameters(f->function_id, arity); 628 DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity())); 629 return new (zone()) Operator1<CallRuntimeParameters>( // -- 630 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode 631 "JSCallRuntime", // name 632 parameters.arity(), 1, 1, f->result_size, 1, 2, // inputs/outputs 633 parameters); // parameter 634} 635 636const Operator* JSOperatorBuilder::CallConstruct( 637 uint32_t arity, float frequency, VectorSlotPair const& feedback) { 638 CallConstructParameters parameters(arity, frequency, feedback); 639 return new (zone()) Operator1<CallConstructParameters>( // -- 640 IrOpcode::kJSCallConstruct, Operator::kNoProperties, // opcode 641 "JSCallConstruct", // name 642 parameters.arity(), 1, 1, 1, 1, 2, // counts 643 parameters); // parameter 644} 645 646 647const Operator* JSOperatorBuilder::ConvertReceiver( 648 ConvertReceiverMode convert_mode) { 649 return new (zone()) Operator1<ConvertReceiverMode>( // -- 650 IrOpcode::kJSConvertReceiver, Operator::kEliminatable, // opcode 651 "JSConvertReceiver", // name 652 1, 1, 1, 1, 1, 0, // counts 653 convert_mode); // parameter 654} 655 656const Operator* JSOperatorBuilder::LoadNamed(Handle<Name> name, 657 const VectorSlotPair& feedback) { 658 NamedAccess access(SLOPPY, name, feedback); 659 return new (zone()) Operator1<NamedAccess>( // -- 660 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode 661 "JSLoadNamed", // name 662 2, 1, 1, 1, 1, 2, // counts 663 access); // parameter 664} 665 666const Operator* JSOperatorBuilder::LoadProperty( 667 VectorSlotPair const& feedback) { 668 PropertyAccess access(SLOPPY, feedback); 669 return new (zone()) Operator1<PropertyAccess>( // -- 670 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode 671 "JSLoadProperty", // name 672 3, 1, 1, 1, 1, 2, // counts 673 access); // parameter 674} 675 676const Operator* JSOperatorBuilder::GeneratorStore(int register_count) { 677 return new (zone()) Operator1<int>( // -- 678 IrOpcode::kJSGeneratorStore, Operator::kNoThrow, // opcode 679 "JSGeneratorStore", // name 680 3 + register_count, 1, 1, 0, 1, 0, // counts 681 register_count); // parameter 682} 683 684const Operator* JSOperatorBuilder::GeneratorRestoreRegister(int index) { 685 return new (zone()) Operator1<int>( // -- 686 IrOpcode::kJSGeneratorRestoreRegister, Operator::kNoThrow, // opcode 687 "JSGeneratorRestoreRegister", // name 688 1, 1, 1, 1, 1, 0, // counts 689 index); // parameter 690} 691 692const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode, 693 Handle<Name> name, 694 VectorSlotPair const& feedback) { 695 NamedAccess access(language_mode, name, feedback); 696 return new (zone()) Operator1<NamedAccess>( // -- 697 IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode 698 "JSStoreNamed", // name 699 3, 1, 1, 0, 1, 2, // counts 700 access); // parameter 701} 702 703 704const Operator* JSOperatorBuilder::StoreProperty( 705 LanguageMode language_mode, VectorSlotPair const& feedback) { 706 PropertyAccess access(language_mode, feedback); 707 return new (zone()) Operator1<PropertyAccess>( // -- 708 IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode 709 "JSStoreProperty", // name 710 4, 1, 1, 0, 1, 2, // counts 711 access); // parameter 712} 713 714 715const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) { 716 return new (zone()) Operator1<LanguageMode>( // -- 717 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode 718 "JSDeleteProperty", // name 719 2, 1, 1, 1, 1, 2, // counts 720 language_mode); // parameter 721} 722 723 724const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name, 725 const VectorSlotPair& feedback, 726 TypeofMode typeof_mode) { 727 LoadGlobalParameters parameters(name, feedback, typeof_mode); 728 return new (zone()) Operator1<LoadGlobalParameters>( // -- 729 IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode 730 "JSLoadGlobal", // name 731 1, 1, 1, 1, 1, 2, // counts 732 parameters); // parameter 733} 734 735 736const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode, 737 const Handle<Name>& name, 738 const VectorSlotPair& feedback) { 739 StoreGlobalParameters parameters(language_mode, feedback, name); 740 return new (zone()) Operator1<StoreGlobalParameters>( // -- 741 IrOpcode::kJSStoreGlobal, Operator::kNoProperties, // opcode 742 "JSStoreGlobal", // name 743 2, 1, 1, 0, 1, 2, // counts 744 parameters); // parameter 745} 746 747 748const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, 749 bool immutable) { 750 ContextAccess access(depth, index, immutable); 751 return new (zone()) Operator1<ContextAccess>( // -- 752 IrOpcode::kJSLoadContext, // opcode 753 Operator::kNoWrite | Operator::kNoThrow, // flags 754 "JSLoadContext", // name 755 1, 1, 0, 1, 1, 0, // counts 756 access); // parameter 757} 758 759 760const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { 761 ContextAccess access(depth, index, false); 762 return new (zone()) Operator1<ContextAccess>( // -- 763 IrOpcode::kJSStoreContext, // opcode 764 Operator::kNoRead | Operator::kNoThrow, // flags 765 "JSStoreContext", // name 766 2, 1, 1, 0, 1, 0, // counts 767 access); // parameter 768} 769 770const Operator* JSOperatorBuilder::LoadModule(int32_t cell_index) { 771 return new (zone()) Operator1<int32_t>( // -- 772 IrOpcode::kJSLoadModule, // opcode 773 Operator::kNoWrite | Operator::kNoThrow, // flags 774 "JSLoadModule", // name 775 1, 1, 1, 1, 1, 0, // counts 776 cell_index); // parameter 777} 778 779const Operator* JSOperatorBuilder::StoreModule(int32_t cell_index) { 780 return new (zone()) Operator1<int32_t>( // -- 781 IrOpcode::kJSStoreModule, // opcode 782 Operator::kNoRead | Operator::kNoThrow, // flags 783 "JSStoreModule", // name 784 2, 1, 1, 0, 1, 0, // counts 785 cell_index); // parameter 786} 787 788const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) { 789 return new (zone()) Operator1<CreateArgumentsType>( // -- 790 IrOpcode::kJSCreateArguments, Operator::kEliminatable, // opcode 791 "JSCreateArguments", // name 792 1, 1, 0, 1, 1, 0, // counts 793 type); // parameter 794} 795 796 797const Operator* JSOperatorBuilder::CreateArray(size_t arity, 798 Handle<AllocationSite> site) { 799 // constructor, new_target, arg1, ..., argN 800 int const value_input_count = static_cast<int>(arity) + 2; 801 CreateArrayParameters parameters(arity, site); 802 return new (zone()) Operator1<CreateArrayParameters>( // -- 803 IrOpcode::kJSCreateArray, Operator::kNoProperties, // opcode 804 "JSCreateArray", // name 805 value_input_count, 1, 1, 1, 1, 2, // counts 806 parameters); // parameter 807} 808 809 810const Operator* JSOperatorBuilder::CreateClosure( 811 Handle<SharedFunctionInfo> shared_info, PretenureFlag pretenure) { 812 CreateClosureParameters parameters(shared_info, pretenure); 813 return new (zone()) Operator1<CreateClosureParameters>( // -- 814 IrOpcode::kJSCreateClosure, Operator::kNoThrow, // opcode 815 "JSCreateClosure", // name 816 0, 1, 1, 1, 1, 0, // counts 817 parameters); // parameter 818} 819 820const Operator* JSOperatorBuilder::CreateLiteralArray( 821 Handle<FixedArray> constant_elements, int literal_flags, int literal_index, 822 int number_of_elements) { 823 CreateLiteralParameters parameters(constant_elements, number_of_elements, 824 literal_flags, literal_index); 825 return new (zone()) Operator1<CreateLiteralParameters>( // -- 826 IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties, // opcode 827 "JSCreateLiteralArray", // name 828 1, 1, 1, 1, 1, 2, // counts 829 parameters); // parameter 830} 831 832const Operator* JSOperatorBuilder::CreateLiteralObject( 833 Handle<FixedArray> constant_properties, int literal_flags, 834 int literal_index, int number_of_properties) { 835 CreateLiteralParameters parameters(constant_properties, number_of_properties, 836 literal_flags, literal_index); 837 return new (zone()) Operator1<CreateLiteralParameters>( // -- 838 IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties, // opcode 839 "JSCreateLiteralObject", // name 840 1, 1, 1, 1, 1, 2, // counts 841 parameters); // parameter 842} 843 844 845const Operator* JSOperatorBuilder::CreateLiteralRegExp( 846 Handle<String> constant_pattern, int literal_flags, int literal_index) { 847 CreateLiteralParameters parameters(constant_pattern, -1, literal_flags, 848 literal_index); 849 return new (zone()) Operator1<CreateLiteralParameters>( // -- 850 IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties, // opcode 851 "JSCreateLiteralRegExp", // name 852 1, 1, 1, 1, 1, 2, // counts 853 parameters); // parameter 854} 855 856 857const Operator* JSOperatorBuilder::CreateFunctionContext(int slot_count) { 858 return new (zone()) Operator1<int>( // -- 859 IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties, // opcode 860 "JSCreateFunctionContext", // name 861 1, 1, 1, 1, 1, 2, // counts 862 slot_count); // parameter 863} 864 865const Operator* JSOperatorBuilder::CreateCatchContext( 866 const Handle<String>& name, const Handle<ScopeInfo>& scope_info) { 867 CreateCatchContextParameters parameters(name, scope_info); 868 return new (zone()) Operator1<CreateCatchContextParameters>( 869 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode 870 "JSCreateCatchContext", // name 871 2, 1, 1, 1, 1, 2, // counts 872 parameters); // parameter 873} 874 875const Operator* JSOperatorBuilder::CreateWithContext( 876 const Handle<ScopeInfo>& scope_info) { 877 return new (zone()) Operator1<Handle<ScopeInfo>>( 878 IrOpcode::kJSCreateWithContext, Operator::kNoProperties, // opcode 879 "JSCreateWithContext", // name 880 2, 1, 1, 1, 1, 2, // counts 881 scope_info); // parameter 882} 883 884const Operator* JSOperatorBuilder::CreateBlockContext( 885 const Handle<ScopeInfo>& scpope_info) { 886 return new (zone()) Operator1<Handle<ScopeInfo>>( // -- 887 IrOpcode::kJSCreateBlockContext, Operator::kNoProperties, // opcode 888 "JSCreateBlockContext", // name 889 1, 1, 1, 1, 1, 2, // counts 890 scpope_info); // parameter 891} 892 893 894const Operator* JSOperatorBuilder::CreateScriptContext( 895 const Handle<ScopeInfo>& scpope_info) { 896 return new (zone()) Operator1<Handle<ScopeInfo>>( // -- 897 IrOpcode::kJSCreateScriptContext, Operator::kNoProperties, // opcode 898 "JSCreateScriptContext", // name 899 1, 1, 1, 1, 1, 2, // counts 900 scpope_info); // parameter 901} 902 903} // namespace compiler 904} // namespace internal 905} // namespace v8 906