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