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