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