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