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