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