lithium-mips.h revision 5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b
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_MIPS_LITHIUM_MIPS_H_ 29#define V8_MIPS_LITHIUM_MIPS_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 37namespace v8 { 38namespace internal { 39 40// Forward declarations. 41class LCodeGen; 42 43#define LITHIUM_ALL_INSTRUCTION_LIST(V) \ 44 V(ControlInstruction) \ 45 V(Call) \ 46 LITHIUM_CONCRETE_INSTRUCTION_LIST(V) 47 48 49#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ 50 V(AccessArgumentsAt) \ 51 V(AddI) \ 52 V(AllocateObject) \ 53 V(ApplyArguments) \ 54 V(ArgumentsElements) \ 55 V(ArgumentsLength) \ 56 V(ArithmeticD) \ 57 V(ArithmeticT) \ 58 V(ArrayLiteral) \ 59 V(BitI) \ 60 V(BitNotI) \ 61 V(BoundsCheck) \ 62 V(Branch) \ 63 V(CallConstantFunction) \ 64 V(CallFunction) \ 65 V(CallGlobal) \ 66 V(CallKeyed) \ 67 V(CallKnownGlobal) \ 68 V(CallNamed) \ 69 V(CallNew) \ 70 V(CallRuntime) \ 71 V(CallStub) \ 72 V(CheckFunction) \ 73 V(CheckInstanceType) \ 74 V(CheckMap) \ 75 V(CheckNonSmi) \ 76 V(CheckPrototypeMaps) \ 77 V(CheckSmi) \ 78 V(ClampDToUint8) \ 79 V(ClampIToUint8) \ 80 V(ClampTToUint8) \ 81 V(ClassOfTestAndBranch) \ 82 V(CmpConstantEqAndBranch) \ 83 V(CmpIDAndBranch) \ 84 V(CmpObjectEqAndBranch) \ 85 V(CmpMapAndBranch) \ 86 V(CmpT) \ 87 V(ConstantD) \ 88 V(ConstantI) \ 89 V(ConstantT) \ 90 V(Context) \ 91 V(DeclareGlobals) \ 92 V(DeleteProperty) \ 93 V(Deoptimize) \ 94 V(DivI) \ 95 V(DoubleToI) \ 96 V(ElementsKind) \ 97 V(FastLiteral) \ 98 V(FixedArrayBaseLength) \ 99 V(FunctionLiteral) \ 100 V(GetCachedArrayIndex) \ 101 V(GlobalObject) \ 102 V(GlobalReceiver) \ 103 V(Goto) \ 104 V(HasCachedArrayIndexAndBranch) \ 105 V(HasInstanceTypeAndBranch) \ 106 V(In) \ 107 V(InstanceOf) \ 108 V(InstanceOfKnownGlobal) \ 109 V(InstructionGap) \ 110 V(Integer32ToDouble) \ 111 V(InvokeFunction) \ 112 V(IsConstructCallAndBranch) \ 113 V(IsNilAndBranch) \ 114 V(IsObjectAndBranch) \ 115 V(IsStringAndBranch) \ 116 V(IsSmiAndBranch) \ 117 V(IsUndetectableAndBranch) \ 118 V(StringCompareAndBranch) \ 119 V(JSArrayLength) \ 120 V(Label) \ 121 V(LazyBailout) \ 122 V(LoadContextSlot) \ 123 V(LoadElements) \ 124 V(LoadExternalArrayPointer) \ 125 V(LoadFunctionPrototype) \ 126 V(LoadGlobalCell) \ 127 V(LoadGlobalGeneric) \ 128 V(LoadKeyedFastDoubleElement) \ 129 V(LoadKeyedFastElement) \ 130 V(LoadKeyedGeneric) \ 131 V(LoadKeyedSpecializedArrayElement) \ 132 V(LoadNamedField) \ 133 V(LoadNamedFieldPolymorphic) \ 134 V(LoadNamedGeneric) \ 135 V(ModI) \ 136 V(MulI) \ 137 V(NumberTagD) \ 138 V(NumberTagI) \ 139 V(NumberUntagD) \ 140 V(ObjectLiteral) \ 141 V(OsrEntry) \ 142 V(OuterContext) \ 143 V(Parameter) \ 144 V(Power) \ 145 V(PushArgument) \ 146 V(Random) \ 147 V(RegExpLiteral) \ 148 V(Return) \ 149 V(ShiftI) \ 150 V(SmiTag) \ 151 V(SmiUntag) \ 152 V(StackCheck) \ 153 V(StoreContextSlot) \ 154 V(StoreGlobalCell) \ 155 V(StoreGlobalGeneric) \ 156 V(StoreKeyedFastDoubleElement) \ 157 V(StoreKeyedFastElement) \ 158 V(StoreKeyedGeneric) \ 159 V(StoreKeyedSpecializedArrayElement) \ 160 V(StoreNamedField) \ 161 V(StoreNamedGeneric) \ 162 V(StringAdd) \ 163 V(StringCharCodeAt) \ 164 V(StringCharFromCode) \ 165 V(StringLength) \ 166 V(SubI) \ 167 V(TaggedToI) \ 168 V(ThisFunction) \ 169 V(Throw) \ 170 V(ToFastProperties) \ 171 V(TransitionElementsKind) \ 172 V(Typeof) \ 173 V(TypeofIsAndBranch) \ 174 V(UnaryMathOperation) \ 175 V(UnknownOSRValue) \ 176 V(ValueOf) \ 177 V(ForInPrepareMap) \ 178 V(ForInCacheArray) \ 179 V(CheckMapValue) \ 180 V(LoadFieldByIndex) \ 181 V(DateField) \ 182 V(WrapReceiver) 183 184#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ 185 virtual Opcode opcode() const { return LInstruction::k##type; } \ 186 virtual void CompileToNative(LCodeGen* generator); \ 187 virtual const char* Mnemonic() const { return mnemonic; } \ 188 static L##type* cast(LInstruction* instr) { \ 189 ASSERT(instr->Is##type()); \ 190 return reinterpret_cast<L##type*>(instr); \ 191 } 192 193 194#define DECLARE_HYDROGEN_ACCESSOR(type) \ 195 H##type* hydrogen() const { \ 196 return H##type::cast(hydrogen_value()); \ 197 } 198 199 200class LInstruction: public ZoneObject { 201 public: 202 LInstruction() 203 : environment_(NULL), 204 hydrogen_value_(NULL), 205 is_call_(false), 206 is_save_doubles_(false) { } 207 virtual ~LInstruction() { } 208 209 virtual void CompileToNative(LCodeGen* generator) = 0; 210 virtual const char* Mnemonic() const = 0; 211 virtual void PrintTo(StringStream* stream); 212 virtual void PrintDataTo(StringStream* stream) = 0; 213 virtual void PrintOutputOperandTo(StringStream* stream) = 0; 214 215 enum Opcode { 216 // Declare a unique enum value for each instruction. 217#define DECLARE_OPCODE(type) k##type, 218 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) 219 kNumberOfInstructions 220#undef DECLARE_OPCODE 221 }; 222 223 virtual Opcode opcode() const = 0; 224 225 // Declare non-virtual type testers for all leaf IR classes. 226#define DECLARE_PREDICATE(type) \ 227 bool Is##type() const { return opcode() == k##type; } 228 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE) 229#undef DECLARE_PREDICATE 230 231 // Declare virtual predicates for instructions that don't have 232 // an opcode. 233 virtual bool IsGap() const { return false; } 234 235 virtual bool IsControl() const { return false; } 236 237 void set_environment(LEnvironment* env) { environment_ = env; } 238 LEnvironment* environment() const { return environment_; } 239 bool HasEnvironment() const { return environment_ != NULL; } 240 241 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } 242 LPointerMap* pointer_map() const { return pointer_map_.get(); } 243 bool HasPointerMap() const { return pointer_map_.is_set(); } 244 245 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } 246 HValue* hydrogen_value() const { return hydrogen_value_; } 247 248 void set_deoptimization_environment(LEnvironment* env) { 249 deoptimization_environment_.set(env); 250 } 251 LEnvironment* deoptimization_environment() const { 252 return deoptimization_environment_.get(); 253 } 254 bool HasDeoptimizationEnvironment() const { 255 return deoptimization_environment_.is_set(); 256 } 257 258 void MarkAsCall() { is_call_ = true; } 259 void MarkAsSaveDoubles() { is_save_doubles_ = true; } 260 261 // Interface to the register allocator and iterators. 262 bool IsMarkedAsCall() const { return is_call_; } 263 bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; } 264 265 virtual bool HasResult() const = 0; 266 virtual LOperand* result() = 0; 267 268 virtual int InputCount() = 0; 269 virtual LOperand* InputAt(int i) = 0; 270 virtual int TempCount() = 0; 271 virtual LOperand* TempAt(int i) = 0; 272 273 LOperand* FirstInput() { return InputAt(0); } 274 LOperand* Output() { return HasResult() ? result() : NULL; } 275 276#ifdef DEBUG 277 void VerifyCall(); 278#endif 279 280 private: 281 LEnvironment* environment_; 282 SetOncePointer<LPointerMap> pointer_map_; 283 HValue* hydrogen_value_; 284 SetOncePointer<LEnvironment> deoptimization_environment_; 285 bool is_call_; 286 bool is_save_doubles_; 287}; 288 289 290// R = number of result operands (0 or 1). 291// I = number of input operands. 292// T = number of temporary operands. 293template<int R, int I, int T> 294class LTemplateInstruction: public LInstruction { 295 public: 296 // Allow 0 or 1 output operands. 297 STATIC_ASSERT(R == 0 || R == 1); 298 virtual bool HasResult() const { return R != 0; } 299 void set_result(LOperand* operand) { results_[0] = operand; } 300 LOperand* result() { return results_[0]; } 301 302 int InputCount() { return I; } 303 LOperand* InputAt(int i) { return inputs_[i]; } 304 305 int TempCount() { return T; } 306 LOperand* TempAt(int i) { return temps_[i]; } 307 308 virtual void PrintDataTo(StringStream* stream); 309 virtual void PrintOutputOperandTo(StringStream* stream); 310 311 protected: 312 EmbeddedContainer<LOperand*, R> results_; 313 EmbeddedContainer<LOperand*, I> inputs_; 314 EmbeddedContainer<LOperand*, T> temps_; 315}; 316 317 318class LGap: public LTemplateInstruction<0, 0, 0> { 319 public: 320 explicit LGap(HBasicBlock* block) 321 : block_(block) { 322 parallel_moves_[BEFORE] = NULL; 323 parallel_moves_[START] = NULL; 324 parallel_moves_[END] = NULL; 325 parallel_moves_[AFTER] = NULL; 326 } 327 328 // Can't use the DECLARE-macro here because of sub-classes. 329 virtual bool IsGap() const { return true; } 330 virtual void PrintDataTo(StringStream* stream); 331 static LGap* cast(LInstruction* instr) { 332 ASSERT(instr->IsGap()); 333 return reinterpret_cast<LGap*>(instr); 334 } 335 336 bool IsRedundant() const; 337 338 HBasicBlock* block() const { return block_; } 339 340 enum InnerPosition { 341 BEFORE, 342 START, 343 END, 344 AFTER, 345 FIRST_INNER_POSITION = BEFORE, 346 LAST_INNER_POSITION = AFTER 347 }; 348 349 LParallelMove* GetOrCreateParallelMove(InnerPosition pos) { 350 if (parallel_moves_[pos] == NULL) parallel_moves_[pos] = new LParallelMove; 351 return parallel_moves_[pos]; 352 } 353 354 LParallelMove* GetParallelMove(InnerPosition pos) { 355 return parallel_moves_[pos]; 356 } 357 358 private: 359 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; 360 HBasicBlock* block_; 361}; 362 363 364class LInstructionGap: public LGap { 365 public: 366 explicit LInstructionGap(HBasicBlock* block) : LGap(block) { } 367 368 DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap") 369}; 370 371 372class LGoto: public LTemplateInstruction<0, 0, 0> { 373 public: 374 explicit LGoto(int block_id) : block_id_(block_id) { } 375 376 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") 377 virtual void PrintDataTo(StringStream* stream); 378 virtual bool IsControl() const { return true; } 379 380 int block_id() const { return block_id_; } 381 382 private: 383 int block_id_; 384}; 385 386 387class LLazyBailout: public LTemplateInstruction<0, 0, 0> { 388 public: 389 LLazyBailout() : gap_instructions_size_(0) { } 390 391 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") 392 393 void set_gap_instructions_size(int gap_instructions_size) { 394 gap_instructions_size_ = gap_instructions_size; 395 } 396 int gap_instructions_size() { return gap_instructions_size_; } 397 398 private: 399 int gap_instructions_size_; 400}; 401 402 403class LDeoptimize: public LTemplateInstruction<0, 0, 0> { 404 public: 405 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") 406}; 407 408 409class LLabel: public LGap { 410 public: 411 explicit LLabel(HBasicBlock* block) 412 : LGap(block), replacement_(NULL) { } 413 414 DECLARE_CONCRETE_INSTRUCTION(Label, "label") 415 416 virtual void PrintDataTo(StringStream* stream); 417 418 int block_id() const { return block()->block_id(); } 419 bool is_loop_header() const { return block()->IsLoopHeader(); } 420 Label* label() { return &label_; } 421 LLabel* replacement() const { return replacement_; } 422 void set_replacement(LLabel* label) { replacement_ = label; } 423 bool HasReplacement() const { return replacement_ != NULL; } 424 425 private: 426 Label label_; 427 LLabel* replacement_; 428}; 429 430 431class LParameter: public LTemplateInstruction<1, 0, 0> { 432 public: 433 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter") 434}; 435 436 437class LCallStub: public LTemplateInstruction<1, 0, 0> { 438 public: 439 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub") 440 DECLARE_HYDROGEN_ACCESSOR(CallStub) 441 442 TranscendentalCache::Type transcendental_type() { 443 return hydrogen()->transcendental_type(); 444 } 445}; 446 447 448class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { 449 public: 450 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value") 451}; 452 453 454template<int I, int T> 455class LControlInstruction: public LTemplateInstruction<0, I, T> { 456 public: 457 virtual bool IsControl() const { return true; } 458 459 int SuccessorCount() { return hydrogen()->SuccessorCount(); } 460 HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } 461 int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); } 462 int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); } 463 464 private: 465 HControlInstruction* hydrogen() { 466 return HControlInstruction::cast(this->hydrogen_value()); 467 } 468}; 469 470 471class LWrapReceiver: public LTemplateInstruction<1, 2, 0> { 472 public: 473 LWrapReceiver(LOperand* receiver, LOperand* function) { 474 inputs_[0] = receiver; 475 inputs_[1] = function; 476 } 477 478 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver") 479 480 LOperand* receiver() { return inputs_[0]; } 481 LOperand* function() { return inputs_[1]; } 482}; 483 484 485class LApplyArguments: public LTemplateInstruction<1, 4, 0> { 486 public: 487 LApplyArguments(LOperand* function, 488 LOperand* receiver, 489 LOperand* length, 490 LOperand* elements) { 491 inputs_[0] = function; 492 inputs_[1] = receiver; 493 inputs_[2] = length; 494 inputs_[3] = elements; 495 } 496 497 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments") 498 499 LOperand* function() { return inputs_[0]; } 500 LOperand* receiver() { return inputs_[1]; } 501 LOperand* length() { return inputs_[2]; } 502 LOperand* elements() { return inputs_[3]; } 503}; 504 505 506class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> { 507 public: 508 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) { 509 inputs_[0] = arguments; 510 inputs_[1] = length; 511 inputs_[2] = index; 512 } 513 514 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at") 515 516 LOperand* arguments() { return inputs_[0]; } 517 LOperand* length() { return inputs_[1]; } 518 LOperand* index() { return inputs_[2]; } 519 520 virtual void PrintDataTo(StringStream* stream); 521}; 522 523 524class LArgumentsLength: public LTemplateInstruction<1, 1, 0> { 525 public: 526 explicit LArgumentsLength(LOperand* elements) { 527 inputs_[0] = elements; 528 } 529 530 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length") 531}; 532 533 534class LArgumentsElements: public LTemplateInstruction<1, 0, 0> { 535 public: 536 LArgumentsElements() { } 537 538 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") 539}; 540 541 542class LModI: public LTemplateInstruction<1, 2, 3> { 543 public: 544 // Used when the right hand is a constant power of 2. 545 LModI(LOperand* left, 546 LOperand* right) { 547 inputs_[0] = left; 548 inputs_[1] = right; 549 temps_[0] = NULL; 550 temps_[1] = NULL; 551 temps_[2] = NULL; 552 } 553 554 // Used for the standard case. 555 LModI(LOperand* left, 556 LOperand* right, 557 LOperand* temp1, 558 LOperand* temp2, 559 LOperand* temp3) { 560 inputs_[0] = left; 561 inputs_[1] = right; 562 temps_[0] = temp1; 563 temps_[1] = temp2; 564 temps_[2] = temp3; 565 } 566 567 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i") 568 DECLARE_HYDROGEN_ACCESSOR(Mod) 569}; 570 571 572class LDivI: public LTemplateInstruction<1, 2, 0> { 573 public: 574 LDivI(LOperand* left, LOperand* right) { 575 inputs_[0] = left; 576 inputs_[1] = right; 577 } 578 579 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i") 580 DECLARE_HYDROGEN_ACCESSOR(Div) 581}; 582 583 584class LMulI: public LTemplateInstruction<1, 2, 1> { 585 public: 586 LMulI(LOperand* left, LOperand* right, LOperand* temp) { 587 inputs_[0] = left; 588 inputs_[1] = right; 589 temps_[0] = temp; 590 } 591 592 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i") 593 DECLARE_HYDROGEN_ACCESSOR(Mul) 594}; 595 596 597class LCmpIDAndBranch: public LControlInstruction<2, 0> { 598 public: 599 LCmpIDAndBranch(LOperand* left, LOperand* right) { 600 inputs_[0] = left; 601 inputs_[1] = right; 602 } 603 604 DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch") 605 DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch) 606 607 Token::Value op() const { return hydrogen()->token(); } 608 bool is_double() const { 609 return hydrogen()->GetInputRepresentation().IsDouble(); 610 } 611 612 virtual void PrintDataTo(StringStream* stream); 613}; 614 615 616class LUnaryMathOperation: public LTemplateInstruction<1, 1, 1> { 617 public: 618 LUnaryMathOperation(LOperand* value, LOperand* temp) { 619 inputs_[0] = value; 620 temps_[0] = temp; 621 } 622 623 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation") 624 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 625 626 virtual void PrintDataTo(StringStream* stream); 627 BuiltinFunctionId op() const { return hydrogen()->op(); } 628}; 629 630 631class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> { 632 public: 633 LCmpObjectEqAndBranch(LOperand* left, LOperand* right) { 634 inputs_[0] = left; 635 inputs_[1] = right; 636 } 637 638 DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, 639 "cmp-object-eq-and-branch") 640 DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch) 641}; 642 643 644class LCmpConstantEqAndBranch: public LControlInstruction<1, 0> { 645 public: 646 explicit LCmpConstantEqAndBranch(LOperand* left) { 647 inputs_[0] = left; 648 } 649 650 DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch, 651 "cmp-constant-eq-and-branch") 652 DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch) 653}; 654 655 656class LIsNilAndBranch: public LControlInstruction<1, 0> { 657 public: 658 explicit LIsNilAndBranch(LOperand* value) { 659 inputs_[0] = value; 660 } 661 662 DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch, "is-nil-and-branch") 663 DECLARE_HYDROGEN_ACCESSOR(IsNilAndBranch) 664 665 EqualityKind kind() const { return hydrogen()->kind(); } 666 NilValue nil() const { return hydrogen()->nil(); } 667 668 virtual void PrintDataTo(StringStream* stream); 669}; 670 671 672class LIsObjectAndBranch: public LControlInstruction<1, 1> { 673 public: 674 LIsObjectAndBranch(LOperand* value, LOperand* temp) { 675 inputs_[0] = value; 676 temps_[0] = temp; 677 } 678 679 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch") 680 DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch) 681 682 virtual void PrintDataTo(StringStream* stream); 683}; 684 685 686class LIsStringAndBranch: public LControlInstruction<1, 1> { 687 public: 688 LIsStringAndBranch(LOperand* value, LOperand* temp) { 689 inputs_[0] = value; 690 temps_[0] = temp; 691 } 692 693 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch") 694 DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch) 695 696 virtual void PrintDataTo(StringStream* stream); 697}; 698 699 700class LIsSmiAndBranch: public LControlInstruction<1, 0> { 701 public: 702 explicit LIsSmiAndBranch(LOperand* value) { 703 inputs_[0] = value; 704 } 705 706 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch") 707 DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch) 708 709 virtual void PrintDataTo(StringStream* stream); 710}; 711 712 713class LIsUndetectableAndBranch: public LControlInstruction<1, 1> { 714 public: 715 explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) { 716 inputs_[0] = value; 717 temps_[0] = temp; 718 } 719 720 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch, 721 "is-undetectable-and-branch") 722 DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch) 723 724 virtual void PrintDataTo(StringStream* stream); 725}; 726 727 728class LStringCompareAndBranch: public LControlInstruction<2, 0> { 729 public: 730 LStringCompareAndBranch(LOperand* left, LOperand* right) { 731 inputs_[0] = left; 732 inputs_[1] = right; 733 } 734 735 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch, 736 "string-compare-and-branch") 737 DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch) 738 739 Token::Value op() const { return hydrogen()->token(); } 740 741 virtual void PrintDataTo(StringStream* stream); 742}; 743 744 745class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> { 746 public: 747 explicit LHasInstanceTypeAndBranch(LOperand* value) { 748 inputs_[0] = value; 749 } 750 751 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch, 752 "has-instance-type-and-branch") 753 DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch) 754 755 virtual void PrintDataTo(StringStream* stream); 756}; 757 758 759class LGetCachedArrayIndex: public LTemplateInstruction<1, 1, 0> { 760 public: 761 explicit LGetCachedArrayIndex(LOperand* value) { 762 inputs_[0] = value; 763 } 764 765 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index") 766 DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex) 767}; 768 769 770class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> { 771 public: 772 explicit LHasCachedArrayIndexAndBranch(LOperand* value) { 773 inputs_[0] = value; 774 } 775 776 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch, 777 "has-cached-array-index-and-branch") 778 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch) 779 780 virtual void PrintDataTo(StringStream* stream); 781}; 782 783 784class LClassOfTestAndBranch: public LControlInstruction<1, 1> { 785 public: 786 LClassOfTestAndBranch(LOperand* value, LOperand* temp) { 787 inputs_[0] = value; 788 temps_[0] = temp; 789 } 790 791 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, 792 "class-of-test-and-branch") 793 DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch) 794 795 virtual void PrintDataTo(StringStream* stream); 796}; 797 798 799class LCmpT: public LTemplateInstruction<1, 2, 0> { 800 public: 801 LCmpT(LOperand* left, LOperand* right) { 802 inputs_[0] = left; 803 inputs_[1] = right; 804 } 805 806 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t") 807 DECLARE_HYDROGEN_ACCESSOR(CompareGeneric) 808 809 Token::Value op() const { return hydrogen()->token(); } 810}; 811 812 813class LInstanceOf: public LTemplateInstruction<1, 2, 0> { 814 public: 815 LInstanceOf(LOperand* left, LOperand* right) { 816 inputs_[0] = left; 817 inputs_[1] = right; 818 } 819 820 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of") 821}; 822 823 824class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> { 825 public: 826 LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) { 827 inputs_[0] = value; 828 temps_[0] = temp; 829 } 830 831 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal, 832 "instance-of-known-global") 833 DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal) 834 835 Handle<JSFunction> function() const { return hydrogen()->function(); } 836}; 837 838 839class LBoundsCheck: public LTemplateInstruction<0, 2, 0> { 840 public: 841 LBoundsCheck(LOperand* index, LOperand* length) { 842 inputs_[0] = index; 843 inputs_[1] = length; 844 } 845 846 LOperand* index() { return inputs_[0]; } 847 LOperand* length() { return inputs_[1]; } 848 849 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") 850}; 851 852 853class LBitI: public LTemplateInstruction<1, 2, 0> { 854 public: 855 LBitI(LOperand* left, LOperand* right) { 856 inputs_[0] = left; 857 inputs_[1] = right; 858 } 859 860 Token::Value op() const { return hydrogen()->op(); } 861 862 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") 863 DECLARE_HYDROGEN_ACCESSOR(Bitwise) 864}; 865 866 867class LShiftI: public LTemplateInstruction<1, 2, 0> { 868 public: 869 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) 870 : op_(op), can_deopt_(can_deopt) { 871 inputs_[0] = left; 872 inputs_[1] = right; 873 } 874 875 Token::Value op() const { return op_; } 876 877 bool can_deopt() const { return can_deopt_; } 878 879 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") 880 881 private: 882 Token::Value op_; 883 bool can_deopt_; 884}; 885 886 887class LSubI: public LTemplateInstruction<1, 2, 0> { 888 public: 889 LSubI(LOperand* left, LOperand* right) { 890 inputs_[0] = left; 891 inputs_[1] = right; 892 } 893 894 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") 895 DECLARE_HYDROGEN_ACCESSOR(Sub) 896}; 897 898 899class LConstantI: public LTemplateInstruction<1, 0, 0> { 900 public: 901 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i") 902 DECLARE_HYDROGEN_ACCESSOR(Constant) 903 904 int32_t value() const { return hydrogen()->Integer32Value(); } 905}; 906 907 908class LConstantD: public LTemplateInstruction<1, 0, 0> { 909 public: 910 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d") 911 DECLARE_HYDROGEN_ACCESSOR(Constant) 912 913 double value() const { return hydrogen()->DoubleValue(); } 914}; 915 916 917class LConstantT: public LTemplateInstruction<1, 0, 0> { 918 public: 919 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t") 920 DECLARE_HYDROGEN_ACCESSOR(Constant) 921 922 Handle<Object> value() const { return hydrogen()->handle(); } 923}; 924 925 926class LBranch: public LControlInstruction<1, 0> { 927 public: 928 explicit LBranch(LOperand* value) { 929 inputs_[0] = value; 930 } 931 932 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch") 933 DECLARE_HYDROGEN_ACCESSOR(Branch) 934 935 virtual void PrintDataTo(StringStream* stream); 936}; 937 938 939class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> { 940 public: 941 LCmpMapAndBranch(LOperand* value, LOperand* temp) { 942 inputs_[0] = value; 943 temps_[0] = temp; 944 } 945 946 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") 947 DECLARE_HYDROGEN_ACCESSOR(CompareMap) 948 949 virtual bool IsControl() const { return true; } 950 951 Handle<Map> map() const { return hydrogen()->map(); } 952 int true_block_id() const { 953 return hydrogen()->FirstSuccessor()->block_id(); 954 } 955 int false_block_id() const { 956 return hydrogen()->SecondSuccessor()->block_id(); 957 } 958}; 959 960 961class LJSArrayLength: public LTemplateInstruction<1, 1, 0> { 962 public: 963 explicit LJSArrayLength(LOperand* value) { 964 inputs_[0] = value; 965 } 966 967 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length") 968 DECLARE_HYDROGEN_ACCESSOR(JSArrayLength) 969}; 970 971 972class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> { 973 public: 974 explicit LFixedArrayBaseLength(LOperand* value) { 975 inputs_[0] = value; 976 } 977 978 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength, 979 "fixed-array-base-length") 980 DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength) 981}; 982 983 984class LElementsKind: public LTemplateInstruction<1, 1, 0> { 985 public: 986 explicit LElementsKind(LOperand* value) { 987 inputs_[0] = value; 988 } 989 990 DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind") 991 DECLARE_HYDROGEN_ACCESSOR(ElementsKind) 992}; 993 994 995class LValueOf: public LTemplateInstruction<1, 1, 1> { 996 public: 997 LValueOf(LOperand* value, LOperand* temp) { 998 inputs_[0] = value; 999 temps_[0] = temp; 1000 } 1001 1002 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of") 1003 DECLARE_HYDROGEN_ACCESSOR(ValueOf) 1004}; 1005 1006 1007class LDateField: public LTemplateInstruction<1, 1, 1> { 1008 public: 1009 LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) { 1010 inputs_[0] = date; 1011 temps_[0] = temp; 1012 } 1013 1014 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "date-field") 1015 DECLARE_HYDROGEN_ACCESSOR(ValueOf) 1016 Smi* index() const { return index_; } 1017 1018 private: 1019 Smi* index_; 1020}; 1021 1022 1023class LThrow: public LTemplateInstruction<0, 1, 0> { 1024 public: 1025 explicit LThrow(LOperand* value) { 1026 inputs_[0] = value; 1027 } 1028 1029 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw") 1030}; 1031 1032 1033class LBitNotI: public LTemplateInstruction<1, 1, 0> { 1034 public: 1035 explicit LBitNotI(LOperand* value) { 1036 inputs_[0] = value; 1037 } 1038 1039 DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i") 1040}; 1041 1042 1043class LAddI: public LTemplateInstruction<1, 2, 0> { 1044 public: 1045 LAddI(LOperand* left, LOperand* right) { 1046 inputs_[0] = left; 1047 inputs_[1] = right; 1048 } 1049 1050 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") 1051 DECLARE_HYDROGEN_ACCESSOR(Add) 1052}; 1053 1054 1055class LPower: public LTemplateInstruction<1, 2, 0> { 1056 public: 1057 LPower(LOperand* left, LOperand* right) { 1058 inputs_[0] = left; 1059 inputs_[1] = right; 1060 } 1061 1062 DECLARE_CONCRETE_INSTRUCTION(Power, "power") 1063 DECLARE_HYDROGEN_ACCESSOR(Power) 1064}; 1065 1066 1067class LRandom: public LTemplateInstruction<1, 1, 0> { 1068 public: 1069 explicit LRandom(LOperand* global_object) { 1070 inputs_[0] = global_object; 1071 } 1072 1073 DECLARE_CONCRETE_INSTRUCTION(Random, "random") 1074 DECLARE_HYDROGEN_ACCESSOR(Random) 1075}; 1076 1077 1078class LArithmeticD: public LTemplateInstruction<1, 2, 0> { 1079 public: 1080 LArithmeticD(Token::Value op, LOperand* left, LOperand* right) 1081 : op_(op) { 1082 inputs_[0] = left; 1083 inputs_[1] = right; 1084 } 1085 1086 Token::Value op() const { return op_; } 1087 1088 virtual Opcode opcode() const { return LInstruction::kArithmeticD; } 1089 virtual void CompileToNative(LCodeGen* generator); 1090 virtual const char* Mnemonic() const; 1091 1092 private: 1093 Token::Value op_; 1094}; 1095 1096 1097class LArithmeticT: public LTemplateInstruction<1, 2, 0> { 1098 public: 1099 LArithmeticT(Token::Value op, LOperand* left, LOperand* right) 1100 : op_(op) { 1101 inputs_[0] = left; 1102 inputs_[1] = right; 1103 } 1104 1105 virtual Opcode opcode() const { return LInstruction::kArithmeticT; } 1106 virtual void CompileToNative(LCodeGen* generator); 1107 virtual const char* Mnemonic() const; 1108 1109 Token::Value op() const { return op_; } 1110 1111 private: 1112 Token::Value op_; 1113}; 1114 1115 1116class LReturn: public LTemplateInstruction<0, 1, 0> { 1117 public: 1118 explicit LReturn(LOperand* value) { 1119 inputs_[0] = value; 1120 } 1121 1122 DECLARE_CONCRETE_INSTRUCTION(Return, "return") 1123}; 1124 1125 1126class LLoadNamedField: public LTemplateInstruction<1, 1, 0> { 1127 public: 1128 explicit LLoadNamedField(LOperand* object) { 1129 inputs_[0] = object; 1130 } 1131 1132 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field") 1133 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField) 1134}; 1135 1136 1137class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> { 1138 public: 1139 explicit LLoadNamedFieldPolymorphic(LOperand* object) { 1140 inputs_[0] = object; 1141 } 1142 1143 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic") 1144 DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic) 1145 1146 LOperand* object() { return inputs_[0]; } 1147}; 1148 1149 1150class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> { 1151 public: 1152 explicit LLoadNamedGeneric(LOperand* object) { 1153 inputs_[0] = object; 1154 } 1155 1156 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic") 1157 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric) 1158 1159 LOperand* object() { return inputs_[0]; } 1160 Handle<Object> name() const { return hydrogen()->name(); } 1161}; 1162 1163 1164class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> { 1165 public: 1166 explicit LLoadFunctionPrototype(LOperand* function) { 1167 inputs_[0] = function; 1168 } 1169 1170 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype") 1171 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype) 1172 1173 LOperand* function() { return inputs_[0]; } 1174}; 1175 1176 1177class LLoadElements: public LTemplateInstruction<1, 1, 0> { 1178 public: 1179 explicit LLoadElements(LOperand* object) { 1180 inputs_[0] = object; 1181 } 1182 1183 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements") 1184}; 1185 1186 1187class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> { 1188 public: 1189 explicit LLoadExternalArrayPointer(LOperand* object) { 1190 inputs_[0] = object; 1191 } 1192 1193 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer, 1194 "load-external-array-pointer") 1195}; 1196 1197 1198class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> { 1199 public: 1200 LLoadKeyedFastElement(LOperand* elements, LOperand* key) { 1201 inputs_[0] = elements; 1202 inputs_[1] = key; 1203 } 1204 1205 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element") 1206 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement) 1207 1208 LOperand* elements() { return inputs_[0]; } 1209 LOperand* key() { return inputs_[1]; } 1210}; 1211 1212 1213class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> { 1214 public: 1215 LLoadKeyedFastDoubleElement(LOperand* elements, LOperand* key) { 1216 inputs_[0] = elements; 1217 inputs_[1] = key; 1218 } 1219 1220 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement, 1221 "load-keyed-fast-double-element") 1222 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement) 1223 1224 LOperand* elements() { return inputs_[0]; } 1225 LOperand* key() { return inputs_[1]; } 1226}; 1227 1228 1229class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> { 1230 public: 1231 LLoadKeyedSpecializedArrayElement(LOperand* external_pointer, 1232 LOperand* key) { 1233 inputs_[0] = external_pointer; 1234 inputs_[1] = key; 1235 } 1236 1237 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement, 1238 "load-keyed-specialized-array-element") 1239 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement) 1240 1241 LOperand* external_pointer() { return inputs_[0]; } 1242 LOperand* key() { return inputs_[1]; } 1243 ElementsKind elements_kind() const { 1244 return hydrogen()->elements_kind(); 1245 } 1246}; 1247 1248 1249class LLoadKeyedGeneric: public LTemplateInstruction<1, 2, 0> { 1250 public: 1251 LLoadKeyedGeneric(LOperand* obj, LOperand* key) { 1252 inputs_[0] = obj; 1253 inputs_[1] = key; 1254 } 1255 1256 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic") 1257 1258 LOperand* object() { return inputs_[0]; } 1259 LOperand* key() { return inputs_[1]; } 1260}; 1261 1262 1263class LLoadGlobalCell: public LTemplateInstruction<1, 0, 0> { 1264 public: 1265 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell") 1266 DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell) 1267}; 1268 1269 1270class LLoadGlobalGeneric: public LTemplateInstruction<1, 1, 0> { 1271 public: 1272 explicit LLoadGlobalGeneric(LOperand* global_object) { 1273 inputs_[0] = global_object; 1274 } 1275 1276 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic") 1277 DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric) 1278 1279 LOperand* global_object() { return inputs_[0]; } 1280 Handle<Object> name() const { return hydrogen()->name(); } 1281 bool for_typeof() const { return hydrogen()->for_typeof(); } 1282}; 1283 1284 1285class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> { 1286 public: 1287 LStoreGlobalCell(LOperand* value, LOperand* temp) { 1288 inputs_[0] = value; 1289 temps_[0] = temp; 1290 } 1291 1292 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell") 1293 DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell) 1294 1295 LOperand* value() { return inputs_[0]; } 1296}; 1297 1298 1299class LStoreGlobalGeneric: public LTemplateInstruction<0, 2, 0> { 1300 public: 1301 explicit LStoreGlobalGeneric(LOperand* global_object, 1302 LOperand* value) { 1303 inputs_[0] = global_object; 1304 inputs_[1] = value; 1305 } 1306 1307 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic") 1308 DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric) 1309 1310 LOperand* global_object() { return InputAt(0); } 1311 Handle<Object> name() const { return hydrogen()->name(); } 1312 LOperand* value() { return InputAt(1); } 1313 StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } 1314}; 1315 1316 1317class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> { 1318 public: 1319 explicit LLoadContextSlot(LOperand* context) { 1320 inputs_[0] = context; 1321 } 1322 1323 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot") 1324 DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot) 1325 1326 LOperand* context() { return InputAt(0); } 1327 int slot_index() { return hydrogen()->slot_index(); } 1328 1329 virtual void PrintDataTo(StringStream* stream); 1330}; 1331 1332 1333class LStoreContextSlot: public LTemplateInstruction<0, 2, 0> { 1334 public: 1335 LStoreContextSlot(LOperand* context, LOperand* value) { 1336 inputs_[0] = context; 1337 inputs_[1] = value; 1338 } 1339 1340 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot") 1341 DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot) 1342 1343 LOperand* context() { return InputAt(0); } 1344 LOperand* value() { return InputAt(1); } 1345 int slot_index() { return hydrogen()->slot_index(); } 1346 1347 virtual void PrintDataTo(StringStream* stream); 1348}; 1349 1350 1351class LPushArgument: public LTemplateInstruction<0, 1, 0> { 1352 public: 1353 explicit LPushArgument(LOperand* value) { 1354 inputs_[0] = value; 1355 } 1356 1357 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument") 1358}; 1359 1360 1361class LThisFunction: public LTemplateInstruction<1, 0, 0> { 1362 public: 1363 DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") 1364 DECLARE_HYDROGEN_ACCESSOR(ThisFunction) 1365}; 1366 1367 1368class LContext: public LTemplateInstruction<1, 0, 0> { 1369 public: 1370 DECLARE_CONCRETE_INSTRUCTION(Context, "context") 1371}; 1372 1373 1374class LOuterContext: public LTemplateInstruction<1, 1, 0> { 1375 public: 1376 explicit LOuterContext(LOperand* context) { 1377 inputs_[0] = context; 1378 } 1379 1380 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context") 1381 1382 LOperand* context() { return InputAt(0); } 1383}; 1384 1385 1386class LDeclareGlobals: public LTemplateInstruction<0, 0, 0> { 1387 public: 1388 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals") 1389 DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals) 1390}; 1391 1392 1393class LGlobalObject: public LTemplateInstruction<1, 1, 0> { 1394 public: 1395 explicit LGlobalObject(LOperand* context) { 1396 inputs_[0] = context; 1397 } 1398 1399 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") 1400 1401 LOperand* context() { return InputAt(0); } 1402}; 1403 1404 1405class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> { 1406 public: 1407 explicit LGlobalReceiver(LOperand* global_object) { 1408 inputs_[0] = global_object; 1409 } 1410 1411 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver") 1412 1413 LOperand* global() { return InputAt(0); } 1414}; 1415 1416 1417class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> { 1418 public: 1419 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function") 1420 DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction) 1421 1422 virtual void PrintDataTo(StringStream* stream); 1423 1424 Handle<JSFunction> function() { return hydrogen()->function(); } 1425 int arity() const { return hydrogen()->argument_count() - 1; } 1426}; 1427 1428 1429class LInvokeFunction: public LTemplateInstruction<1, 1, 0> { 1430 public: 1431 explicit LInvokeFunction(LOperand* function) { 1432 inputs_[0] = function; 1433 } 1434 1435 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") 1436 DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) 1437 1438 LOperand* function() { return inputs_[0]; } 1439 1440 virtual void PrintDataTo(StringStream* stream); 1441 1442 int arity() const { return hydrogen()->argument_count() - 1; } 1443}; 1444 1445 1446class LCallKeyed: public LTemplateInstruction<1, 1, 0> { 1447 public: 1448 explicit LCallKeyed(LOperand* key) { 1449 inputs_[0] = key; 1450 } 1451 1452 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed") 1453 DECLARE_HYDROGEN_ACCESSOR(CallKeyed) 1454 1455 virtual void PrintDataTo(StringStream* stream); 1456 1457 int arity() const { return hydrogen()->argument_count() - 1; } 1458}; 1459 1460 1461 1462class LCallNamed: public LTemplateInstruction<1, 0, 0> { 1463 public: 1464 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named") 1465 DECLARE_HYDROGEN_ACCESSOR(CallNamed) 1466 1467 virtual void PrintDataTo(StringStream* stream); 1468 1469 Handle<String> name() const { return hydrogen()->name(); } 1470 int arity() const { return hydrogen()->argument_count() - 1; } 1471}; 1472 1473 1474class LCallFunction: public LTemplateInstruction<1, 1, 0> { 1475 public: 1476 explicit LCallFunction(LOperand* function) { 1477 inputs_[0] = function; 1478 } 1479 1480 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function") 1481 DECLARE_HYDROGEN_ACCESSOR(CallFunction) 1482 1483 LOperand* function() { return inputs_[0]; } 1484 int arity() const { return hydrogen()->argument_count() - 1; } 1485}; 1486 1487 1488class LCallGlobal: public LTemplateInstruction<1, 0, 0> { 1489 public: 1490 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global") 1491 DECLARE_HYDROGEN_ACCESSOR(CallGlobal) 1492 1493 virtual void PrintDataTo(StringStream* stream); 1494 1495 Handle<String> name() const {return hydrogen()->name(); } 1496 int arity() const { return hydrogen()->argument_count() - 1; } 1497}; 1498 1499 1500class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> { 1501 public: 1502 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global") 1503 DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal) 1504 1505 virtual void PrintDataTo(StringStream* stream); 1506 1507 Handle<JSFunction> target() const { return hydrogen()->target(); } 1508 int arity() const { return hydrogen()->argument_count() - 1; } 1509}; 1510 1511 1512class LCallNew: public LTemplateInstruction<1, 1, 0> { 1513 public: 1514 explicit LCallNew(LOperand* constructor) { 1515 inputs_[0] = constructor; 1516 } 1517 1518 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new") 1519 DECLARE_HYDROGEN_ACCESSOR(CallNew) 1520 1521 virtual void PrintDataTo(StringStream* stream); 1522 1523 int arity() const { return hydrogen()->argument_count() - 1; } 1524}; 1525 1526 1527class LCallRuntime: public LTemplateInstruction<1, 0, 0> { 1528 public: 1529 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime") 1530 DECLARE_HYDROGEN_ACCESSOR(CallRuntime) 1531 1532 const Runtime::Function* function() const { return hydrogen()->function(); } 1533 int arity() const { return hydrogen()->argument_count(); } 1534}; 1535 1536 1537class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> { 1538 public: 1539 explicit LInteger32ToDouble(LOperand* value) { 1540 inputs_[0] = value; 1541 } 1542 1543 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double") 1544}; 1545 1546 1547class LNumberTagI: public LTemplateInstruction<1, 1, 0> { 1548 public: 1549 explicit LNumberTagI(LOperand* value) { 1550 inputs_[0] = value; 1551 } 1552 1553 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") 1554}; 1555 1556 1557class LNumberTagD: public LTemplateInstruction<1, 1, 2> { 1558 public: 1559 LNumberTagD(LOperand* value, LOperand* temp1, LOperand* temp2) { 1560 inputs_[0] = value; 1561 temps_[0] = temp1; 1562 temps_[1] = temp2; 1563 } 1564 1565 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d") 1566}; 1567 1568 1569// Sometimes truncating conversion from a tagged value to an int32. 1570class LDoubleToI: public LTemplateInstruction<1, 1, 2> { 1571 public: 1572 LDoubleToI(LOperand* value, LOperand* temp1, LOperand* temp2) { 1573 inputs_[0] = value; 1574 temps_[0] = temp1; 1575 temps_[1] = temp2; 1576 } 1577 1578 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i") 1579 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 1580 1581 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1582}; 1583 1584 1585// Truncating conversion from a tagged value to an int32. 1586class LTaggedToI: public LTemplateInstruction<1, 1, 3> { 1587 public: 1588 LTaggedToI(LOperand* value, 1589 LOperand* temp1, 1590 LOperand* temp2, 1591 LOperand* temp3) { 1592 inputs_[0] = value; 1593 temps_[0] = temp1; 1594 temps_[1] = temp2; 1595 temps_[2] = temp3; 1596 } 1597 1598 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i") 1599 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 1600 1601 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1602}; 1603 1604 1605class LSmiTag: public LTemplateInstruction<1, 1, 0> { 1606 public: 1607 explicit LSmiTag(LOperand* value) { 1608 inputs_[0] = value; 1609 } 1610 1611 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag") 1612}; 1613 1614 1615class LNumberUntagD: public LTemplateInstruction<1, 1, 0> { 1616 public: 1617 explicit LNumberUntagD(LOperand* value) { 1618 inputs_[0] = value; 1619 } 1620 1621 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") 1622 DECLARE_HYDROGEN_ACCESSOR(Change) 1623}; 1624 1625 1626class LSmiUntag: public LTemplateInstruction<1, 1, 0> { 1627 public: 1628 LSmiUntag(LOperand* value, bool needs_check) 1629 : needs_check_(needs_check) { 1630 inputs_[0] = value; 1631 } 1632 1633 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") 1634 1635 bool needs_check() const { return needs_check_; } 1636 1637 private: 1638 bool needs_check_; 1639}; 1640 1641 1642class LStoreNamedField: public LTemplateInstruction<0, 2, 0> { 1643 public: 1644 LStoreNamedField(LOperand* obj, LOperand* val) { 1645 inputs_[0] = obj; 1646 inputs_[1] = val; 1647 } 1648 1649 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field") 1650 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField) 1651 1652 virtual void PrintDataTo(StringStream* stream); 1653 1654 LOperand* object() { return inputs_[0]; } 1655 LOperand* value() { return inputs_[1]; } 1656 1657 Handle<Object> name() const { return hydrogen()->name(); } 1658 bool is_in_object() { return hydrogen()->is_in_object(); } 1659 int offset() { return hydrogen()->offset(); } 1660 Handle<Map> transition() const { return hydrogen()->transition(); } 1661}; 1662 1663 1664class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> { 1665 public: 1666 LStoreNamedGeneric(LOperand* obj, LOperand* val) { 1667 inputs_[0] = obj; 1668 inputs_[1] = val; 1669 } 1670 1671 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic") 1672 DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric) 1673 1674 virtual void PrintDataTo(StringStream* stream); 1675 1676 LOperand* object() { return inputs_[0]; } 1677 LOperand* value() { return inputs_[1]; } 1678 Handle<Object> name() const { return hydrogen()->name(); } 1679 StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } 1680}; 1681 1682 1683class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> { 1684 public: 1685 LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val) { 1686 inputs_[0] = obj; 1687 inputs_[1] = key; 1688 inputs_[2] = val; 1689 } 1690 1691 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement, 1692 "store-keyed-fast-element") 1693 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement) 1694 1695 virtual void PrintDataTo(StringStream* stream); 1696 1697 LOperand* object() { return inputs_[0]; } 1698 LOperand* key() { return inputs_[1]; } 1699 LOperand* value() { return inputs_[2]; } 1700}; 1701 1702 1703class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { 1704 public: 1705 LStoreKeyedFastDoubleElement(LOperand* elements, 1706 LOperand* key, 1707 LOperand* val) { 1708 inputs_[0] = elements; 1709 inputs_[1] = key; 1710 inputs_[2] = val; 1711 } 1712 1713 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement, 1714 "store-keyed-fast-double-element") 1715 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement) 1716 1717 virtual void PrintDataTo(StringStream* stream); 1718 1719 LOperand* elements() { return inputs_[0]; } 1720 LOperand* key() { return inputs_[1]; } 1721 LOperand* value() { return inputs_[2]; } 1722}; 1723 1724 1725class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> { 1726 public: 1727 LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val) { 1728 inputs_[0] = obj; 1729 inputs_[1] = key; 1730 inputs_[2] = val; 1731 } 1732 1733 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic") 1734 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric) 1735 1736 virtual void PrintDataTo(StringStream* stream); 1737 1738 LOperand* object() { return inputs_[0]; } 1739 LOperand* key() { return inputs_[1]; } 1740 LOperand* value() { return inputs_[2]; } 1741 StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } 1742}; 1743 1744class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> { 1745 public: 1746 LStoreKeyedSpecializedArrayElement(LOperand* external_pointer, 1747 LOperand* key, 1748 LOperand* val) { 1749 inputs_[0] = external_pointer; 1750 inputs_[1] = key; 1751 inputs_[2] = val; 1752 } 1753 1754 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement, 1755 "store-keyed-specialized-array-element") 1756 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement) 1757 1758 LOperand* external_pointer() { return inputs_[0]; } 1759 LOperand* key() { return inputs_[1]; } 1760 LOperand* value() { return inputs_[2]; } 1761 ElementsKind elements_kind() const { 1762 return hydrogen()->elements_kind(); 1763 } 1764}; 1765 1766 1767class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> { 1768 public: 1769 LTransitionElementsKind(LOperand* object, 1770 LOperand* new_map_temp, 1771 LOperand* temp_reg) { 1772 inputs_[0] = object; 1773 temps_[0] = new_map_temp; 1774 temps_[1] = temp_reg; 1775 } 1776 1777 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind, 1778 "transition-elements-kind") 1779 DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind) 1780 1781 virtual void PrintDataTo(StringStream* stream); 1782 1783 LOperand* object() { return inputs_[0]; } 1784 LOperand* new_map_reg() { return temps_[0]; } 1785 LOperand* temp_reg() { return temps_[1]; } 1786 Handle<Map> original_map() { return hydrogen()->original_map(); } 1787 Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); } 1788}; 1789 1790 1791class LStringAdd: public LTemplateInstruction<1, 2, 0> { 1792 public: 1793 LStringAdd(LOperand* left, LOperand* right) { 1794 inputs_[0] = left; 1795 inputs_[1] = right; 1796 } 1797 1798 DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add") 1799 DECLARE_HYDROGEN_ACCESSOR(StringAdd) 1800 1801 LOperand* left() { return inputs_[0]; } 1802 LOperand* right() { return inputs_[1]; } 1803}; 1804 1805 1806 1807class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> { 1808 public: 1809 LStringCharCodeAt(LOperand* string, LOperand* index) { 1810 inputs_[0] = string; 1811 inputs_[1] = index; 1812 } 1813 1814 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at") 1815 DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt) 1816 1817 LOperand* string() { return inputs_[0]; } 1818 LOperand* index() { return inputs_[1]; } 1819}; 1820 1821 1822class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> { 1823 public: 1824 explicit LStringCharFromCode(LOperand* char_code) { 1825 inputs_[0] = char_code; 1826 } 1827 1828 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code") 1829 DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode) 1830 1831 LOperand* char_code() { return inputs_[0]; } 1832}; 1833 1834 1835class LStringLength: public LTemplateInstruction<1, 1, 0> { 1836 public: 1837 explicit LStringLength(LOperand* string) { 1838 inputs_[0] = string; 1839 } 1840 1841 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length") 1842 DECLARE_HYDROGEN_ACCESSOR(StringLength) 1843 1844 LOperand* string() { return inputs_[0]; } 1845}; 1846 1847 1848class LCheckFunction: public LTemplateInstruction<0, 1, 0> { 1849 public: 1850 explicit LCheckFunction(LOperand* value) { 1851 inputs_[0] = value; 1852 } 1853 1854 LOperand* value() { return InputAt(0); } 1855 1856 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function") 1857 DECLARE_HYDROGEN_ACCESSOR(CheckFunction) 1858}; 1859 1860 1861class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> { 1862 public: 1863 explicit LCheckInstanceType(LOperand* value) { 1864 inputs_[0] = value; 1865 } 1866 1867 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type") 1868 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType) 1869}; 1870 1871 1872class LCheckMap: public LTemplateInstruction<0, 1, 0> { 1873 public: 1874 explicit LCheckMap(LOperand* value) { 1875 inputs_[0] = value; 1876 } 1877 1878 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map") 1879 DECLARE_HYDROGEN_ACCESSOR(CheckMap) 1880}; 1881 1882 1883class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 2> { 1884 public: 1885 LCheckPrototypeMaps(LOperand* temp1, LOperand* temp2) { 1886 temps_[0] = temp1; 1887 temps_[1] = temp2; 1888 } 1889 1890 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps") 1891 DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps) 1892 1893 Handle<JSObject> prototype() const { return hydrogen()->prototype(); } 1894 Handle<JSObject> holder() const { return hydrogen()->holder(); } 1895}; 1896 1897 1898class LCheckSmi: public LTemplateInstruction<0, 1, 0> { 1899 public: 1900 explicit LCheckSmi(LOperand* value) { 1901 inputs_[0] = value; 1902 } 1903 1904 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi") 1905}; 1906 1907 1908class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> { 1909 public: 1910 explicit LCheckNonSmi(LOperand* value) { 1911 inputs_[0] = value; 1912 } 1913 1914 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi") 1915}; 1916 1917 1918class LClampDToUint8: public LTemplateInstruction<1, 1, 1> { 1919 public: 1920 LClampDToUint8(LOperand* value, LOperand* temp) { 1921 inputs_[0] = value; 1922 temps_[0] = temp; 1923 } 1924 1925 LOperand* unclamped() { return inputs_[0]; } 1926 1927 DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8") 1928}; 1929 1930 1931class LClampIToUint8: public LTemplateInstruction<1, 1, 0> { 1932 public: 1933 explicit LClampIToUint8(LOperand* value) { 1934 inputs_[0] = value; 1935 } 1936 1937 LOperand* unclamped() { return inputs_[0]; } 1938 1939 DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8") 1940}; 1941 1942 1943class LClampTToUint8: public LTemplateInstruction<1, 1, 1> { 1944 public: 1945 LClampTToUint8(LOperand* value, LOperand* temp) { 1946 inputs_[0] = value; 1947 temps_[0] = temp; 1948 } 1949 1950 LOperand* unclamped() { return inputs_[0]; } 1951 1952 DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8") 1953}; 1954 1955 1956class LAllocateObject: public LTemplateInstruction<1, 0, 2> { 1957 public: 1958 LAllocateObject(LOperand* temp1, LOperand* temp2) { 1959 temps_[0] = temp1; 1960 temps_[1] = temp2; 1961 } 1962 1963 DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object") 1964 DECLARE_HYDROGEN_ACCESSOR(AllocateObject) 1965}; 1966 1967 1968class LFastLiteral: public LTemplateInstruction<1, 0, 0> { 1969 public: 1970 DECLARE_CONCRETE_INSTRUCTION(FastLiteral, "fast-literal") 1971 DECLARE_HYDROGEN_ACCESSOR(FastLiteral) 1972}; 1973 1974 1975class LArrayLiteral: public LTemplateInstruction<1, 0, 0> { 1976 public: 1977 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal") 1978 DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral) 1979}; 1980 1981 1982class LObjectLiteral: public LTemplateInstruction<1, 0, 0> { 1983 public: 1984 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal") 1985 DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral) 1986}; 1987 1988 1989class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> { 1990 public: 1991 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal") 1992 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral) 1993}; 1994 1995 1996class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> { 1997 public: 1998 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal") 1999 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral) 2000 2001 Handle<SharedFunctionInfo> shared_info() { return hydrogen()->shared_info(); } 2002}; 2003 2004 2005class LToFastProperties: public LTemplateInstruction<1, 1, 0> { 2006 public: 2007 explicit LToFastProperties(LOperand* value) { 2008 inputs_[0] = value; 2009 } 2010 2011 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties") 2012 DECLARE_HYDROGEN_ACCESSOR(ToFastProperties) 2013}; 2014 2015 2016class LTypeof: public LTemplateInstruction<1, 1, 0> { 2017 public: 2018 explicit LTypeof(LOperand* value) { 2019 inputs_[0] = value; 2020 } 2021 2022 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof") 2023}; 2024 2025 2026class LTypeofIsAndBranch: public LControlInstruction<1, 0> { 2027 public: 2028 explicit LTypeofIsAndBranch(LOperand* value) { 2029 inputs_[0] = value; 2030 } 2031 2032 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch") 2033 DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch) 2034 2035 Handle<String> type_literal() { return hydrogen()->type_literal(); } 2036 2037 virtual void PrintDataTo(StringStream* stream); 2038}; 2039 2040 2041class LIsConstructCallAndBranch: public LControlInstruction<0, 1> { 2042 public: 2043 explicit LIsConstructCallAndBranch(LOperand* temp) { 2044 temps_[0] = temp; 2045 } 2046 2047 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch, 2048 "is-construct-call-and-branch") 2049}; 2050 2051 2052class LDeleteProperty: public LTemplateInstruction<1, 2, 0> { 2053 public: 2054 LDeleteProperty(LOperand* obj, LOperand* key) { 2055 inputs_[0] = obj; 2056 inputs_[1] = key; 2057 } 2058 2059 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property") 2060 2061 LOperand* object() { return inputs_[0]; } 2062 LOperand* key() { return inputs_[1]; } 2063}; 2064 2065 2066class LOsrEntry: public LTemplateInstruction<0, 0, 0> { 2067 public: 2068 LOsrEntry(); 2069 2070 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") 2071 2072 LOperand** SpilledRegisterArray() { return register_spills_; } 2073 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; } 2074 2075 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand); 2076 void MarkSpilledDoubleRegister(int allocation_index, 2077 LOperand* spill_operand); 2078 2079 private: 2080 // Arrays of spill slot operands for registers with an assigned spill 2081 // slot, i.e., that must also be restored to the spill slot on OSR entry. 2082 // NULL if the register has no assigned spill slot. Indexed by allocation 2083 // index. 2084 LOperand* register_spills_[Register::kNumAllocatableRegisters]; 2085 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters]; 2086}; 2087 2088 2089class LStackCheck: public LTemplateInstruction<0, 0, 0> { 2090 public: 2091 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check") 2092 DECLARE_HYDROGEN_ACCESSOR(StackCheck) 2093 2094 Label* done_label() { return &done_label_; } 2095 2096 private: 2097 Label done_label_; 2098}; 2099 2100 2101class LIn: public LTemplateInstruction<1, 2, 0> { 2102 public: 2103 LIn(LOperand* key, LOperand* object) { 2104 inputs_[0] = key; 2105 inputs_[1] = object; 2106 } 2107 2108 LOperand* key() { return inputs_[0]; } 2109 LOperand* object() { return inputs_[1]; } 2110 2111 DECLARE_CONCRETE_INSTRUCTION(In, "in") 2112}; 2113 2114 2115class LForInPrepareMap: public LTemplateInstruction<1, 1, 0> { 2116 public: 2117 explicit LForInPrepareMap(LOperand* object) { 2118 inputs_[0] = object; 2119 } 2120 2121 LOperand* object() { return inputs_[0]; } 2122 2123 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map") 2124}; 2125 2126 2127class LForInCacheArray: public LTemplateInstruction<1, 1, 0> { 2128 public: 2129 explicit LForInCacheArray(LOperand* map) { 2130 inputs_[0] = map; 2131 } 2132 2133 LOperand* map() { return inputs_[0]; } 2134 2135 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array") 2136 2137 int idx() { 2138 return HForInCacheArray::cast(this->hydrogen_value())->idx(); 2139 } 2140}; 2141 2142 2143class LCheckMapValue: public LTemplateInstruction<0, 2, 0> { 2144 public: 2145 LCheckMapValue(LOperand* value, LOperand* map) { 2146 inputs_[0] = value; 2147 inputs_[1] = map; 2148 } 2149 2150 LOperand* value() { return inputs_[0]; } 2151 LOperand* map() { return inputs_[1]; } 2152 2153 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value") 2154}; 2155 2156 2157class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> { 2158 public: 2159 LLoadFieldByIndex(LOperand* object, LOperand* index) { 2160 inputs_[0] = object; 2161 inputs_[1] = index; 2162 } 2163 2164 LOperand* object() { return inputs_[0]; } 2165 LOperand* index() { return inputs_[1]; } 2166 2167 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index") 2168}; 2169 2170 2171class LChunkBuilder; 2172class LChunk: public ZoneObject { 2173 public: 2174 explicit LChunk(CompilationInfo* info, HGraph* graph); 2175 2176 void AddInstruction(LInstruction* instruction, HBasicBlock* block); 2177 LConstantOperand* DefineConstantOperand(HConstant* constant); 2178 Handle<Object> LookupLiteral(LConstantOperand* operand) const; 2179 Representation LookupLiteralRepresentation(LConstantOperand* operand) const; 2180 2181 int GetNextSpillIndex(bool is_double); 2182 LOperand* GetNextSpillSlot(bool is_double); 2183 2184 int ParameterAt(int index); 2185 int GetParameterStackSlot(int index) const; 2186 int spill_slot_count() const { return spill_slot_count_; } 2187 CompilationInfo* info() const { return info_; } 2188 HGraph* graph() const { return graph_; } 2189 const ZoneList<LInstruction*>* instructions() const { return &instructions_; } 2190 void AddGapMove(int index, LOperand* from, LOperand* to); 2191 LGap* GetGapAt(int index) const; 2192 bool IsGapAt(int index) const; 2193 int NearestGapPos(int index) const; 2194 void MarkEmptyBlocks(); 2195 const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; } 2196 LLabel* GetLabel(int block_id) const { 2197 HBasicBlock* block = graph_->blocks()->at(block_id); 2198 int first_instruction = block->first_instruction_index(); 2199 return LLabel::cast(instructions_[first_instruction]); 2200 } 2201 int LookupDestination(int block_id) const { 2202 LLabel* cur = GetLabel(block_id); 2203 while (cur->replacement() != NULL) { 2204 cur = cur->replacement(); 2205 } 2206 return cur->block_id(); 2207 } 2208 Label* GetAssemblyLabel(int block_id) const { 2209 LLabel* label = GetLabel(block_id); 2210 ASSERT(!label->HasReplacement()); 2211 return label->label(); 2212 } 2213 2214 const ZoneList<Handle<JSFunction> >* inlined_closures() const { 2215 return &inlined_closures_; 2216 } 2217 2218 void AddInlinedClosure(Handle<JSFunction> closure) { 2219 inlined_closures_.Add(closure); 2220 } 2221 2222 private: 2223 int spill_slot_count_; 2224 CompilationInfo* info_; 2225 HGraph* const graph_; 2226 ZoneList<LInstruction*> instructions_; 2227 ZoneList<LPointerMap*> pointer_maps_; 2228 ZoneList<Handle<JSFunction> > inlined_closures_; 2229}; 2230 2231 2232class LChunkBuilder BASE_EMBEDDED { 2233 public: 2234 LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator) 2235 : chunk_(NULL), 2236 info_(info), 2237 graph_(graph), 2238 zone_(graph->isolate()->zone()), 2239 status_(UNUSED), 2240 current_instruction_(NULL), 2241 current_block_(NULL), 2242 next_block_(NULL), 2243 argument_count_(0), 2244 allocator_(allocator), 2245 position_(RelocInfo::kNoPosition), 2246 instruction_pending_deoptimization_environment_(NULL), 2247 pending_deoptimization_ast_id_(AstNode::kNoNumber) { } 2248 2249 // Build the sequence for the graph. 2250 LChunk* Build(); 2251 2252 // Declare methods that deal with the individual node types. 2253#define DECLARE_DO(type) LInstruction* Do##type(H##type* node); 2254 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 2255#undef DECLARE_DO 2256 2257 private: 2258 enum Status { 2259 UNUSED, 2260 BUILDING, 2261 DONE, 2262 ABORTED 2263 }; 2264 2265 LChunk* chunk() const { return chunk_; } 2266 CompilationInfo* info() const { return info_; } 2267 HGraph* graph() const { return graph_; } 2268 Zone* zone() const { return zone_; } 2269 2270 bool is_unused() const { return status_ == UNUSED; } 2271 bool is_building() const { return status_ == BUILDING; } 2272 bool is_done() const { return status_ == DONE; } 2273 bool is_aborted() const { return status_ == ABORTED; } 2274 2275 void Abort(const char* format, ...); 2276 2277 // Methods for getting operands for Use / Define / Temp. 2278 LUnallocated* ToUnallocated(Register reg); 2279 LUnallocated* ToUnallocated(DoubleRegister reg); 2280 2281 // Methods for setting up define-use relationships. 2282 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); 2283 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register); 2284 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value, 2285 DoubleRegister fixed_register); 2286 2287 // A value that is guaranteed to be allocated to a register. 2288 // Operand created by UseRegister is guaranteed to be live until the end of 2289 // instruction. This means that register allocator will not reuse it's 2290 // register for any other operand inside instruction. 2291 // Operand created by UseRegisterAtStart is guaranteed to be live only at 2292 // instruction start. Register allocator is free to assign the same register 2293 // to some other operand used inside instruction (i.e. temporary or 2294 // output). 2295 MUST_USE_RESULT LOperand* UseRegister(HValue* value); 2296 MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value); 2297 2298 // An input operand in a register that may be trashed. 2299 MUST_USE_RESULT LOperand* UseTempRegister(HValue* value); 2300 2301 // An input operand in a register or stack slot. 2302 MUST_USE_RESULT LOperand* Use(HValue* value); 2303 MUST_USE_RESULT LOperand* UseAtStart(HValue* value); 2304 2305 // An input operand in a register, stack slot or a constant operand. 2306 MUST_USE_RESULT LOperand* UseOrConstant(HValue* value); 2307 MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value); 2308 2309 // An input operand in a register or a constant operand. 2310 MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value); 2311 MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value); 2312 2313 // An input operand in register, stack slot or a constant operand. 2314 // Will not be moved to a register even if one is freely available. 2315 MUST_USE_RESULT LOperand* UseAny(HValue* value); 2316 2317 // Temporary operand that must be in a register. 2318 MUST_USE_RESULT LUnallocated* TempRegister(); 2319 MUST_USE_RESULT LOperand* FixedTemp(Register reg); 2320 MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg); 2321 2322 // Methods for setting up define-use relationships. 2323 // Return the same instruction that they are passed. 2324 template<int I, int T> 2325 LInstruction* Define(LTemplateInstruction<1, I, T>* instr, 2326 LUnallocated* result); 2327 template<int I, int T> 2328 LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr); 2329 template<int I, int T> 2330 LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr, 2331 int index); 2332 template<int I, int T> 2333 LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr); 2334 template<int I, int T> 2335 LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr, 2336 Register reg); 2337 template<int I, int T> 2338 LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr, 2339 DoubleRegister reg); 2340 LInstruction* AssignEnvironment(LInstruction* instr); 2341 LInstruction* AssignPointerMap(LInstruction* instr); 2342 2343 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY }; 2344 2345 // By default we assume that instruction sequences generated for calls 2346 // cannot deoptimize eagerly and we do not attach environment to this 2347 // instruction. 2348 LInstruction* MarkAsCall( 2349 LInstruction* instr, 2350 HInstruction* hinstr, 2351 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); 2352 LInstruction* MarkAsSaveDoubles(LInstruction* instr); 2353 2354 LInstruction* SetInstructionPendingDeoptimizationEnvironment( 2355 LInstruction* instr, int ast_id); 2356 void ClearInstructionPendingDeoptimizationEnvironment(); 2357 2358 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env, 2359 int* argument_index_accumulator); 2360 2361 void VisitInstruction(HInstruction* current); 2362 2363 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); 2364 LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr); 2365 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); 2366 LInstruction* DoArithmeticD(Token::Value op, 2367 HArithmeticBinaryOperation* instr); 2368 LInstruction* DoArithmeticT(Token::Value op, 2369 HArithmeticBinaryOperation* instr); 2370 2371 LChunk* chunk_; 2372 CompilationInfo* info_; 2373 HGraph* const graph_; 2374 Zone* zone_; 2375 Status status_; 2376 HInstruction* current_instruction_; 2377 HBasicBlock* current_block_; 2378 HBasicBlock* next_block_; 2379 int argument_count_; 2380 LAllocator* allocator_; 2381 int position_; 2382 LInstruction* instruction_pending_deoptimization_environment_; 2383 int pending_deoptimization_ast_id_; 2384 2385 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); 2386}; 2387 2388#undef DECLARE_HYDROGEN_ACCESSOR 2389#undef DECLARE_CONCRETE_INSTRUCTION 2390 2391} } // namespace v8::internal 2392 2393#endif // V8_MIPS_LITHIUM_MIPS_H_ 2394