1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_X64_LITHIUM_X64_H_ 29 #define V8_X64_LITHIUM_X64_H_ 30 31 #include "hydrogen.h" 32 #include "lithium-allocator.h" 33 #include "lithium.h" 34 #include "safepoint-table.h" 35 #include "utils.h" 36 37 namespace v8 { 38 namespace internal { 39 40 // Forward declarations. 41 class LCodeGen; 42 43 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ 44 V(AccessArgumentsAt) \ 45 V(AddI) \ 46 V(Allocate) \ 47 V(ApplyArguments) \ 48 V(ArgumentsElements) \ 49 V(ArgumentsLength) \ 50 V(ArithmeticD) \ 51 V(ArithmeticT) \ 52 V(BitI) \ 53 V(BoundsCheck) \ 54 V(Branch) \ 55 V(CallConstantFunction) \ 56 V(CallFunction) \ 57 V(CallGlobal) \ 58 V(CallKeyed) \ 59 V(CallKnownGlobal) \ 60 V(CallNamed) \ 61 V(CallNew) \ 62 V(CallNewArray) \ 63 V(CallRuntime) \ 64 V(CallStub) \ 65 V(CheckFunction) \ 66 V(CheckInstanceType) \ 67 V(CheckMaps) \ 68 V(CheckMapValue) \ 69 V(CheckNonSmi) \ 70 V(CheckSmi) \ 71 V(ClampDToUint8) \ 72 V(ClampIToUint8) \ 73 V(ClampTToUint8) \ 74 V(ClassOfTestAndBranch) \ 75 V(CompareNumericAndBranch) \ 76 V(CmpObjectEqAndBranch) \ 77 V(CmpHoleAndBranch) \ 78 V(CmpMapAndBranch) \ 79 V(CmpT) \ 80 V(ConstantD) \ 81 V(ConstantE) \ 82 V(ConstantI) \ 83 V(ConstantS) \ 84 V(ConstantT) \ 85 V(Context) \ 86 V(DateField) \ 87 V(DebugBreak) \ 88 V(DeclareGlobals) \ 89 V(Deoptimize) \ 90 V(DivI) \ 91 V(DoubleToI) \ 92 V(DoubleToSmi) \ 93 V(Drop) \ 94 V(DummyUse) \ 95 V(ElementsKind) \ 96 V(ForInCacheArray) \ 97 V(ForInPrepareMap) \ 98 V(FunctionLiteral) \ 99 V(GetCachedArrayIndex) \ 100 V(GlobalObject) \ 101 V(GlobalReceiver) \ 102 V(Goto) \ 103 V(HasCachedArrayIndexAndBranch) \ 104 V(HasInstanceTypeAndBranch) \ 105 V(InnerAllocatedObject) \ 106 V(InstanceOf) \ 107 V(InstanceOfKnownGlobal) \ 108 V(InstanceSize) \ 109 V(InstructionGap) \ 110 V(Integer32ToDouble) \ 111 V(Integer32ToSmi) \ 112 V(InvokeFunction) \ 113 V(IsConstructCallAndBranch) \ 114 V(IsObjectAndBranch) \ 115 V(IsStringAndBranch) \ 116 V(IsSmiAndBranch) \ 117 V(IsNumberAndBranch) \ 118 V(IsUndetectableAndBranch) \ 119 V(Label) \ 120 V(LazyBailout) \ 121 V(LoadContextSlot) \ 122 V(LoadExternalArrayPointer) \ 123 V(LoadFieldByIndex) \ 124 V(LoadFunctionPrototype) \ 125 V(LoadGlobalCell) \ 126 V(LoadGlobalGeneric) \ 127 V(LoadKeyed) \ 128 V(LoadKeyedGeneric) \ 129 V(LoadNamedField) \ 130 V(LoadNamedGeneric) \ 131 V(MapEnumLength) \ 132 V(MathAbs) \ 133 V(MathCos) \ 134 V(MathExp) \ 135 V(MathFloor) \ 136 V(MathFloorOfDiv) \ 137 V(MathLog) \ 138 V(MathMinMax) \ 139 V(MathPowHalf) \ 140 V(MathRound) \ 141 V(MathSin) \ 142 V(MathSqrt) \ 143 V(MathTan) \ 144 V(ModI) \ 145 V(MulI) \ 146 V(NumberTagD) \ 147 V(NumberTagI) \ 148 V(NumberTagU) \ 149 V(NumberUntagD) \ 150 V(OsrEntry) \ 151 V(OuterContext) \ 152 V(Parameter) \ 153 V(Power) \ 154 V(PushArgument) \ 155 V(Random) \ 156 V(RegExpLiteral) \ 157 V(Return) \ 158 V(SeqStringSetChar) \ 159 V(ShiftI) \ 160 V(SmiTag) \ 161 V(SmiUntag) \ 162 V(StackCheck) \ 163 V(StoreContextSlot) \ 164 V(StoreGlobalCell) \ 165 V(StoreGlobalGeneric) \ 166 V(StoreKeyed) \ 167 V(StoreKeyedGeneric) \ 168 V(StoreNamedField) \ 169 V(StoreNamedGeneric) \ 170 V(StringAdd) \ 171 V(StringCharCodeAt) \ 172 V(StringCharFromCode) \ 173 V(StringCompareAndBranch) \ 174 V(SubI) \ 175 V(TaggedToI) \ 176 V(ThisFunction) \ 177 V(Throw) \ 178 V(ToFastProperties) \ 179 V(TransitionElementsKind) \ 180 V(TrapAllocationMemento) \ 181 V(Typeof) \ 182 V(TypeofIsAndBranch) \ 183 V(Uint32ToDouble) \ 184 V(Uint32ToSmi) \ 185 V(UnknownOSRValue) \ 186 V(ValueOf) \ 187 V(WrapReceiver) 188 189 190 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ 191 virtual Opcode opcode() const { return LInstruction::k##type; } \ 192 virtual void CompileToNative(LCodeGen* generator); \ 193 virtual const char* Mnemonic() const { return mnemonic; } \ 194 static L##type* cast(LInstruction* instr) { \ 195 ASSERT(instr->Is##type()); \ 196 return reinterpret_cast<L##type*>(instr); \ 197 } 198 199 200 #define DECLARE_HYDROGEN_ACCESSOR(type) \ 201 H##type* hydrogen() const { \ 202 return H##type::cast(hydrogen_value()); \ 203 } 204 205 206 class LInstruction: public ZoneObject { 207 public: 208 LInstruction() 209 : environment_(NULL), 210 hydrogen_value_(NULL), 211 bit_field_(IsCallBits::encode(false)) { 212 set_position(RelocInfo::kNoPosition); 213 } 214 215 virtual ~LInstruction() { } 216 217 virtual void CompileToNative(LCodeGen* generator) = 0; 218 virtual const char* Mnemonic() const = 0; 219 virtual void PrintTo(StringStream* stream); 220 virtual void PrintDataTo(StringStream* stream); 221 virtual void PrintOutputOperandTo(StringStream* stream); 222 223 enum Opcode { 224 // Declare a unique enum value for each instruction. 225 #define DECLARE_OPCODE(type) k##type, 226 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) 227 kNumberOfInstructions 228 #undef DECLARE_OPCODE 229 }; 230 231 virtual Opcode opcode() const = 0; 232 233 // Declare non-virtual type testers for all leaf IR classes. 234 #define DECLARE_PREDICATE(type) \ 235 bool Is##type() const { return opcode() == k##type; } 236 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE) 237 #undef DECLARE_PREDICATE 238 239 // Declare virtual predicates for instructions that don't have 240 // an opcode. 241 virtual bool IsGap() const { return false; } 242 243 virtual bool IsControl() const { return false; } 244 245 void set_environment(LEnvironment* env) { environment_ = env; } 246 LEnvironment* environment() const { return environment_; } 247 bool HasEnvironment() const { return environment_ != NULL; } 248 249 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } 250 LPointerMap* pointer_map() const { return pointer_map_.get(); } 251 bool HasPointerMap() const { return pointer_map_.is_set(); } 252 253 // The 31 bits PositionBits is used to store the int position value. And the 254 // position value may be RelocInfo::kNoPosition (-1). The accessor always 255 // +1/-1 so that the encoded value of position in bit_field_ is always >= 0 256 // and can fit into the 31 bits PositionBits. 257 void set_position(int pos) { 258 bit_field_ = PositionBits::update(bit_field_, pos + 1); 259 } 260 int position() { return PositionBits::decode(bit_field_) - 1; } 261 262 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } 263 HValue* hydrogen_value() const { return hydrogen_value_; } 264 265 void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); } 266 bool IsCall() const { return IsCallBits::decode(bit_field_); } 267 268 // Interface to the register allocator and iterators. 269 bool ClobbersTemps() const { return IsCall(); } 270 bool ClobbersRegisters() const { return IsCall(); } 271 bool ClobbersDoubleRegisters() const { return IsCall(); } 272 273 virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } 274 275 // Interface to the register allocator and iterators. 276 bool IsMarkedAsCall() const { return IsCall(); } 277 278 virtual bool HasResult() const = 0; 279 virtual LOperand* result() const = 0; 280 281 LOperand* FirstInput() { return InputAt(0); } 282 LOperand* Output() { return HasResult() ? result() : NULL; } 283 284 virtual bool HasInterestingComment(LCodeGen* gen) const { return true; } 285 286 #ifdef DEBUG 287 void VerifyCall(); 288 #endif 289 290 private: 291 // Iterator support. 292 friend class InputIterator; 293 virtual int InputCount() = 0; 294 virtual LOperand* InputAt(int i) = 0; 295 296 friend class TempIterator; 297 virtual int TempCount() = 0; 298 virtual LOperand* TempAt(int i) = 0; 299 300 class IsCallBits: public BitField<bool, 0, 1> {}; 301 class PositionBits: public BitField<int, 1, 31> {}; 302 303 LEnvironment* environment_; 304 SetOncePointer<LPointerMap> pointer_map_; 305 HValue* hydrogen_value_; 306 int bit_field_; 307 }; 308 309 310 // R = number of result operands (0 or 1). 311 // I = number of input operands. 312 // T = number of temporary operands. 313 template<int R, int I, int T> 314 class LTemplateInstruction: public LInstruction { 315 public: 316 // Allow 0 or 1 output operands. 317 STATIC_ASSERT(R == 0 || R == 1); 318 virtual bool HasResult() const { return R != 0 && result() != NULL; } 319 void set_result(LOperand* operand) { results_[0] = operand; } 320 LOperand* result() const { return results_[0]; } 321 322 protected: 323 EmbeddedContainer<LOperand*, R> results_; 324 EmbeddedContainer<LOperand*, I> inputs_; 325 EmbeddedContainer<LOperand*, T> temps_; 326 327 private: 328 // Iterator support. 329 virtual int InputCount() { return I; } 330 virtual LOperand* InputAt(int i) { return inputs_[i]; } 331 332 virtual int TempCount() { return T; } 333 virtual LOperand* TempAt(int i) { return temps_[i]; } 334 }; 335 336 337 class LGap: public LTemplateInstruction<0, 0, 0> { 338 public: 339 explicit LGap(HBasicBlock* block) 340 : block_(block) { 341 parallel_moves_[BEFORE] = NULL; 342 parallel_moves_[START] = NULL; 343 parallel_moves_[END] = NULL; 344 parallel_moves_[AFTER] = NULL; 345 } 346 347 // Can't use the DECLARE-macro here because of sub-classes. 348 virtual bool IsGap() const { return true; } 349 virtual void PrintDataTo(StringStream* stream); 350 static LGap* cast(LInstruction* instr) { 351 ASSERT(instr->IsGap()); 352 return reinterpret_cast<LGap*>(instr); 353 } 354 355 bool IsRedundant() const; 356 357 HBasicBlock* block() const { return block_; } 358 359 enum InnerPosition { 360 BEFORE, 361 START, 362 END, 363 AFTER, 364 FIRST_INNER_POSITION = BEFORE, 365 LAST_INNER_POSITION = AFTER 366 }; 367 368 LParallelMove* GetOrCreateParallelMove(InnerPosition pos, 369 Zone* zone) { 370 if (parallel_moves_[pos] == NULL) { 371 parallel_moves_[pos] = new(zone) LParallelMove(zone); 372 } 373 return parallel_moves_[pos]; 374 } 375 376 LParallelMove* GetParallelMove(InnerPosition pos) { 377 return parallel_moves_[pos]; 378 } 379 380 private: 381 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; 382 HBasicBlock* block_; 383 }; 384 385 386 class LInstructionGap: public LGap { 387 public: 388 explicit LInstructionGap(HBasicBlock* block) : LGap(block) { } 389 390 virtual bool HasInterestingComment(LCodeGen* gen) const { 391 return !IsRedundant(); 392 } 393 394 DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap") 395 }; 396 397 398 class LGoto: public LTemplateInstruction<0, 0, 0> { 399 public: 400 explicit LGoto(int block_id) : block_id_(block_id) { } 401 402 virtual bool HasInterestingComment(LCodeGen* gen) const; 403 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") 404 virtual void PrintDataTo(StringStream* stream); 405 virtual bool IsControl() const { return true; } 406 407 int block_id() const { return block_id_; } 408 409 private: 410 int block_id_; 411 }; 412 413 414 class LLazyBailout: public LTemplateInstruction<0, 0, 0> { 415 public: 416 LLazyBailout() : gap_instructions_size_(0) { } 417 418 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") 419 420 void set_gap_instructions_size(int gap_instructions_size) { 421 gap_instructions_size_ = gap_instructions_size; 422 } 423 int gap_instructions_size() { return gap_instructions_size_; } 424 425 private: 426 int gap_instructions_size_; 427 }; 428 429 430 class LDummyUse: public LTemplateInstruction<1, 1, 0> { 431 public: 432 explicit LDummyUse(LOperand* value) { 433 inputs_[0] = value; 434 } 435 DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use") 436 }; 437 438 439 class LDeoptimize: public LTemplateInstruction<0, 0, 0> { 440 public: 441 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") 442 DECLARE_HYDROGEN_ACCESSOR(Deoptimize) 443 }; 444 445 446 class LLabel: public LGap { 447 public: 448 explicit LLabel(HBasicBlock* block) 449 : LGap(block), replacement_(NULL) { } 450 451 virtual bool HasInterestingComment(LCodeGen* gen) const { return false; } 452 DECLARE_CONCRETE_INSTRUCTION(Label, "label") 453 454 virtual void PrintDataTo(StringStream* stream); 455 456 int block_id() const { return block()->block_id(); } 457 bool is_loop_header() const { return block()->IsLoopHeader(); } 458 bool is_osr_entry() const { return block()->is_osr_entry(); } 459 Label* label() { return &label_; } 460 LLabel* replacement() const { return replacement_; } 461 void set_replacement(LLabel* label) { replacement_ = label; } 462 bool HasReplacement() const { return replacement_ != NULL; } 463 464 private: 465 Label label_; 466 LLabel* replacement_; 467 }; 468 469 470 class LParameter: public LTemplateInstruction<1, 0, 0> { 471 public: 472 virtual bool HasInterestingComment(LCodeGen* gen) const { return false; } 473 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter") 474 }; 475 476 477 class LCallStub: public LTemplateInstruction<1, 0, 0> { 478 public: 479 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub") 480 DECLARE_HYDROGEN_ACCESSOR(CallStub) 481 482 TranscendentalCache::Type transcendental_type() { 483 return hydrogen()->transcendental_type(); 484 } 485 }; 486 487 488 class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { 489 public: 490 virtual bool HasInterestingComment(LCodeGen* gen) const { return false; } 491 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value") 492 }; 493 494 495 template<int I, int T> 496 class LControlInstruction: public LTemplateInstruction<0, I, T> { 497 public: 498 LControlInstruction() : false_label_(NULL), true_label_(NULL) { } 499 500 virtual bool IsControl() const { return true; } 501 502 int SuccessorCount() { return hydrogen()->SuccessorCount(); } 503 HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } 504 505 int TrueDestination(LChunk* chunk) { 506 return chunk->LookupDestination(true_block_id()); 507 } 508 int FalseDestination(LChunk* chunk) { 509 return chunk->LookupDestination(false_block_id()); 510 } 511 512 Label* TrueLabel(LChunk* chunk) { 513 if (true_label_ == NULL) { 514 true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk)); 515 } 516 return true_label_; 517 } 518 Label* FalseLabel(LChunk* chunk) { 519 if (false_label_ == NULL) { 520 false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk)); 521 } 522 return false_label_; 523 } 524 525 protected: 526 int true_block_id() { return SuccessorAt(0)->block_id(); } 527 int false_block_id() { return SuccessorAt(1)->block_id(); } 528 529 private: 530 HControlInstruction* hydrogen() { 531 return HControlInstruction::cast(this->hydrogen_value()); 532 } 533 534 Label* false_label_; 535 Label* true_label_; 536 }; 537 538 539 class LWrapReceiver: public LTemplateInstruction<1, 2, 0> { 540 public: 541 LWrapReceiver(LOperand* receiver, LOperand* function) { 542 inputs_[0] = receiver; 543 inputs_[1] = function; 544 } 545 546 LOperand* receiver() { return inputs_[0]; } 547 LOperand* function() { return inputs_[1]; } 548 549 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver") 550 }; 551 552 553 class LApplyArguments: public LTemplateInstruction<1, 4, 0> { 554 public: 555 LApplyArguments(LOperand* function, 556 LOperand* receiver, 557 LOperand* length, 558 LOperand* elements) { 559 inputs_[0] = function; 560 inputs_[1] = receiver; 561 inputs_[2] = length; 562 inputs_[3] = elements; 563 } 564 565 LOperand* function() { return inputs_[0]; } 566 LOperand* receiver() { return inputs_[1]; } 567 LOperand* length() { return inputs_[2]; } 568 LOperand* elements() { return inputs_[3]; } 569 570 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments") 571 }; 572 573 574 class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> { 575 public: 576 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) { 577 inputs_[0] = arguments; 578 inputs_[1] = length; 579 inputs_[2] = index; 580 } 581 582 LOperand* arguments() { return inputs_[0]; } 583 LOperand* length() { return inputs_[1]; } 584 LOperand* index() { return inputs_[2]; } 585 586 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at") 587 588 virtual void PrintDataTo(StringStream* stream); 589 }; 590 591 592 class LArgumentsLength: public LTemplateInstruction<1, 1, 0> { 593 public: 594 explicit LArgumentsLength(LOperand* elements) { 595 inputs_[0] = elements; 596 } 597 598 LOperand* elements() { return inputs_[0]; } 599 600 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length") 601 }; 602 603 604 class LArgumentsElements: public LTemplateInstruction<1, 0, 0> { 605 public: 606 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") 607 DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements) 608 }; 609 610 611 class LModI: public LTemplateInstruction<1, 2, 1> { 612 public: 613 LModI(LOperand* left, LOperand* right, LOperand* temp) { 614 inputs_[0] = left; 615 inputs_[1] = right; 616 temps_[0] = temp; 617 } 618 619 LOperand* left() { return inputs_[0]; } 620 LOperand* right() { return inputs_[1]; } 621 LOperand* temp() { return temps_[0]; } 622 623 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i") 624 DECLARE_HYDROGEN_ACCESSOR(Mod) 625 }; 626 627 628 class LDivI: public LTemplateInstruction<1, 2, 1> { 629 public: 630 LDivI(LOperand* left, LOperand* right, LOperand* temp) { 631 inputs_[0] = left; 632 inputs_[1] = right; 633 temps_[0] = temp; 634 } 635 636 LOperand* left() { return inputs_[0]; } 637 LOperand* right() { return inputs_[1]; } 638 LOperand* temp() { return temps_[0]; } 639 640 bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); } 641 642 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i") 643 DECLARE_HYDROGEN_ACCESSOR(Div) 644 }; 645 646 647 class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> { 648 public: 649 LMathFloorOfDiv(LOperand* left, 650 LOperand* right, 651 LOperand* temp = NULL) { 652 inputs_[0] = left; 653 inputs_[1] = right; 654 temps_[0] = temp; 655 } 656 657 LOperand* left() { return inputs_[0]; } 658 LOperand* right() { return inputs_[1]; } 659 LOperand* temp() { return temps_[0]; } 660 661 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div") 662 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) 663 }; 664 665 666 class LMulI: public LTemplateInstruction<1, 2, 0> { 667 public: 668 LMulI(LOperand* left, LOperand* right) { 669 inputs_[0] = left; 670 inputs_[1] = right; 671 } 672 673 LOperand* left() { return inputs_[0]; } 674 LOperand* right() { return inputs_[1]; } 675 676 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i") 677 DECLARE_HYDROGEN_ACCESSOR(Mul) 678 }; 679 680 681 class LCompareNumericAndBranch: public LControlInstruction<2, 0> { 682 public: 683 LCompareNumericAndBranch(LOperand* left, LOperand* right) { 684 inputs_[0] = left; 685 inputs_[1] = right; 686 } 687 688 LOperand* left() { return inputs_[0]; } 689 LOperand* right() { return inputs_[1]; } 690 691 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch, 692 "compare-numeric-and-branch") 693 DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch) 694 695 Token::Value op() const { return hydrogen()->token(); } 696 bool is_double() const { 697 return hydrogen()->representation().IsDouble(); 698 } 699 700 virtual void PrintDataTo(StringStream* stream); 701 }; 702 703 704 class LMathFloor: public LTemplateInstruction<1, 1, 0> { 705 public: 706 explicit LMathFloor(LOperand* value) { 707 inputs_[0] = value; 708 } 709 710 LOperand* value() { return inputs_[0]; } 711 712 DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor") 713 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 714 }; 715 716 717 class LMathRound: public LTemplateInstruction<1, 1, 0> { 718 public: 719 explicit LMathRound(LOperand* value) { 720 inputs_[0] = value; 721 } 722 723 LOperand* value() { return inputs_[0]; } 724 725 DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round") 726 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 727 }; 728 729 730 class LMathAbs: public LTemplateInstruction<1, 1, 0> { 731 public: 732 explicit LMathAbs(LOperand* value) { 733 inputs_[0] = value; 734 } 735 736 LOperand* value() { return inputs_[0]; } 737 738 DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs") 739 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 740 }; 741 742 743 class LMathLog: public LTemplateInstruction<1, 1, 0> { 744 public: 745 explicit LMathLog(LOperand* value) { 746 inputs_[0] = value; 747 } 748 749 LOperand* value() { return inputs_[0]; } 750 751 DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log") 752 }; 753 754 755 class LMathSin: public LTemplateInstruction<1, 1, 0> { 756 public: 757 explicit LMathSin(LOperand* value) { 758 inputs_[0] = value; 759 } 760 761 LOperand* value() { return inputs_[0]; } 762 763 DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin") 764 }; 765 766 767 class LMathCos: public LTemplateInstruction<1, 1, 0> { 768 public: 769 explicit LMathCos(LOperand* value) { 770 inputs_[0] = value; 771 } 772 773 LOperand* value() { return inputs_[0]; } 774 775 DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos") 776 }; 777 778 779 class LMathTan: public LTemplateInstruction<1, 1, 0> { 780 public: 781 explicit LMathTan(LOperand* value) { 782 inputs_[0] = value; 783 } 784 785 LOperand* value() { return inputs_[0]; } 786 787 DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan") 788 }; 789 790 791 class LMathExp: public LTemplateInstruction<1, 1, 2> { 792 public: 793 LMathExp(LOperand* value, LOperand* temp1, LOperand* temp2) { 794 inputs_[0] = value; 795 temps_[0] = temp1; 796 temps_[1] = temp2; 797 ExternalReference::InitializeMathExpData(); 798 } 799 800 LOperand* value() { return inputs_[0]; } 801 LOperand* temp1() { return temps_[0]; } 802 LOperand* temp2() { return temps_[1]; } 803 804 DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp") 805 }; 806 807 808 class LMathSqrt: public LTemplateInstruction<1, 1, 0> { 809 public: 810 explicit LMathSqrt(LOperand* value) { 811 inputs_[0] = value; 812 } 813 814 LOperand* value() { return inputs_[0]; } 815 816 DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt") 817 }; 818 819 820 class LMathPowHalf: public LTemplateInstruction<1, 1, 0> { 821 public: 822 explicit LMathPowHalf(LOperand* value) { 823 inputs_[0] = value; 824 } 825 826 LOperand* value() { return inputs_[0]; } 827 828 DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half") 829 }; 830 831 832 class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> { 833 public: 834 LCmpObjectEqAndBranch(LOperand* left, LOperand* right) { 835 inputs_[0] = left; 836 inputs_[1] = right; 837 } 838 839 LOperand* left() { return inputs_[0]; } 840 LOperand* right() { return inputs_[1]; } 841 842 DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch") 843 }; 844 845 846 class LCmpHoleAndBranch: public LControlInstruction<1, 0> { 847 public: 848 explicit LCmpHoleAndBranch(LOperand* object) { 849 inputs_[0] = object; 850 } 851 852 LOperand* object() { return inputs_[0]; } 853 854 DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch") 855 DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch) 856 }; 857 858 859 class LIsObjectAndBranch: public LControlInstruction<1, 0> { 860 public: 861 explicit LIsObjectAndBranch(LOperand* value) { 862 inputs_[0] = value; 863 } 864 865 LOperand* value() { return inputs_[0]; } 866 867 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch") 868 DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch) 869 870 virtual void PrintDataTo(StringStream* stream); 871 }; 872 873 874 class LIsNumberAndBranch: public LControlInstruction<1, 0> { 875 public: 876 explicit LIsNumberAndBranch(LOperand* value) { 877 inputs_[0] = value; 878 } 879 880 LOperand* value() { return inputs_[0]; } 881 882 DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch, "is-number-and-branch") 883 DECLARE_HYDROGEN_ACCESSOR(IsNumberAndBranch) 884 }; 885 886 887 class LIsStringAndBranch: public LControlInstruction<1, 1> { 888 public: 889 explicit LIsStringAndBranch(LOperand* value, LOperand* temp) { 890 inputs_[0] = value; 891 temps_[0] = temp; 892 } 893 894 LOperand* value() { return inputs_[0]; } 895 LOperand* temp() { return temps_[0]; } 896 897 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch") 898 DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch) 899 900 virtual void PrintDataTo(StringStream* stream); 901 }; 902 903 904 class LIsSmiAndBranch: public LControlInstruction<1, 0> { 905 public: 906 explicit LIsSmiAndBranch(LOperand* value) { 907 inputs_[0] = value; 908 } 909 910 LOperand* value() { return inputs_[0]; } 911 912 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch") 913 DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch) 914 915 virtual void PrintDataTo(StringStream* stream); 916 }; 917 918 919 class LIsUndetectableAndBranch: public LControlInstruction<1, 1> { 920 public: 921 explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) { 922 inputs_[0] = value; 923 temps_[0] = temp; 924 } 925 926 LOperand* value() { return inputs_[0]; } 927 LOperand* temp() { return temps_[0]; } 928 929 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch, 930 "is-undetectable-and-branch") 931 DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch) 932 933 virtual void PrintDataTo(StringStream* stream); 934 }; 935 936 937 class LStringCompareAndBranch: public LControlInstruction<2, 0> { 938 public: 939 explicit LStringCompareAndBranch(LOperand* left, LOperand* right) { 940 inputs_[0] = left; 941 inputs_[1] = right; 942 } 943 944 LOperand* left() { return inputs_[0]; } 945 LOperand* right() { return inputs_[1]; } 946 947 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch, 948 "string-compare-and-branch") 949 DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch) 950 951 virtual void PrintDataTo(StringStream* stream); 952 953 Token::Value op() const { return hydrogen()->token(); } 954 }; 955 956 957 class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> { 958 public: 959 explicit LHasInstanceTypeAndBranch(LOperand* value) { 960 inputs_[0] = value; 961 } 962 963 LOperand* value() { return inputs_[0]; } 964 965 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch, 966 "has-instance-type-and-branch") 967 DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch) 968 969 virtual void PrintDataTo(StringStream* stream); 970 }; 971 972 973 class LGetCachedArrayIndex: public LTemplateInstruction<1, 1, 0> { 974 public: 975 explicit LGetCachedArrayIndex(LOperand* value) { 976 inputs_[0] = value; 977 } 978 979 LOperand* value() { return inputs_[0]; } 980 981 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index") 982 DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex) 983 }; 984 985 986 class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> { 987 public: 988 explicit LHasCachedArrayIndexAndBranch(LOperand* value) { 989 inputs_[0] = value; 990 } 991 992 LOperand* value() { return inputs_[0]; } 993 994 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch, 995 "has-cached-array-index-and-branch") 996 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch) 997 998 virtual void PrintDataTo(StringStream* stream); 999 }; 1000 1001 1002 class LClassOfTestAndBranch: public LControlInstruction<1, 2> { 1003 public: 1004 LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) { 1005 inputs_[0] = value; 1006 temps_[0] = temp; 1007 temps_[1] = temp2; 1008 } 1009 1010 LOperand* value() { return inputs_[0]; } 1011 LOperand* temp() { return temps_[0]; } 1012 LOperand* temp2() { return temps_[1]; } 1013 1014 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, 1015 "class-of-test-and-branch") 1016 DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch) 1017 1018 virtual void PrintDataTo(StringStream* stream); 1019 }; 1020 1021 1022 class LCmpT: public LTemplateInstruction<1, 2, 0> { 1023 public: 1024 LCmpT(LOperand* left, LOperand* right) { 1025 inputs_[0] = left; 1026 inputs_[1] = right; 1027 } 1028 1029 LOperand* left() { return inputs_[0]; } 1030 LOperand* right() { return inputs_[1]; } 1031 1032 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t") 1033 DECLARE_HYDROGEN_ACCESSOR(CompareGeneric) 1034 1035 Token::Value op() const { return hydrogen()->token(); } 1036 }; 1037 1038 1039 class LInstanceOf: public LTemplateInstruction<1, 2, 0> { 1040 public: 1041 LInstanceOf(LOperand* left, LOperand* right) { 1042 inputs_[0] = left; 1043 inputs_[1] = right; 1044 } 1045 1046 LOperand* left() { return inputs_[0]; } 1047 LOperand* right() { return inputs_[1]; } 1048 1049 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of") 1050 }; 1051 1052 1053 class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> { 1054 public: 1055 LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) { 1056 inputs_[0] = value; 1057 temps_[0] = temp; 1058 } 1059 1060 LOperand* value() { return inputs_[0]; } 1061 LOperand* temp() { return temps_[0]; } 1062 1063 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal, 1064 "instance-of-known-global") 1065 DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal) 1066 1067 Handle<JSFunction> function() const { return hydrogen()->function(); } 1068 LEnvironment* GetDeferredLazyDeoptimizationEnvironment() { 1069 return lazy_deopt_env_; 1070 } 1071 virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { 1072 lazy_deopt_env_ = env; 1073 } 1074 1075 private: 1076 LEnvironment* lazy_deopt_env_; 1077 }; 1078 1079 1080 class LInstanceSize: public LTemplateInstruction<1, 1, 0> { 1081 public: 1082 explicit LInstanceSize(LOperand* object) { 1083 inputs_[0] = object; 1084 } 1085 1086 LOperand* object() { return inputs_[0]; } 1087 1088 DECLARE_CONCRETE_INSTRUCTION(InstanceSize, "instance-size") 1089 DECLARE_HYDROGEN_ACCESSOR(InstanceSize) 1090 }; 1091 1092 1093 class LBoundsCheck: public LTemplateInstruction<0, 2, 0> { 1094 public: 1095 LBoundsCheck(LOperand* index, LOperand* length) { 1096 inputs_[0] = index; 1097 inputs_[1] = length; 1098 } 1099 1100 LOperand* index() { return inputs_[0]; } 1101 LOperand* length() { return inputs_[1]; } 1102 1103 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") 1104 DECLARE_HYDROGEN_ACCESSOR(BoundsCheck) 1105 }; 1106 1107 1108 class LBitI: public LTemplateInstruction<1, 2, 0> { 1109 public: 1110 LBitI(LOperand* left, LOperand* right) { 1111 inputs_[0] = left; 1112 inputs_[1] = right; 1113 } 1114 1115 LOperand* left() { return inputs_[0]; } 1116 LOperand* right() { return inputs_[1]; } 1117 1118 Token::Value op() const { return hydrogen()->op(); } 1119 1120 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") 1121 DECLARE_HYDROGEN_ACCESSOR(Bitwise) 1122 }; 1123 1124 1125 class LShiftI: public LTemplateInstruction<1, 2, 0> { 1126 public: 1127 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) 1128 : op_(op), can_deopt_(can_deopt) { 1129 inputs_[0] = left; 1130 inputs_[1] = right; 1131 } 1132 1133 Token::Value op() const { return op_; } 1134 LOperand* left() { return inputs_[0]; } 1135 LOperand* right() { return inputs_[1]; } 1136 bool can_deopt() const { return can_deopt_; } 1137 1138 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") 1139 1140 private: 1141 Token::Value op_; 1142 bool can_deopt_; 1143 }; 1144 1145 1146 class LSubI: public LTemplateInstruction<1, 2, 0> { 1147 public: 1148 LSubI(LOperand* left, LOperand* right) { 1149 inputs_[0] = left; 1150 inputs_[1] = right; 1151 } 1152 1153 LOperand* left() { return inputs_[0]; } 1154 LOperand* right() { return inputs_[1]; } 1155 1156 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") 1157 DECLARE_HYDROGEN_ACCESSOR(Sub) 1158 }; 1159 1160 1161 class LConstantI: public LTemplateInstruction<1, 0, 0> { 1162 public: 1163 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i") 1164 DECLARE_HYDROGEN_ACCESSOR(Constant) 1165 1166 int32_t value() const { return hydrogen()->Integer32Value(); } 1167 }; 1168 1169 1170 class LConstantS: public LTemplateInstruction<1, 0, 0> { 1171 public: 1172 DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s") 1173 DECLARE_HYDROGEN_ACCESSOR(Constant) 1174 1175 Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); } 1176 }; 1177 1178 1179 class LConstantD: public LTemplateInstruction<1, 0, 1> { 1180 public: 1181 explicit LConstantD(LOperand* temp) { 1182 temps_[0] = temp; 1183 } 1184 1185 LOperand* temp() { return temps_[0]; } 1186 1187 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d") 1188 DECLARE_HYDROGEN_ACCESSOR(Constant) 1189 1190 double value() const { return hydrogen()->DoubleValue(); } 1191 }; 1192 1193 1194 class LConstantE: public LTemplateInstruction<1, 0, 0> { 1195 public: 1196 DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e") 1197 DECLARE_HYDROGEN_ACCESSOR(Constant) 1198 1199 ExternalReference value() const { 1200 return hydrogen()->ExternalReferenceValue(); 1201 } 1202 }; 1203 1204 1205 class LConstantT: public LTemplateInstruction<1, 0, 0> { 1206 public: 1207 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t") 1208 DECLARE_HYDROGEN_ACCESSOR(Constant) 1209 1210 Handle<Object> value() const { return hydrogen()->handle(); } 1211 }; 1212 1213 1214 class LBranch: public LControlInstruction<1, 0> { 1215 public: 1216 explicit LBranch(LOperand* value) { 1217 inputs_[0] = value; 1218 } 1219 1220 LOperand* value() { return inputs_[0]; } 1221 1222 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch") 1223 DECLARE_HYDROGEN_ACCESSOR(Branch) 1224 1225 virtual void PrintDataTo(StringStream* stream); 1226 }; 1227 1228 1229 class LDebugBreak: public LTemplateInstruction<0, 0, 0> { 1230 public: 1231 DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break") 1232 }; 1233 1234 1235 class LCmpMapAndBranch: public LControlInstruction<1, 0> { 1236 public: 1237 explicit LCmpMapAndBranch(LOperand* value) { 1238 inputs_[0] = value; 1239 } 1240 1241 LOperand* value() { return inputs_[0]; } 1242 1243 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") 1244 DECLARE_HYDROGEN_ACCESSOR(CompareMap) 1245 1246 Handle<Map> map() const { return hydrogen()->map(); } 1247 }; 1248 1249 1250 class LMapEnumLength: public LTemplateInstruction<1, 1, 0> { 1251 public: 1252 explicit LMapEnumLength(LOperand* value) { 1253 inputs_[0] = value; 1254 } 1255 1256 LOperand* value() { return inputs_[0]; } 1257 1258 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length") 1259 }; 1260 1261 1262 class LElementsKind: public LTemplateInstruction<1, 1, 0> { 1263 public: 1264 explicit LElementsKind(LOperand* value) { 1265 inputs_[0] = value; 1266 } 1267 1268 LOperand* value() { return inputs_[0]; } 1269 1270 DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind") 1271 DECLARE_HYDROGEN_ACCESSOR(ElementsKind) 1272 }; 1273 1274 1275 class LValueOf: public LTemplateInstruction<1, 1, 0> { 1276 public: 1277 explicit LValueOf(LOperand* value) { 1278 inputs_[0] = value; 1279 } 1280 1281 LOperand* value() { return inputs_[0]; } 1282 1283 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of") 1284 DECLARE_HYDROGEN_ACCESSOR(ValueOf) 1285 }; 1286 1287 1288 class LDateField: public LTemplateInstruction<1, 1, 0> { 1289 public: 1290 LDateField(LOperand* date, Smi* index) : index_(index) { 1291 inputs_[0] = date; 1292 } 1293 1294 LOperand* date() { return inputs_[0]; } 1295 Smi* index() const { return index_; } 1296 1297 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "date-field") 1298 DECLARE_HYDROGEN_ACCESSOR(ValueOf) 1299 1300 private: 1301 Smi* index_; 1302 }; 1303 1304 1305 class LSeqStringSetChar: public LTemplateInstruction<1, 3, 0> { 1306 public: 1307 LSeqStringSetChar(String::Encoding encoding, 1308 LOperand* string, 1309 LOperand* index, 1310 LOperand* value) : encoding_(encoding) { 1311 inputs_[0] = string; 1312 inputs_[1] = index; 1313 inputs_[2] = value; 1314 } 1315 1316 String::Encoding encoding() { return encoding_; } 1317 LOperand* string() { return inputs_[0]; } 1318 LOperand* index() { return inputs_[1]; } 1319 LOperand* value() { return inputs_[2]; } 1320 1321 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") 1322 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) 1323 1324 private: 1325 String::Encoding encoding_; 1326 }; 1327 1328 1329 class LThrow: public LTemplateInstruction<0, 1, 0> { 1330 public: 1331 explicit LThrow(LOperand* value) { 1332 inputs_[0] = value; 1333 } 1334 1335 LOperand* value() { return inputs_[0]; } 1336 1337 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw") 1338 }; 1339 1340 1341 class LAddI: public LTemplateInstruction<1, 2, 0> { 1342 public: 1343 LAddI(LOperand* left, LOperand* right) { 1344 inputs_[0] = left; 1345 inputs_[1] = right; 1346 } 1347 1348 LOperand* left() { return inputs_[0]; } 1349 LOperand* right() { return inputs_[1]; } 1350 1351 static bool UseLea(HAdd* add) { 1352 return !add->CheckFlag(HValue::kCanOverflow) && 1353 add->BetterLeftOperand()->UseCount() > 1; 1354 } 1355 1356 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") 1357 DECLARE_HYDROGEN_ACCESSOR(Add) 1358 }; 1359 1360 1361 class LMathMinMax: public LTemplateInstruction<1, 2, 0> { 1362 public: 1363 LMathMinMax(LOperand* left, LOperand* right) { 1364 inputs_[0] = left; 1365 inputs_[1] = right; 1366 } 1367 1368 LOperand* left() { return inputs_[0]; } 1369 LOperand* right() { return inputs_[1]; } 1370 1371 DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max") 1372 DECLARE_HYDROGEN_ACCESSOR(MathMinMax) 1373 }; 1374 1375 1376 class LPower: public LTemplateInstruction<1, 2, 0> { 1377 public: 1378 LPower(LOperand* left, LOperand* right) { 1379 inputs_[0] = left; 1380 inputs_[1] = right; 1381 } 1382 1383 LOperand* left() { return inputs_[0]; } 1384 LOperand* right() { return inputs_[1]; } 1385 1386 DECLARE_CONCRETE_INSTRUCTION(Power, "power") 1387 DECLARE_HYDROGEN_ACCESSOR(Power) 1388 }; 1389 1390 1391 class LRandom: public LTemplateInstruction<1, 1, 0> { 1392 public: 1393 explicit LRandom(LOperand* global_object) { 1394 inputs_[0] = global_object; 1395 } 1396 1397 LOperand* global_object() { return inputs_[0]; } 1398 1399 DECLARE_CONCRETE_INSTRUCTION(Random, "random") 1400 DECLARE_HYDROGEN_ACCESSOR(Random) 1401 }; 1402 1403 1404 class LArithmeticD: public LTemplateInstruction<1, 2, 0> { 1405 public: 1406 LArithmeticD(Token::Value op, LOperand* left, LOperand* right) 1407 : op_(op) { 1408 inputs_[0] = left; 1409 inputs_[1] = right; 1410 } 1411 1412 Token::Value op() const { return op_; } 1413 LOperand* left() { return inputs_[0]; } 1414 LOperand* right() { return inputs_[1]; } 1415 1416 virtual Opcode opcode() const { return LInstruction::kArithmeticD; } 1417 virtual void CompileToNative(LCodeGen* generator); 1418 virtual const char* Mnemonic() const; 1419 1420 private: 1421 Token::Value op_; 1422 }; 1423 1424 1425 class LArithmeticT: public LTemplateInstruction<1, 2, 0> { 1426 public: 1427 LArithmeticT(Token::Value op, LOperand* left, LOperand* right) 1428 : op_(op) { 1429 inputs_[0] = left; 1430 inputs_[1] = right; 1431 } 1432 1433 Token::Value op() const { return op_; } 1434 LOperand* left() { return inputs_[0]; } 1435 LOperand* right() { return inputs_[1]; } 1436 1437 virtual Opcode opcode() const { return LInstruction::kArithmeticT; } 1438 virtual void CompileToNative(LCodeGen* generator); 1439 virtual const char* Mnemonic() const; 1440 1441 private: 1442 Token::Value op_; 1443 }; 1444 1445 1446 class LReturn: public LTemplateInstruction<0, 2, 0> { 1447 public: 1448 explicit LReturn(LOperand* value, LOperand* parameter_count) { 1449 inputs_[0] = value; 1450 inputs_[1] = parameter_count; 1451 } 1452 1453 LOperand* value() { return inputs_[0]; } 1454 1455 bool has_constant_parameter_count() { 1456 return parameter_count()->IsConstantOperand(); 1457 } 1458 LConstantOperand* constant_parameter_count() { 1459 ASSERT(has_constant_parameter_count()); 1460 return LConstantOperand::cast(parameter_count()); 1461 } 1462 LOperand* parameter_count() { return inputs_[1]; } 1463 1464 DECLARE_CONCRETE_INSTRUCTION(Return, "return") 1465 DECLARE_HYDROGEN_ACCESSOR(Return) 1466 }; 1467 1468 1469 class LLoadNamedField: public LTemplateInstruction<1, 1, 0> { 1470 public: 1471 explicit LLoadNamedField(LOperand* object) { 1472 inputs_[0] = object; 1473 } 1474 1475 LOperand* object() { return inputs_[0]; } 1476 1477 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field") 1478 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField) 1479 }; 1480 1481 1482 class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> { 1483 public: 1484 explicit LLoadNamedGeneric(LOperand* object) { 1485 inputs_[0] = object; 1486 } 1487 1488 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic") 1489 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric) 1490 1491 LOperand* object() { return inputs_[0]; } 1492 Handle<Object> name() const { return hydrogen()->name(); } 1493 }; 1494 1495 1496 class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> { 1497 public: 1498 explicit LLoadFunctionPrototype(LOperand* function) { 1499 inputs_[0] = function; 1500 } 1501 1502 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype") 1503 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype) 1504 1505 LOperand* function() { return inputs_[0]; } 1506 }; 1507 1508 1509 class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> { 1510 public: 1511 explicit LLoadExternalArrayPointer(LOperand* object) { 1512 inputs_[0] = object; 1513 } 1514 1515 LOperand* object() { return inputs_[0]; } 1516 1517 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer, 1518 "load-external-array-pointer") 1519 }; 1520 1521 1522 class LLoadKeyed: public LTemplateInstruction<1, 2, 0> { 1523 public: 1524 LLoadKeyed(LOperand* elements, LOperand* key) { 1525 inputs_[0] = elements; 1526 inputs_[1] = key; 1527 } 1528 1529 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed") 1530 DECLARE_HYDROGEN_ACCESSOR(LoadKeyed) 1531 1532 bool is_external() const { 1533 return hydrogen()->is_external(); 1534 } 1535 LOperand* elements() { return inputs_[0]; } 1536 LOperand* key() { return inputs_[1]; } 1537 virtual void PrintDataTo(StringStream* stream); 1538 uint32_t additional_index() const { return hydrogen()->index_offset(); } 1539 ElementsKind elements_kind() const { 1540 return hydrogen()->elements_kind(); 1541 } 1542 }; 1543 1544 1545 class LLoadKeyedGeneric: public LTemplateInstruction<1, 2, 0> { 1546 public: 1547 LLoadKeyedGeneric(LOperand* obj, LOperand* key) { 1548 inputs_[0] = obj; 1549 inputs_[1] = key; 1550 } 1551 1552 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic") 1553 1554 LOperand* object() { return inputs_[0]; } 1555 LOperand* key() { return inputs_[1]; } 1556 }; 1557 1558 1559 class LLoadGlobalCell: public LTemplateInstruction<1, 0, 0> { 1560 public: 1561 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell") 1562 DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell) 1563 }; 1564 1565 1566 class LLoadGlobalGeneric: public LTemplateInstruction<1, 1, 0> { 1567 public: 1568 explicit LLoadGlobalGeneric(LOperand* global_object) { 1569 inputs_[0] = global_object; 1570 } 1571 1572 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic") 1573 DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric) 1574 1575 LOperand* global_object() { return inputs_[0]; } 1576 Handle<Object> name() const { return hydrogen()->name(); } 1577 bool for_typeof() const { return hydrogen()->for_typeof(); } 1578 }; 1579 1580 1581 class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> { 1582 public: 1583 explicit LStoreGlobalCell(LOperand* value, LOperand* temp) { 1584 inputs_[0] = value; 1585 temps_[0] = temp; 1586 } 1587 1588 LOperand* value() { return inputs_[0]; } 1589 LOperand* temp() { return temps_[0]; } 1590 1591 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell") 1592 DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell) 1593 }; 1594 1595 1596 class LStoreGlobalGeneric: public LTemplateInstruction<0, 2, 0> { 1597 public: 1598 explicit LStoreGlobalGeneric(LOperand* global_object, 1599 LOperand* value) { 1600 inputs_[0] = global_object; 1601 inputs_[1] = value; 1602 } 1603 1604 LOperand* global_object() { return inputs_[0]; } 1605 LOperand* value() { return inputs_[1]; } 1606 1607 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic") 1608 DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric) 1609 1610 Handle<Object> name() const { return hydrogen()->name(); } 1611 StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } 1612 }; 1613 1614 1615 class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> { 1616 public: 1617 explicit LLoadContextSlot(LOperand* context) { 1618 inputs_[0] = context; 1619 } 1620 1621 LOperand* context() { return inputs_[0]; } 1622 1623 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot") 1624 DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot) 1625 1626 int slot_index() { return hydrogen()->slot_index(); } 1627 1628 virtual void PrintDataTo(StringStream* stream); 1629 }; 1630 1631 1632 class LStoreContextSlot: public LTemplateInstruction<0, 2, 1> { 1633 public: 1634 LStoreContextSlot(LOperand* context, LOperand* value, LOperand* temp) { 1635 inputs_[0] = context; 1636 inputs_[1] = value; 1637 temps_[0] = temp; 1638 } 1639 1640 LOperand* context() { return inputs_[0]; } 1641 LOperand* value() { return inputs_[1]; } 1642 LOperand* temp() { return temps_[0]; } 1643 1644 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot") 1645 DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot) 1646 1647 int slot_index() { return hydrogen()->slot_index(); } 1648 1649 virtual void PrintDataTo(StringStream* stream); 1650 }; 1651 1652 1653 class LPushArgument: public LTemplateInstruction<0, 1, 0> { 1654 public: 1655 explicit LPushArgument(LOperand* value) { 1656 inputs_[0] = value; 1657 } 1658 1659 LOperand* value() { return inputs_[0]; } 1660 1661 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument") 1662 }; 1663 1664 1665 class LDrop: public LTemplateInstruction<0, 0, 0> { 1666 public: 1667 explicit LDrop(int count) : count_(count) { } 1668 1669 int count() const { return count_; } 1670 1671 DECLARE_CONCRETE_INSTRUCTION(Drop, "drop") 1672 1673 private: 1674 int count_; 1675 }; 1676 1677 1678 class LInnerAllocatedObject: public LTemplateInstruction<1, 1, 0> { 1679 public: 1680 explicit LInnerAllocatedObject(LOperand* base_object) { 1681 inputs_[0] = base_object; 1682 } 1683 1684 LOperand* base_object() { return inputs_[0]; } 1685 int offset() { return hydrogen()->offset(); } 1686 1687 virtual void PrintDataTo(StringStream* stream); 1688 1689 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object") 1690 DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject) 1691 }; 1692 1693 1694 class LThisFunction: public LTemplateInstruction<1, 0, 0> { 1695 public: 1696 DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") 1697 DECLARE_HYDROGEN_ACCESSOR(ThisFunction) 1698 }; 1699 1700 1701 class LContext: public LTemplateInstruction<1, 0, 0> { 1702 public: 1703 DECLARE_CONCRETE_INSTRUCTION(Context, "context") 1704 DECLARE_HYDROGEN_ACCESSOR(Context) 1705 }; 1706 1707 1708 class LOuterContext: public LTemplateInstruction<1, 1, 0> { 1709 public: 1710 explicit LOuterContext(LOperand* context) { 1711 inputs_[0] = context; 1712 } 1713 1714 LOperand* context() { return inputs_[0]; } 1715 1716 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context") 1717 }; 1718 1719 1720 class LDeclareGlobals: public LTemplateInstruction<0, 0, 0> { 1721 public: 1722 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals") 1723 DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals) 1724 }; 1725 1726 1727 class LGlobalObject: public LTemplateInstruction<1, 0, 0> { 1728 public: 1729 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") 1730 }; 1731 1732 1733 class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> { 1734 public: 1735 explicit LGlobalReceiver(LOperand* global_object) { 1736 inputs_[0] = global_object; 1737 } 1738 1739 LOperand* global() { return inputs_[0]; } 1740 1741 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver") 1742 }; 1743 1744 1745 class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> { 1746 public: 1747 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function") 1748 DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction) 1749 1750 virtual void PrintDataTo(StringStream* stream); 1751 1752 Handle<JSFunction> function() { return hydrogen()->function(); } 1753 int arity() const { return hydrogen()->argument_count() - 1; } 1754 }; 1755 1756 1757 class LInvokeFunction: public LTemplateInstruction<1, 1, 0> { 1758 public: 1759 explicit LInvokeFunction(LOperand* function) { 1760 inputs_[0] = function; 1761 } 1762 1763 LOperand* function() { return inputs_[0]; } 1764 1765 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") 1766 DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) 1767 1768 virtual void PrintDataTo(StringStream* stream); 1769 1770 int arity() const { return hydrogen()->argument_count() - 1; } 1771 }; 1772 1773 1774 class LCallKeyed: public LTemplateInstruction<1, 1, 0> { 1775 public: 1776 explicit LCallKeyed(LOperand* key) { 1777 inputs_[0] = key; 1778 } 1779 1780 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed") 1781 DECLARE_HYDROGEN_ACCESSOR(CallKeyed) 1782 1783 LOperand* key() { return inputs_[0]; } 1784 1785 virtual void PrintDataTo(StringStream* stream); 1786 1787 int arity() const { return hydrogen()->argument_count() - 1; } 1788 }; 1789 1790 1791 class LCallNamed: public LTemplateInstruction<1, 0, 0> { 1792 public: 1793 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named") 1794 DECLARE_HYDROGEN_ACCESSOR(CallNamed) 1795 1796 virtual void PrintDataTo(StringStream* stream); 1797 1798 Handle<String> name() const { return hydrogen()->name(); } 1799 int arity() const { return hydrogen()->argument_count() - 1; } 1800 }; 1801 1802 1803 class LCallFunction: public LTemplateInstruction<1, 1, 0> { 1804 public: 1805 explicit LCallFunction(LOperand* function) { 1806 inputs_[0] = function; 1807 } 1808 1809 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function") 1810 DECLARE_HYDROGEN_ACCESSOR(CallFunction) 1811 1812 LOperand* function() { return inputs_[0]; } 1813 int arity() const { return hydrogen()->argument_count() - 1; } 1814 }; 1815 1816 1817 class LCallGlobal: public LTemplateInstruction<1, 0, 0> { 1818 public: 1819 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global") 1820 DECLARE_HYDROGEN_ACCESSOR(CallGlobal) 1821 1822 virtual void PrintDataTo(StringStream* stream); 1823 1824 Handle<String> name() const {return hydrogen()->name(); } 1825 int arity() const { return hydrogen()->argument_count() - 1; } 1826 }; 1827 1828 1829 class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> { 1830 public: 1831 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global") 1832 DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal) 1833 1834 virtual void PrintDataTo(StringStream* stream); 1835 1836 int arity() const { return hydrogen()->argument_count() - 1; } 1837 }; 1838 1839 1840 class LCallNew: public LTemplateInstruction<1, 1, 0> { 1841 public: 1842 explicit LCallNew(LOperand* constructor) { 1843 inputs_[0] = constructor; 1844 } 1845 1846 LOperand* constructor() { return inputs_[0]; } 1847 1848 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new") 1849 DECLARE_HYDROGEN_ACCESSOR(CallNew) 1850 1851 virtual void PrintDataTo(StringStream* stream); 1852 1853 int arity() const { return hydrogen()->argument_count() - 1; } 1854 }; 1855 1856 1857 class LCallNewArray: public LTemplateInstruction<1, 1, 0> { 1858 public: 1859 explicit LCallNewArray(LOperand* constructor) { 1860 inputs_[0] = constructor; 1861 } 1862 1863 LOperand* constructor() { return inputs_[0]; } 1864 1865 DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array") 1866 DECLARE_HYDROGEN_ACCESSOR(CallNewArray) 1867 1868 virtual void PrintDataTo(StringStream* stream); 1869 1870 int arity() const { return hydrogen()->argument_count() - 1; } 1871 }; 1872 1873 1874 class LCallRuntime: public LTemplateInstruction<1, 0, 0> { 1875 public: 1876 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime") 1877 DECLARE_HYDROGEN_ACCESSOR(CallRuntime) 1878 1879 const Runtime::Function* function() const { return hydrogen()->function(); } 1880 int arity() const { return hydrogen()->argument_count(); } 1881 }; 1882 1883 1884 class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> { 1885 public: 1886 explicit LInteger32ToDouble(LOperand* value) { 1887 inputs_[0] = value; 1888 } 1889 1890 LOperand* value() { return inputs_[0]; } 1891 1892 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double") 1893 }; 1894 1895 1896 class LInteger32ToSmi: public LTemplateInstruction<1, 1, 0> { 1897 public: 1898 explicit LInteger32ToSmi(LOperand* value) { 1899 inputs_[0] = value; 1900 } 1901 1902 LOperand* value() { return inputs_[0]; } 1903 1904 DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi") 1905 DECLARE_HYDROGEN_ACCESSOR(Change) 1906 }; 1907 1908 1909 class LUint32ToDouble: public LTemplateInstruction<1, 1, 1> { 1910 public: 1911 explicit LUint32ToDouble(LOperand* value, LOperand* temp) { 1912 inputs_[0] = value; 1913 temps_[0] = temp; 1914 } 1915 1916 LOperand* value() { return inputs_[0]; } 1917 LOperand* temp() { return temps_[0]; } 1918 1919 DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double") 1920 }; 1921 1922 1923 class LUint32ToSmi: public LTemplateInstruction<1, 1, 0> { 1924 public: 1925 explicit LUint32ToSmi(LOperand* value) { 1926 inputs_[0] = value; 1927 } 1928 1929 LOperand* value() { return inputs_[0]; } 1930 1931 DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi") 1932 DECLARE_HYDROGEN_ACCESSOR(Change) 1933 }; 1934 1935 1936 class LNumberTagI: public LTemplateInstruction<1, 1, 0> { 1937 public: 1938 explicit LNumberTagI(LOperand* value) { 1939 inputs_[0] = value; 1940 } 1941 1942 LOperand* value() { return inputs_[0]; } 1943 1944 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") 1945 }; 1946 1947 1948 class LNumberTagU: public LTemplateInstruction<1, 1, 1> { 1949 public: 1950 explicit LNumberTagU(LOperand* value, LOperand* temp) { 1951 inputs_[0] = value; 1952 temps_[0] = temp; 1953 } 1954 1955 LOperand* value() { return inputs_[0]; } 1956 LOperand* temp() { return temps_[0]; } 1957 1958 DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u") 1959 }; 1960 1961 1962 class LNumberTagD: public LTemplateInstruction<1, 1, 1> { 1963 public: 1964 explicit LNumberTagD(LOperand* value, LOperand* temp) { 1965 inputs_[0] = value; 1966 temps_[0] = temp; 1967 } 1968 1969 LOperand* value() { return inputs_[0]; } 1970 LOperand* temp() { return temps_[0]; } 1971 1972 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d") 1973 DECLARE_HYDROGEN_ACCESSOR(Change) 1974 }; 1975 1976 1977 // Sometimes truncating conversion from a tagged value to an int32. 1978 class LDoubleToI: public LTemplateInstruction<1, 1, 0> { 1979 public: 1980 explicit LDoubleToI(LOperand* value) { 1981 inputs_[0] = value; 1982 } 1983 1984 LOperand* value() { return inputs_[0]; } 1985 1986 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i") 1987 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 1988 1989 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1990 }; 1991 1992 1993 class LDoubleToSmi: public LTemplateInstruction<1, 1, 0> { 1994 public: 1995 explicit LDoubleToSmi(LOperand* value) { 1996 inputs_[0] = value; 1997 } 1998 1999 LOperand* value() { return inputs_[0]; } 2000 2001 DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi") 2002 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 2003 }; 2004 2005 2006 // Truncating conversion from a tagged value to an int32. 2007 class LTaggedToI: public LTemplateInstruction<1, 1, 1> { 2008 public: 2009 LTaggedToI(LOperand* value, LOperand* temp) { 2010 inputs_[0] = value; 2011 temps_[0] = temp; 2012 } 2013 2014 LOperand* value() { return inputs_[0]; } 2015 LOperand* temp() { return temps_[0]; } 2016 2017 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i") 2018 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 2019 2020 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 2021 }; 2022 2023 2024 class LSmiTag: public LTemplateInstruction<1, 1, 0> { 2025 public: 2026 explicit LSmiTag(LOperand* value) { 2027 inputs_[0] = value; 2028 } 2029 2030 LOperand* value() { return inputs_[0]; } 2031 2032 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag") 2033 }; 2034 2035 2036 class LNumberUntagD: public LTemplateInstruction<1, 1, 0> { 2037 public: 2038 explicit LNumberUntagD(LOperand* value) { 2039 inputs_[0] = value; 2040 } 2041 2042 LOperand* value() { return inputs_[0]; } 2043 2044 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") 2045 DECLARE_HYDROGEN_ACCESSOR(Change); 2046 }; 2047 2048 2049 class LSmiUntag: public LTemplateInstruction<1, 1, 0> { 2050 public: 2051 LSmiUntag(LOperand* value, bool needs_check) 2052 : needs_check_(needs_check) { 2053 inputs_[0] = value; 2054 } 2055 2056 LOperand* value() { return inputs_[0]; } 2057 bool needs_check() const { return needs_check_; } 2058 2059 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") 2060 2061 private: 2062 bool needs_check_; 2063 }; 2064 2065 2066 class LStoreNamedField: public LTemplateInstruction<0, 2, 1> { 2067 public: 2068 LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) { 2069 inputs_[0] = object; 2070 inputs_[1] = value; 2071 temps_[0] = temp; 2072 } 2073 2074 LOperand* object() { return inputs_[0]; } 2075 LOperand* value() { return inputs_[1]; } 2076 LOperand* temp() { return temps_[0]; } 2077 2078 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field") 2079 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField) 2080 2081 virtual void PrintDataTo(StringStream* stream); 2082 2083 Handle<Map> transition() const { return hydrogen()->transition_map(); } 2084 Representation representation() const { 2085 return hydrogen()->field_representation(); 2086 } 2087 }; 2088 2089 2090 class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> { 2091 public: 2092 LStoreNamedGeneric(LOperand* object, LOperand* value) { 2093 inputs_[0] = object; 2094 inputs_[1] = value; 2095 } 2096 2097 LOperand* object() { return inputs_[0]; } 2098 LOperand* value() { return inputs_[1]; } 2099 2100 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic") 2101 DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric) 2102 2103 virtual void PrintDataTo(StringStream* stream); 2104 2105 Handle<Object> name() const { return hydrogen()->name(); } 2106 StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } 2107 }; 2108 2109 2110 class LStoreKeyed: public LTemplateInstruction<0, 3, 0> { 2111 public: 2112 LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) { 2113 inputs_[0] = object; 2114 inputs_[1] = key; 2115 inputs_[2] = value; 2116 } 2117 2118 bool is_external() const { return hydrogen()->is_external(); } 2119 LOperand* elements() { return inputs_[0]; } 2120 LOperand* key() { return inputs_[1]; } 2121 LOperand* value() { return inputs_[2]; } 2122 ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } 2123 2124 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed") 2125 DECLARE_HYDROGEN_ACCESSOR(StoreKeyed) 2126 2127 virtual void PrintDataTo(StringStream* stream); 2128 bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } 2129 uint32_t additional_index() const { return hydrogen()->index_offset(); } 2130 }; 2131 2132 2133 class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> { 2134 public: 2135 LStoreKeyedGeneric(LOperand* object, LOperand* key, LOperand* value) { 2136 inputs_[0] = object; 2137 inputs_[1] = key; 2138 inputs_[2] = value; 2139 } 2140 2141 LOperand* object() { return inputs_[0]; } 2142 LOperand* key() { return inputs_[1]; } 2143 LOperand* value() { return inputs_[2]; } 2144 2145 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic") 2146 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric) 2147 2148 virtual void PrintDataTo(StringStream* stream); 2149 2150 StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } 2151 }; 2152 2153 2154 class LTransitionElementsKind: public LTemplateInstruction<0, 1, 2> { 2155 public: 2156 LTransitionElementsKind(LOperand* object, 2157 LOperand* new_map_temp, 2158 LOperand* temp) { 2159 inputs_[0] = object; 2160 temps_[0] = new_map_temp; 2161 temps_[1] = temp; 2162 } 2163 2164 LOperand* object() { return inputs_[0]; } 2165 LOperand* new_map_temp() { return temps_[0]; } 2166 LOperand* temp() { return temps_[1]; } 2167 2168 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind, 2169 "transition-elements-kind") 2170 DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind) 2171 2172 virtual void PrintDataTo(StringStream* stream); 2173 2174 Handle<Map> original_map() { return hydrogen()->original_map(); } 2175 Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); } 2176 ElementsKind from_kind() { return hydrogen()->from_kind(); } 2177 ElementsKind to_kind() { return hydrogen()->to_kind(); } 2178 }; 2179 2180 2181 class LTrapAllocationMemento : public LTemplateInstruction<0, 1, 1> { 2182 public: 2183 LTrapAllocationMemento(LOperand* object, 2184 LOperand* temp) { 2185 inputs_[0] = object; 2186 temps_[0] = temp; 2187 } 2188 2189 LOperand* object() { return inputs_[0]; } 2190 LOperand* temp() { return temps_[0]; } 2191 2192 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento, 2193 "trap-allocation-memento") 2194 }; 2195 2196 2197 class LStringAdd: public LTemplateInstruction<1, 2, 0> { 2198 public: 2199 LStringAdd(LOperand* left, LOperand* right) { 2200 inputs_[0] = left; 2201 inputs_[1] = right; 2202 } 2203 2204 LOperand* left() { return inputs_[0]; } 2205 LOperand* right() { return inputs_[1]; } 2206 2207 DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add") 2208 DECLARE_HYDROGEN_ACCESSOR(StringAdd) 2209 }; 2210 2211 2212 class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> { 2213 public: 2214 LStringCharCodeAt(LOperand* string, LOperand* index) { 2215 inputs_[0] = string; 2216 inputs_[1] = index; 2217 } 2218 2219 LOperand* string() { return inputs_[0]; } 2220 LOperand* index() { return inputs_[1]; } 2221 2222 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at") 2223 DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt) 2224 }; 2225 2226 2227 class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> { 2228 public: 2229 explicit LStringCharFromCode(LOperand* char_code) { 2230 inputs_[0] = char_code; 2231 } 2232 2233 LOperand* char_code() { return inputs_[0]; } 2234 2235 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code") 2236 DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode) 2237 }; 2238 2239 2240 class LCheckFunction: public LTemplateInstruction<0, 1, 0> { 2241 public: 2242 explicit LCheckFunction(LOperand* value) { 2243 inputs_[0] = value; 2244 } 2245 2246 LOperand* value() { return inputs_[0]; } 2247 2248 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function") 2249 DECLARE_HYDROGEN_ACCESSOR(CheckFunction) 2250 }; 2251 2252 2253 class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> { 2254 public: 2255 explicit LCheckInstanceType(LOperand* value) { 2256 inputs_[0] = value; 2257 } 2258 2259 LOperand* value() { return inputs_[0]; } 2260 2261 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type") 2262 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType) 2263 }; 2264 2265 2266 class LCheckMaps: public LTemplateInstruction<0, 1, 0> { 2267 public: 2268 explicit LCheckMaps(LOperand* value) { 2269 inputs_[0] = value; 2270 } 2271 2272 LOperand* value() { return inputs_[0]; } 2273 2274 DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps") 2275 DECLARE_HYDROGEN_ACCESSOR(CheckMaps) 2276 }; 2277 2278 2279 class LCheckSmi: public LTemplateInstruction<1, 1, 0> { 2280 public: 2281 explicit LCheckSmi(LOperand* value) { 2282 inputs_[0] = value; 2283 } 2284 2285 LOperand* value() { return inputs_[0]; } 2286 2287 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi") 2288 }; 2289 2290 2291 class LClampDToUint8: public LTemplateInstruction<1, 1, 0> { 2292 public: 2293 explicit LClampDToUint8(LOperand* unclamped) { 2294 inputs_[0] = unclamped; 2295 } 2296 2297 LOperand* unclamped() { return inputs_[0]; } 2298 2299 DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8") 2300 }; 2301 2302 2303 class LClampIToUint8: public LTemplateInstruction<1, 1, 0> { 2304 public: 2305 explicit LClampIToUint8(LOperand* unclamped) { 2306 inputs_[0] = unclamped; 2307 } 2308 2309 LOperand* unclamped() { return inputs_[0]; } 2310 2311 DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8") 2312 }; 2313 2314 2315 class LClampTToUint8: public LTemplateInstruction<1, 1, 1> { 2316 public: 2317 LClampTToUint8(LOperand* unclamped, 2318 LOperand* temp_xmm) { 2319 inputs_[0] = unclamped; 2320 temps_[0] = temp_xmm; 2321 } 2322 2323 LOperand* unclamped() { return inputs_[0]; } 2324 LOperand* temp_xmm() { return temps_[0]; } 2325 2326 DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8") 2327 }; 2328 2329 2330 class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> { 2331 public: 2332 explicit LCheckNonSmi(LOperand* value) { 2333 inputs_[0] = value; 2334 } 2335 2336 LOperand* value() { return inputs_[0]; } 2337 2338 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi") 2339 DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject) 2340 }; 2341 2342 2343 class LAllocate: public LTemplateInstruction<1, 1, 1> { 2344 public: 2345 LAllocate(LOperand* size, LOperand* temp) { 2346 inputs_[0] = size; 2347 temps_[0] = temp; 2348 } 2349 2350 LOperand* size() { return inputs_[0]; } 2351 LOperand* temp() { return temps_[0]; } 2352 2353 DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate") 2354 DECLARE_HYDROGEN_ACCESSOR(Allocate) 2355 }; 2356 2357 2358 class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> { 2359 public: 2360 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal") 2361 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral) 2362 }; 2363 2364 2365 class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> { 2366 public: 2367 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal") 2368 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral) 2369 }; 2370 2371 2372 class LToFastProperties: public LTemplateInstruction<1, 1, 0> { 2373 public: 2374 explicit LToFastProperties(LOperand* value) { 2375 inputs_[0] = value; 2376 } 2377 2378 LOperand* value() { return inputs_[0]; } 2379 2380 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties") 2381 DECLARE_HYDROGEN_ACCESSOR(ToFastProperties) 2382 }; 2383 2384 2385 class LTypeof: public LTemplateInstruction<1, 1, 0> { 2386 public: 2387 explicit LTypeof(LOperand* value) { 2388 inputs_[0] = value; 2389 } 2390 2391 LOperand* value() { return inputs_[0]; } 2392 2393 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof") 2394 }; 2395 2396 2397 class LTypeofIsAndBranch: public LControlInstruction<1, 0> { 2398 public: 2399 explicit LTypeofIsAndBranch(LOperand* value) { 2400 inputs_[0] = value; 2401 } 2402 2403 LOperand* value() { return inputs_[0]; } 2404 2405 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch") 2406 DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch) 2407 2408 Handle<String> type_literal() { return hydrogen()->type_literal(); } 2409 2410 virtual void PrintDataTo(StringStream* stream); 2411 }; 2412 2413 2414 class LIsConstructCallAndBranch: public LControlInstruction<0, 1> { 2415 public: 2416 explicit LIsConstructCallAndBranch(LOperand* temp) { 2417 temps_[0] = temp; 2418 } 2419 2420 LOperand* temp() { return temps_[0]; } 2421 2422 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch, 2423 "is-construct-call-and-branch") 2424 DECLARE_HYDROGEN_ACCESSOR(IsConstructCallAndBranch) 2425 }; 2426 2427 2428 class LOsrEntry: public LTemplateInstruction<0, 0, 0> { 2429 public: 2430 LOsrEntry() {} 2431 2432 virtual bool HasInterestingComment(LCodeGen* gen) const { return false; } 2433 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") 2434 }; 2435 2436 2437 class LStackCheck: public LTemplateInstruction<0, 0, 0> { 2438 public: 2439 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check") 2440 DECLARE_HYDROGEN_ACCESSOR(StackCheck) 2441 2442 Label* done_label() { return &done_label_; } 2443 2444 private: 2445 Label done_label_; 2446 }; 2447 2448 2449 class LForInPrepareMap: public LTemplateInstruction<1, 1, 0> { 2450 public: 2451 explicit LForInPrepareMap(LOperand* object) { 2452 inputs_[0] = object; 2453 } 2454 2455 LOperand* object() { return inputs_[0]; } 2456 2457 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map") 2458 }; 2459 2460 2461 class LForInCacheArray: public LTemplateInstruction<1, 1, 0> { 2462 public: 2463 explicit LForInCacheArray(LOperand* map) { 2464 inputs_[0] = map; 2465 } 2466 2467 LOperand* map() { return inputs_[0]; } 2468 2469 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array") 2470 2471 int idx() { 2472 return HForInCacheArray::cast(this->hydrogen_value())->idx(); 2473 } 2474 }; 2475 2476 2477 class LCheckMapValue: public LTemplateInstruction<0, 2, 0> { 2478 public: 2479 LCheckMapValue(LOperand* value, LOperand* map) { 2480 inputs_[0] = value; 2481 inputs_[1] = map; 2482 } 2483 2484 LOperand* value() { return inputs_[0]; } 2485 LOperand* map() { return inputs_[1]; } 2486 2487 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value") 2488 }; 2489 2490 2491 class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> { 2492 public: 2493 LLoadFieldByIndex(LOperand* object, LOperand* index) { 2494 inputs_[0] = object; 2495 inputs_[1] = index; 2496 } 2497 2498 LOperand* object() { return inputs_[0]; } 2499 LOperand* index() { return inputs_[1]; } 2500 2501 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index") 2502 }; 2503 2504 2505 class LChunkBuilder; 2506 class LPlatformChunk: public LChunk { 2507 public: 2508 LPlatformChunk(CompilationInfo* info, HGraph* graph) 2509 : LChunk(info, graph) { } 2510 2511 int GetNextSpillIndex(bool is_double); 2512 LOperand* GetNextSpillSlot(bool is_double); 2513 }; 2514 2515 2516 class LChunkBuilder BASE_EMBEDDED { 2517 public: 2518 LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator) 2519 : chunk_(NULL), 2520 info_(info), 2521 graph_(graph), 2522 zone_(graph->zone()), 2523 status_(UNUSED), 2524 current_instruction_(NULL), 2525 current_block_(NULL), 2526 next_block_(NULL), 2527 argument_count_(0), 2528 allocator_(allocator), 2529 position_(RelocInfo::kNoPosition), 2530 instruction_pending_deoptimization_environment_(NULL), 2531 pending_deoptimization_ast_id_(BailoutId::None()) { } 2532 2533 // Build the sequence for the graph. 2534 LPlatformChunk* Build(); 2535 2536 // Declare methods that deal with the individual node types. 2537 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node); 2538 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 2539 #undef DECLARE_DO 2540 2541 static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val); 2542 2543 LInstruction* DoMathFloor(HUnaryMathOperation* instr); 2544 LInstruction* DoMathRound(HUnaryMathOperation* instr); 2545 LInstruction* DoMathAbs(HUnaryMathOperation* instr); 2546 LInstruction* DoMathLog(HUnaryMathOperation* instr); 2547 LInstruction* DoMathSin(HUnaryMathOperation* instr); 2548 LInstruction* DoMathCos(HUnaryMathOperation* instr); 2549 LInstruction* DoMathTan(HUnaryMathOperation* instr); 2550 LInstruction* DoMathExp(HUnaryMathOperation* instr); 2551 LInstruction* DoMathSqrt(HUnaryMathOperation* instr); 2552 LInstruction* DoMathPowHalf(HUnaryMathOperation* instr); 2553 2554 private: 2555 enum Status { 2556 UNUSED, 2557 BUILDING, 2558 DONE, 2559 ABORTED 2560 }; 2561 2562 LPlatformChunk* chunk() const { return chunk_; } 2563 CompilationInfo* info() const { return info_; } 2564 HGraph* graph() const { return graph_; } 2565 Zone* zone() const { return zone_; } 2566 2567 bool is_unused() const { return status_ == UNUSED; } 2568 bool is_building() const { return status_ == BUILDING; } 2569 bool is_done() const { return status_ == DONE; } 2570 bool is_aborted() const { return status_ == ABORTED; } 2571 2572 void Abort(BailoutReason reason); 2573 2574 // Methods for getting operands for Use / Define / Temp. 2575 LUnallocated* ToUnallocated(Register reg); 2576 LUnallocated* ToUnallocated(XMMRegister reg); 2577 2578 // Methods for setting up define-use relationships. 2579 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); 2580 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register); 2581 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value, 2582 XMMRegister fixed_register); 2583 2584 // A value that is guaranteed to be allocated to a register. 2585 // Operand created by UseRegister is guaranteed to be live until the end of 2586 // instruction. This means that register allocator will not reuse it's 2587 // register for any other operand inside instruction. 2588 // Operand created by UseRegisterAtStart is guaranteed to be live only at 2589 // instruction start. Register allocator is free to assign the same register 2590 // to some other operand used inside instruction (i.e. temporary or 2591 // output). 2592 MUST_USE_RESULT LOperand* UseRegister(HValue* value); 2593 MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value); 2594 2595 // An input operand in a register that may be trashed. 2596 MUST_USE_RESULT LOperand* UseTempRegister(HValue* value); 2597 2598 // An input operand in a register or stack slot. 2599 MUST_USE_RESULT LOperand* Use(HValue* value); 2600 MUST_USE_RESULT LOperand* UseAtStart(HValue* value); 2601 2602 // An input operand in a register, stack slot or a constant operand. 2603 MUST_USE_RESULT LOperand* UseOrConstant(HValue* value); 2604 MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value); 2605 2606 // An input operand in a register or a constant operand. 2607 MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value); 2608 MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value); 2609 2610 // An input operand in a constant operand. 2611 MUST_USE_RESULT LOperand* UseConstant(HValue* value); 2612 2613 // An input operand in register, stack slot or a constant operand. 2614 // Will not be moved to a register even if one is freely available. 2615 MUST_USE_RESULT LOperand* UseAny(HValue* value); 2616 2617 // Temporary operand that must be in a register. 2618 MUST_USE_RESULT LUnallocated* TempRegister(); 2619 MUST_USE_RESULT LOperand* FixedTemp(Register reg); 2620 MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg); 2621 2622 // Methods for setting up define-use relationships. 2623 // Return the same instruction that they are passed. 2624 template<int I, int T> 2625 LInstruction* Define(LTemplateInstruction<1, I, T>* instr, 2626 LUnallocated* result); 2627 template<int I, int T> 2628 LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr); 2629 template<int I, int T> 2630 LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr, 2631 int index); 2632 template<int I, int T> 2633 LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr); 2634 template<int I, int T> 2635 LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr, 2636 Register reg); 2637 template<int I, int T> 2638 LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr, 2639 XMMRegister reg); 2640 // Assigns an environment to an instruction. An instruction which can 2641 // deoptimize must have an environment. 2642 LInstruction* AssignEnvironment(LInstruction* instr); 2643 // Assigns a pointer map to an instruction. An instruction which can 2644 // trigger a GC or a lazy deoptimization must have a pointer map. 2645 LInstruction* AssignPointerMap(LInstruction* instr); 2646 2647 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY }; 2648 2649 // Marks a call for the register allocator. Assigns a pointer map to 2650 // support GC and lazy deoptimization. Assigns an environment to support 2651 // eager deoptimization if CAN_DEOPTIMIZE_EAGERLY. 2652 LInstruction* MarkAsCall( 2653 LInstruction* instr, 2654 HInstruction* hinstr, 2655 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); 2656 2657 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env, 2658 int* argument_index_accumulator, 2659 ZoneList<HValue*>* objects_to_materialize); 2660 2661 void VisitInstruction(HInstruction* current); 2662 2663 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); 2664 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); 2665 LInstruction* DoArithmeticD(Token::Value op, 2666 HArithmeticBinaryOperation* instr); 2667 LInstruction* DoArithmeticT(Token::Value op, 2668 HArithmeticBinaryOperation* instr); 2669 2670 LPlatformChunk* chunk_; 2671 CompilationInfo* info_; 2672 HGraph* const graph_; 2673 Zone* zone_; 2674 Status status_; 2675 HInstruction* current_instruction_; 2676 HBasicBlock* current_block_; 2677 HBasicBlock* next_block_; 2678 int argument_count_; 2679 LAllocator* allocator_; 2680 int position_; 2681 LInstruction* instruction_pending_deoptimization_environment_; 2682 BailoutId pending_deoptimization_ast_id_; 2683 2684 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); 2685 }; 2686 2687 #undef DECLARE_HYDROGEN_ACCESSOR 2688 #undef DECLARE_CONCRETE_INSTRUCTION 2689 2690 } } // namespace v8::int 2691 2692 #endif // V8_X64_LITHIUM_X64_H_ 2693