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