| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #if defined(V8_TARGET_ARCH_X64) | 30 #if defined(V8_TARGET_ARCH_X64) |
| 31 | 31 |
| 32 #include "lithium-allocator-inl.h" |
| 32 #include "x64/lithium-x64.h" | 33 #include "x64/lithium-x64.h" |
| 33 #include "x64/lithium-codegen-x64.h" | 34 #include "x64/lithium-codegen-x64.h" |
| 34 | 35 |
| 35 namespace v8 { | 36 namespace v8 { |
| 36 namespace internal { | 37 namespace internal { |
| 37 | 38 |
| 38 #define DEFINE_COMPILE(type) \ | 39 #define DEFINE_COMPILE(type) \ |
| 39 void L##type::CompileToNative(LCodeGen* generator) { \ | 40 void L##type::CompileToNative(LCodeGen* generator) { \ |
| 40 generator->Do##type(this); \ | 41 generator->Do##type(this); \ |
| 41 } | 42 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 61 | 62 |
| 62 | 63 |
| 63 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, | 64 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, |
| 64 LOperand* spill_operand) { | 65 LOperand* spill_operand) { |
| 65 ASSERT(spill_operand->IsDoubleStackSlot()); | 66 ASSERT(spill_operand->IsDoubleStackSlot()); |
| 66 ASSERT(double_register_spills_[allocation_index] == NULL); | 67 ASSERT(double_register_spills_[allocation_index] == NULL); |
| 67 double_register_spills_[allocation_index] = spill_operand; | 68 double_register_spills_[allocation_index] = spill_operand; |
| 68 } | 69 } |
| 69 | 70 |
| 70 | 71 |
| 72 #ifdef DEBUG |
| 73 void LInstruction::VerifyCall() { |
| 74 // Call instructions can use only fixed registers as |
| 75 // temporaries and outputs because all registers |
| 76 // are blocked by the calling convention. |
| 77 // Inputs can use either fixed register or have a short lifetime (be |
| 78 // used at start of the instruction). |
| 79 ASSERT(Output() == NULL || |
| 80 LUnallocated::cast(Output())->HasFixedPolicy() || |
| 81 !LUnallocated::cast(Output())->HasRegisterPolicy()); |
| 82 for (UseIterator it(this); it.HasNext(); it.Advance()) { |
| 83 LOperand* operand = it.Next(); |
| 84 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || |
| 85 LUnallocated::cast(operand)->IsUsedAtStart() || |
| 86 !LUnallocated::cast(operand)->HasRegisterPolicy()); |
| 87 } |
| 88 for (TempIterator it(this); it.HasNext(); it.Advance()) { |
| 89 LOperand* operand = it.Next(); |
| 90 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || |
| 91 !LUnallocated::cast(operand)->HasRegisterPolicy()); |
| 92 } |
| 93 } |
| 94 #endif |
| 95 |
| 96 |
| 71 void LInstruction::PrintTo(StringStream* stream) { | 97 void LInstruction::PrintTo(StringStream* stream) { |
| 72 stream->Add("%s ", this->Mnemonic()); | 98 stream->Add("%s ", this->Mnemonic()); |
| 73 if (HasResult()) { | 99 |
| 74 PrintOutputOperandTo(stream); | 100 PrintOutputOperandTo(stream); |
| 75 } | |
| 76 | 101 |
| 77 PrintDataTo(stream); | 102 PrintDataTo(stream); |
| 78 | 103 |
| 79 if (HasEnvironment()) { | 104 if (HasEnvironment()) { |
| 80 stream->Add(" "); | 105 stream->Add(" "); |
| 81 environment()->PrintTo(stream); | 106 environment()->PrintTo(stream); |
| 82 } | 107 } |
| 83 | 108 |
| 84 if (HasPointerMap()) { | 109 if (HasPointerMap()) { |
| 85 stream->Add(" "); | 110 stream->Add(" "); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 } | 180 } |
| 156 | 181 |
| 157 | 182 |
| 158 const char* LArithmeticT::Mnemonic() const { | 183 const char* LArithmeticT::Mnemonic() const { |
| 159 switch (op()) { | 184 switch (op()) { |
| 160 case Token::ADD: return "add-t"; | 185 case Token::ADD: return "add-t"; |
| 161 case Token::SUB: return "sub-t"; | 186 case Token::SUB: return "sub-t"; |
| 162 case Token::MUL: return "mul-t"; | 187 case Token::MUL: return "mul-t"; |
| 163 case Token::MOD: return "mod-t"; | 188 case Token::MOD: return "mod-t"; |
| 164 case Token::DIV: return "div-t"; | 189 case Token::DIV: return "div-t"; |
| 190 case Token::BIT_AND: return "bit-and-t"; |
| 191 case Token::BIT_OR: return "bit-or-t"; |
| 192 case Token::BIT_XOR: return "bit-xor-t"; |
| 193 case Token::SHL: return "sal-t"; |
| 194 case Token::SAR: return "sar-t"; |
| 195 case Token::SHR: return "shr-t"; |
| 165 default: | 196 default: |
| 166 UNREACHABLE(); | 197 UNREACHABLE(); |
| 167 return NULL; | 198 return NULL; |
| 168 } | 199 } |
| 169 } | 200 } |
| 170 | 201 |
| 171 | 202 |
| 172 void LGoto::PrintDataTo(StringStream* stream) { | 203 void LGoto::PrintDataTo(StringStream* stream) { |
| 173 stream->Add("B%d", block_id()); | 204 stream->Add("B%d", block_id()); |
| 174 } | 205 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 } | 286 } |
| 256 | 287 |
| 257 | 288 |
| 258 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { | 289 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { |
| 259 stream->Add("/%s ", hydrogen()->OpName()); | 290 stream->Add("/%s ", hydrogen()->OpName()); |
| 260 InputAt(0)->PrintTo(stream); | 291 InputAt(0)->PrintTo(stream); |
| 261 } | 292 } |
| 262 | 293 |
| 263 | 294 |
| 264 void LLoadContextSlot::PrintDataTo(StringStream* stream) { | 295 void LLoadContextSlot::PrintDataTo(StringStream* stream) { |
| 265 stream->Add("(%d, %d)", context_chain_length(), slot_index()); | 296 InputAt(0)->PrintTo(stream); |
| 297 stream->Add("[%d]", slot_index()); |
| 266 } | 298 } |
| 267 | 299 |
| 268 | 300 |
| 269 void LCallKeyed::PrintDataTo(StringStream* stream) { | 301 void LCallKeyed::PrintDataTo(StringStream* stream) { |
| 270 stream->Add("[ecx] #%d / ", arity()); | 302 stream->Add("[ecx] #%d / ", arity()); |
| 271 } | 303 } |
| 272 | 304 |
| 273 | 305 |
| 274 void LCallNamed::PrintDataTo(StringStream* stream) { | 306 void LCallNamed::PrintDataTo(StringStream* stream) { |
| 275 SmartPointer<char> name_string = name()->ToCString(); | 307 SmartPointer<char> name_string = name()->ToCString(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 stream->Add(" index "); | 343 stream->Add(" index "); |
| 312 index()->PrintTo(stream); | 344 index()->PrintTo(stream); |
| 313 } | 345 } |
| 314 | 346 |
| 315 | 347 |
| 316 int LChunk::GetNextSpillIndex(bool is_double) { | 348 int LChunk::GetNextSpillIndex(bool is_double) { |
| 317 return spill_slot_count_++; | 349 return spill_slot_count_++; |
| 318 } | 350 } |
| 319 | 351 |
| 320 | 352 |
| 321 LOperand* LChunk::GetNextSpillSlot(bool is_double) { | 353 LOperand* LChunk::GetNextSpillSlot(bool is_double) { |
| 322 // All stack slots are Double stack slots on x64. | 354 // All stack slots are Double stack slots on x64. |
| 323 // Alternatively, at some point, start using half-size | 355 // Alternatively, at some point, start using half-size |
| 324 // stack slots for int32 values. | 356 // stack slots for int32 values. |
| 325 int index = GetNextSpillIndex(is_double); | 357 int index = GetNextSpillIndex(is_double); |
| 326 if (is_double) { | 358 if (is_double) { |
| 327 return LDoubleStackSlot::Create(index); | 359 return LDoubleStackSlot::Create(index); |
| 328 } else { | 360 } else { |
| 329 return LStackSlot::Create(index); | 361 return LStackSlot::Create(index); |
| 330 } | 362 } |
| 331 } | 363 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 | 411 |
| 380 void LStoreKeyed::PrintDataTo(StringStream* stream) { | 412 void LStoreKeyed::PrintDataTo(StringStream* stream) { |
| 381 object()->PrintTo(stream); | 413 object()->PrintTo(stream); |
| 382 stream->Add("["); | 414 stream->Add("["); |
| 383 key()->PrintTo(stream); | 415 key()->PrintTo(stream); |
| 384 stream->Add("] <- "); | 416 stream->Add("] <- "); |
| 385 value()->PrintTo(stream); | 417 value()->PrintTo(stream); |
| 386 } | 418 } |
| 387 | 419 |
| 388 | 420 |
| 389 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { | 421 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { |
| 390 LGap* gap = new LGap(block); | 422 LGap* gap = new LGap(block); |
| 391 int index = -1; | 423 int index = -1; |
| 392 if (instr->IsControl()) { | 424 if (instr->IsControl()) { |
| 393 instructions_.Add(gap); | 425 instructions_.Add(gap); |
| 394 index = instructions_.length(); | 426 index = instructions_.length(); |
| 395 instructions_.Add(instr); | 427 instructions_.Add(instr); |
| 396 } else { | 428 } else { |
| 397 index = instructions_.length(); | 429 index = instructions_.length(); |
| 398 instructions_.Add(instr); | 430 instructions_.Add(instr); |
| 399 instructions_.Add(gap); | 431 instructions_.Add(gap); |
| 400 } | 432 } |
| 401 if (instr->HasPointerMap()) { | 433 if (instr->HasPointerMap()) { |
| 402 pointer_maps_.Add(instr->pointer_map()); | 434 pointer_maps_.Add(instr->pointer_map()); |
| 403 instr->pointer_map()->set_lithium_position(index); | 435 instr->pointer_map()->set_lithium_position(index); |
| 404 } | 436 } |
| 405 return index; | |
| 406 } | 437 } |
| 407 | 438 |
| 408 | 439 |
| 409 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { | 440 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { |
| 410 return LConstantOperand::Create(constant->id()); | 441 return LConstantOperand::Create(constant->id()); |
| 411 } | 442 } |
| 412 | 443 |
| 413 | 444 |
| 414 int LChunk::GetParameterStackSlot(int index) const { | 445 int LChunk::GetParameterStackSlot(int index) const { |
| 415 // The receiver is at index 0, the first parameter at index 1, so we | 446 // The receiver is at index 0, the first parameter at index 1, so we |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 | 677 |
| 647 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { | 678 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { |
| 648 HEnvironment* hydrogen_env = current_block_->last_environment(); | 679 HEnvironment* hydrogen_env = current_block_->last_environment(); |
| 649 instr->set_environment(CreateEnvironment(hydrogen_env)); | 680 instr->set_environment(CreateEnvironment(hydrogen_env)); |
| 650 return instr; | 681 return instr; |
| 651 } | 682 } |
| 652 | 683 |
| 653 | 684 |
| 654 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( | 685 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( |
| 655 LInstruction* instr, int ast_id) { | 686 LInstruction* instr, int ast_id) { |
| 656 ASSERT(instructions_pending_deoptimization_environment_ == NULL); | 687 ASSERT(instruction_pending_deoptimization_environment_ == NULL); |
| 657 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); | 688 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); |
| 658 instructions_pending_deoptimization_environment_ = instr; | 689 instruction_pending_deoptimization_environment_ = instr; |
| 659 pending_deoptimization_ast_id_ = ast_id; | 690 pending_deoptimization_ast_id_ = ast_id; |
| 660 return instr; | 691 return instr; |
| 661 } | 692 } |
| 662 | 693 |
| 663 | 694 |
| 664 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { | 695 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { |
| 665 instructions_pending_deoptimization_environment_ = NULL; | 696 instruction_pending_deoptimization_environment_ = NULL; |
| 666 pending_deoptimization_ast_id_ = AstNode::kNoNumber; | 697 pending_deoptimization_ast_id_ = AstNode::kNoNumber; |
| 667 } | 698 } |
| 668 | 699 |
| 669 | 700 |
| 670 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, | 701 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, |
| 671 HInstruction* hinstr, | 702 HInstruction* hinstr, |
| 672 CanDeoptimize can_deoptimize) { | 703 CanDeoptimize can_deoptimize) { |
| 673 allocator_->MarkAsCall(); | 704 #ifdef DEBUG |
| 705 instr->VerifyCall(); |
| 706 #endif |
| 707 instr->MarkAsCall(); |
| 674 instr = AssignPointerMap(instr); | 708 instr = AssignPointerMap(instr); |
| 675 | 709 |
| 676 if (hinstr->HasSideEffects()) { | 710 if (hinstr->HasSideEffects()) { |
| 677 ASSERT(hinstr->next()->IsSimulate()); | 711 ASSERT(hinstr->next()->IsSimulate()); |
| 678 HSimulate* sim = HSimulate::cast(hinstr->next()); | 712 HSimulate* sim = HSimulate::cast(hinstr->next()); |
| 679 instr = SetInstructionPendingDeoptimizationEnvironment( | 713 instr = SetInstructionPendingDeoptimizationEnvironment( |
| 680 instr, sim->ast_id()); | 714 instr, sim->ast_id()); |
| 681 } | 715 } |
| 682 | 716 |
| 683 // If instruction does not have side-effects lazy deoptimization | 717 // If instruction does not have side-effects lazy deoptimization |
| 684 // after the call will try to deoptimize to the point before the call. | 718 // after the call will try to deoptimize to the point before the call. |
| 685 // Thus we still need to attach environment to this call even if | 719 // Thus we still need to attach environment to this call even if |
| 686 // call sequence can not deoptimize eagerly. | 720 // call sequence can not deoptimize eagerly. |
| 687 bool needs_environment = | 721 bool needs_environment = |
| 688 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); | 722 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); |
| 689 if (needs_environment && !instr->HasEnvironment()) { | 723 if (needs_environment && !instr->HasEnvironment()) { |
| 690 instr = AssignEnvironment(instr); | 724 instr = AssignEnvironment(instr); |
| 691 } | 725 } |
| 692 | 726 |
| 693 return instr; | 727 return instr; |
| 694 } | 728 } |
| 695 | 729 |
| 696 | 730 |
| 697 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { | 731 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { |
| 698 allocator_->MarkAsSaveDoubles(); | 732 instr->MarkAsSaveDoubles(); |
| 699 return instr; | 733 return instr; |
| 700 } | 734 } |
| 701 | 735 |
| 702 | 736 |
| 703 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 737 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
| 704 ASSERT(!instr->HasPointerMap()); | 738 ASSERT(!instr->HasPointerMap()); |
| 705 instr->set_pointer_map(new LPointerMap(position_)); | 739 instr->set_pointer_map(new LPointerMap(position_)); |
| 706 return instr; | 740 return instr; |
| 707 } | 741 } |
| 708 | 742 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 733 } | 767 } |
| 734 | 768 |
| 735 | 769 |
| 736 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 770 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 737 return AssignEnvironment(new LDeoptimize); | 771 return AssignEnvironment(new LDeoptimize); |
| 738 } | 772 } |
| 739 | 773 |
| 740 | 774 |
| 741 LInstruction* LChunkBuilder::DoBit(Token::Value op, | 775 LInstruction* LChunkBuilder::DoBit(Token::Value op, |
| 742 HBitwiseBinaryOperation* instr) { | 776 HBitwiseBinaryOperation* instr) { |
| 743 Abort("Unimplemented: %s", "DoBit"); | 777 if (instr->representation().IsInteger32()) { |
| 744 return NULL; | 778 ASSERT(instr->left()->representation().IsInteger32()); |
| 779 ASSERT(instr->right()->representation().IsInteger32()); |
| 780 |
| 781 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 782 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); |
| 783 return DefineSameAsFirst(new LBitI(op, left, right)); |
| 784 } else { |
| 785 ASSERT(instr->representation().IsTagged()); |
| 786 ASSERT(instr->left()->representation().IsTagged()); |
| 787 ASSERT(instr->right()->representation().IsTagged()); |
| 788 |
| 789 LOperand* left = UseFixed(instr->left(), rdx); |
| 790 LOperand* right = UseFixed(instr->right(), rax); |
| 791 LArithmeticT* result = new LArithmeticT(op, left, right); |
| 792 return MarkAsCall(DefineFixed(result, rax), instr); |
| 793 } |
| 794 } |
| 795 |
| 796 |
| 797 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 798 HBitwiseBinaryOperation* instr) { |
| 799 if (instr->representation().IsTagged()) { |
| 800 ASSERT(instr->left()->representation().IsTagged()); |
| 801 ASSERT(instr->right()->representation().IsTagged()); |
| 802 |
| 803 LOperand* left = UseFixed(instr->left(), rdx); |
| 804 LOperand* right = UseFixed(instr->right(), rax); |
| 805 LArithmeticT* result = new LArithmeticT(op, left, right); |
| 806 return MarkAsCall(DefineFixed(result, rax), instr); |
| 807 } |
| 808 |
| 809 ASSERT(instr->representation().IsInteger32()); |
| 810 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); |
| 811 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); |
| 812 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); |
| 813 |
| 814 HValue* right_value = instr->OperandAt(1); |
| 815 LOperand* right = NULL; |
| 816 int constant_value = 0; |
| 817 if (right_value->IsConstant()) { |
| 818 HConstant* constant = HConstant::cast(right_value); |
| 819 right = chunk_->DefineConstantOperand(constant); |
| 820 constant_value = constant->Integer32Value() & 0x1f; |
| 821 } else { |
| 822 right = UseFixed(right_value, rcx); |
| 823 } |
| 824 |
| 825 // Shift operations can only deoptimize if we do a logical shift |
| 826 // by 0 and the result cannot be truncated to int32. |
| 827 bool can_deopt = (op == Token::SHR && constant_value == 0); |
| 828 if (can_deopt) { |
| 829 bool can_truncate = true; |
| 830 for (int i = 0; i < instr->uses()->length(); i++) { |
| 831 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) { |
| 832 can_truncate = false; |
| 833 break; |
| 834 } |
| 835 } |
| 836 can_deopt = !can_truncate; |
| 837 } |
| 838 |
| 839 LShiftI* result = new LShiftI(op, left, right, can_deopt); |
| 840 return can_deopt |
| 841 ? AssignEnvironment(DefineSameAsFirst(result)) |
| 842 : DefineSameAsFirst(result); |
| 745 } | 843 } |
| 746 | 844 |
| 747 | 845 |
| 748 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 846 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 749 HArithmeticBinaryOperation* instr) { | 847 HArithmeticBinaryOperation* instr) { |
| 750 Abort("Unimplemented: %s", "DoArithmeticD"); | 848 Abort("Unimplemented: %s", "DoArithmeticD"); |
| 751 return NULL; | 849 return NULL; |
| 752 } | 850 } |
| 753 | 851 |
| 754 | 852 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 } | 927 } |
| 830 block->set_argument_count(argument_count_); | 928 block->set_argument_count(argument_count_); |
| 831 next_block_ = NULL; | 929 next_block_ = NULL; |
| 832 current_block_ = NULL; | 930 current_block_ = NULL; |
| 833 } | 931 } |
| 834 | 932 |
| 835 | 933 |
| 836 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 934 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 837 HInstruction* old_current = current_instruction_; | 935 HInstruction* old_current = current_instruction_; |
| 838 current_instruction_ = current; | 936 current_instruction_ = current; |
| 839 allocator_->BeginInstruction(); | |
| 840 if (current->has_position()) position_ = current->position(); | 937 if (current->has_position()) position_ = current->position(); |
| 841 LInstruction* instr = current->CompileToLithium(this); | 938 LInstruction* instr = current->CompileToLithium(this); |
| 842 | 939 |
| 843 if (instr != NULL) { | 940 if (instr != NULL) { |
| 844 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 941 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 845 instr = AssignPointerMap(instr); | 942 instr = AssignPointerMap(instr); |
| 846 } | 943 } |
| 847 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 944 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 848 instr = AssignEnvironment(instr); | 945 instr = AssignEnvironment(instr); |
| 849 } | 946 } |
| 850 if (current->IsTest() && !instr->IsGoto()) { | 947 if (current->IsTest() && !instr->IsGoto()) { |
| 851 ASSERT(instr->IsControl()); | 948 ASSERT(instr->IsControl()); |
| 852 HTest* test = HTest::cast(current); | 949 HTest* test = HTest::cast(current); |
| 853 instr->set_hydrogen_value(test->value()); | 950 instr->set_hydrogen_value(test->value()); |
| 854 HBasicBlock* first = test->FirstSuccessor(); | 951 HBasicBlock* first = test->FirstSuccessor(); |
| 855 HBasicBlock* second = test->SecondSuccessor(); | 952 HBasicBlock* second = test->SecondSuccessor(); |
| 856 ASSERT(first != NULL && second != NULL); | 953 ASSERT(first != NULL && second != NULL); |
| 857 instr->SetBranchTargets(first->block_id(), second->block_id()); | 954 instr->SetBranchTargets(first->block_id(), second->block_id()); |
| 858 } else { | 955 } else { |
| 859 instr->set_hydrogen_value(current); | 956 instr->set_hydrogen_value(current); |
| 860 } | 957 } |
| 861 | 958 |
| 862 int index = chunk_->AddInstruction(instr, current_block_); | 959 chunk_->AddInstruction(instr, current_block_); |
| 863 allocator_->SummarizeInstruction(index); | |
| 864 } else { | |
| 865 // This instruction should be omitted. | |
| 866 allocator_->OmitInstruction(); | |
| 867 } | 960 } |
| 868 current_instruction_ = old_current; | 961 current_instruction_ = old_current; |
| 869 } | 962 } |
| 870 | 963 |
| 871 | 964 |
| 872 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { | 965 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { |
| 873 if (hydrogen_env == NULL) return NULL; | 966 if (hydrogen_env == NULL) return NULL; |
| 874 | 967 |
| 875 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); | 968 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); |
| 876 int ast_id = hydrogen_env->ast_id(); | 969 int ast_id = hydrogen_env->ast_id(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } else if (v->IsInstanceOf()) { | 1075 } else if (v->IsInstanceOf()) { |
| 983 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1076 HInstanceOf* instance_of = HInstanceOf::cast(v); |
| 984 LInstanceOfAndBranch* result = | 1077 LInstanceOfAndBranch* result = |
| 985 new LInstanceOfAndBranch( | 1078 new LInstanceOfAndBranch( |
| 986 UseFixed(instance_of->left(), InstanceofStub::left()), | 1079 UseFixed(instance_of->left(), InstanceofStub::left()), |
| 987 UseFixed(instance_of->right(), InstanceofStub::right())); | 1080 UseFixed(instance_of->right(), InstanceofStub::right())); |
| 988 return MarkAsCall(result, instr); | 1081 return MarkAsCall(result, instr); |
| 989 } else if (v->IsTypeofIs()) { | 1082 } else if (v->IsTypeofIs()) { |
| 990 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1083 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
| 991 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); | 1084 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); |
| 1085 } else if (v->IsIsConstructCall()) { |
| 1086 return new LIsConstructCallAndBranch(TempRegister()); |
| 992 } else { | 1087 } else { |
| 993 if (v->IsConstant()) { | 1088 if (v->IsConstant()) { |
| 994 if (HConstant::cast(v)->handle()->IsTrue()) { | 1089 if (HConstant::cast(v)->handle()->IsTrue()) { |
| 995 return new LGoto(instr->FirstSuccessor()->block_id()); | 1090 return new LGoto(instr->FirstSuccessor()->block_id()); |
| 996 } else if (HConstant::cast(v)->handle()->IsFalse()) { | 1091 } else if (HConstant::cast(v)->handle()->IsFalse()) { |
| 997 return new LGoto(instr->SecondSuccessor()->block_id()); | 1092 return new LGoto(instr->SecondSuccessor()->block_id()); |
| 998 } | 1093 } |
| 999 } | 1094 } |
| 1000 Abort("Undefined compare before branch"); | 1095 Abort("Undefined compare before branch"); |
| 1001 return NULL; | 1096 return NULL; |
| 1002 } | 1097 } |
| 1003 } | 1098 } |
| 1004 return new LBranch(UseRegisterAtStart(v)); | 1099 return new LBranch(UseRegisterAtStart(v)); |
| 1005 } | 1100 } |
| 1006 | 1101 |
| 1007 | 1102 |
| 1008 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 1103 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1009 Abort("Unimplemented: %s", "DoCompareMap"); | 1104 ASSERT(instr->value()->representation().IsTagged()); |
| 1010 return NULL; | 1105 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1106 return new LCmpMapAndBranch(value); |
| 1011 } | 1107 } |
| 1012 | 1108 |
| 1013 | 1109 |
| 1014 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 1110 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 1015 Abort("Unimplemented: %s", "DoArgumentsLength"); | 1111 Abort("Unimplemented: %s", "DoArgumentsLength"); |
| 1016 return NULL; | 1112 return NULL; |
| 1017 } | 1113 } |
| 1018 | 1114 |
| 1019 | 1115 |
| 1020 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1116 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1036 } | 1132 } |
| 1037 | 1133 |
| 1038 | 1134 |
| 1039 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { | 1135 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
| 1040 Abort("Unimplemented: %s", "DoApplyArguments"); | 1136 Abort("Unimplemented: %s", "DoApplyArguments"); |
| 1041 return NULL; | 1137 return NULL; |
| 1042 } | 1138 } |
| 1043 | 1139 |
| 1044 | 1140 |
| 1045 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1141 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1046 Abort("Unimplemented: %s", "DoPushArgument"); | 1142 ++argument_count_; |
| 1143 LOperand* argument = UseOrConstant(instr->argument()); |
| 1144 return new LPushArgument(argument); |
| 1145 } |
| 1146 |
| 1147 |
| 1148 LInstruction* LChunkBuilder::DoContext(HContext* instr) { |
| 1149 Abort("Unimplemented: DoContext"); |
| 1150 return NULL; |
| 1151 } |
| 1152 |
| 1153 |
| 1154 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { |
| 1155 Abort("Unimplemented: DoOuterContext"); |
| 1047 return NULL; | 1156 return NULL; |
| 1048 } | 1157 } |
| 1049 | 1158 |
| 1050 | 1159 |
| 1051 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { | 1160 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { |
| 1052 return DefineAsRegister(new LGlobalObject); | 1161 return DefineAsRegister(new LGlobalObject); |
| 1053 } | 1162 } |
| 1054 | 1163 |
| 1055 | 1164 |
| 1056 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1165 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
| 1057 Abort("Unimplemented: %s", "DoGlobalReceiver"); | 1166 return DefineAsRegister(new LGlobalReceiver); |
| 1058 return NULL; | |
| 1059 } | 1167 } |
| 1060 | 1168 |
| 1061 | 1169 |
| 1062 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1170 LInstruction* LChunkBuilder::DoCallConstantFunction( |
| 1063 HCallConstantFunction* instr) { | 1171 HCallConstantFunction* instr) { |
| 1064 Abort("Unimplemented: %s", "DoCallConstantFunction"); | 1172 argument_count_ -= instr->argument_count(); |
| 1065 return NULL; | 1173 return MarkAsCall(DefineFixed(new LCallConstantFunction, rax), instr); |
| 1066 } | 1174 } |
| 1067 | 1175 |
| 1068 | 1176 |
| 1069 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1177 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1070 Abort("Unimplemented: %s", "DoUnaryMathOperation"); | 1178 Abort("Unimplemented: %s", "DoUnaryMathOperation"); |
| 1071 return NULL; | 1179 return NULL; |
| 1072 } | 1180 } |
| 1073 | 1181 |
| 1074 | 1182 |
| 1075 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1183 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
| 1076 Abort("Unimplemented: %s", "DoCallKeyed"); | 1184 Abort("Unimplemented: %s", "DoCallKeyed"); |
| 1077 return NULL; | 1185 return NULL; |
| 1078 } | 1186 } |
| 1079 | 1187 |
| 1080 | 1188 |
| 1081 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1189 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
| 1082 Abort("Unimplemented: %s", "DoCallNamed"); | 1190 argument_count_ -= instr->argument_count(); |
| 1083 return NULL; | 1191 return MarkAsCall(DefineFixed(new LCallNamed, rax), instr); |
| 1084 } | 1192 } |
| 1085 | 1193 |
| 1086 | 1194 |
| 1087 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1195 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
| 1088 Abort("Unimplemented: %s", "DoCallGlobal"); | 1196 Abort("Unimplemented: %s", "DoCallGlobal"); |
| 1089 return NULL; | 1197 return NULL; |
| 1090 } | 1198 } |
| 1091 | 1199 |
| 1092 | 1200 |
| 1093 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1201 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
| 1094 Abort("Unimplemented: %s", "DoCallKnownGlobal"); | 1202 argument_count_ -= instr->argument_count(); |
| 1095 return NULL; | 1203 return MarkAsCall(DefineFixed(new LCallKnownGlobal, rax), instr); |
| 1096 } | 1204 } |
| 1097 | 1205 |
| 1098 | 1206 |
| 1099 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1207 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
| 1100 Abort("Unimplemented: %s", "DoCallNew"); | 1208 LOperand* constructor = UseFixed(instr->constructor(), rdi); |
| 1101 return NULL; | 1209 argument_count_ -= instr->argument_count(); |
| 1210 LCallNew* result = new LCallNew(constructor); |
| 1211 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1102 } | 1212 } |
| 1103 | 1213 |
| 1104 | 1214 |
| 1105 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1215 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1106 Abort("Unimplemented: %s", "DoCallFunction"); | 1216 Abort("Unimplemented: %s", "DoCallFunction"); |
| 1107 return NULL; | 1217 return NULL; |
| 1108 } | 1218 } |
| 1109 | 1219 |
| 1110 | 1220 |
| 1111 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1221 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1112 Abort("Unimplemented: %s", "DoCallRuntime"); | 1222 argument_count_ -= instr->argument_count(); |
| 1113 return NULL; | 1223 return MarkAsCall(DefineFixed(new LCallRuntime, rax), instr); |
| 1114 } | 1224 } |
| 1115 | 1225 |
| 1116 | 1226 |
| 1117 LInstruction* LChunkBuilder::DoShr(HShr* instr) { | 1227 LInstruction* LChunkBuilder::DoShr(HShr* instr) { |
| 1118 Abort("Unimplemented: %s", "DoShr"); | 1228 return DoShift(Token::SHR, instr); |
| 1119 return NULL; | |
| 1120 } | 1229 } |
| 1121 | 1230 |
| 1122 | 1231 |
| 1123 LInstruction* LChunkBuilder::DoSar(HSar* instr) { | 1232 LInstruction* LChunkBuilder::DoSar(HSar* instr) { |
| 1124 Abort("Unimplemented: %s", "DoSar"); | 1233 return DoShift(Token::SAR, instr); |
| 1125 return NULL; | |
| 1126 } | 1234 } |
| 1127 | 1235 |
| 1128 | 1236 |
| 1129 LInstruction* LChunkBuilder::DoShl(HShl* instr) { | 1237 LInstruction* LChunkBuilder::DoShl(HShl* instr) { |
| 1130 Abort("Unimplemented: %s", "DoShl"); | 1238 return DoShift(Token::SHL, instr); |
| 1131 return NULL; | |
| 1132 } | 1239 } |
| 1133 | 1240 |
| 1134 | 1241 |
| 1135 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) { | 1242 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) { |
| 1136 Abort("Unimplemented: %s", "DoBitAnd"); | 1243 return DoBit(Token::BIT_AND, instr); |
| 1137 return NULL; | |
| 1138 } | 1244 } |
| 1139 | 1245 |
| 1140 | 1246 |
| 1141 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { | 1247 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { |
| 1142 Abort("Unimplemented: %s", "DoBitNot"); | 1248 ASSERT(instr->value()->representation().IsInteger32()); |
| 1143 return NULL; | 1249 ASSERT(instr->representation().IsInteger32()); |
| 1250 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1251 LBitNotI* result = new LBitNotI(input); |
| 1252 return DefineSameAsFirst(result); |
| 1144 } | 1253 } |
| 1145 | 1254 |
| 1146 | 1255 |
| 1147 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) { | 1256 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) { |
| 1148 Abort("Unimplemented: %s", "DoBitOr"); | 1257 return DoBit(Token::BIT_OR, instr); |
| 1149 return NULL; | |
| 1150 } | 1258 } |
| 1151 | 1259 |
| 1152 | 1260 |
| 1153 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { | 1261 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { |
| 1154 Abort("Unimplemented: %s", "DoBitXor"); | 1262 return DoBit(Token::BIT_XOR, instr); |
| 1155 return NULL; | |
| 1156 } | 1263 } |
| 1157 | 1264 |
| 1158 | 1265 |
| 1159 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1266 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
| 1160 Abort("Unimplemented: %s", "DoDiv"); | 1267 if (instr->representation().IsDouble()) { |
| 1161 return NULL; | 1268 return DoArithmeticD(Token::DIV, instr); |
| 1269 } else if (instr->representation().IsInteger32()) { |
| 1270 // The temporary operand is necessary to ensure that right is not allocated |
| 1271 // into rdx. |
| 1272 LOperand* temp = FixedTemp(rdx); |
| 1273 LOperand* dividend = UseFixed(instr->left(), rax); |
| 1274 LOperand* divisor = UseRegister(instr->right()); |
| 1275 LDivI* result = new LDivI(dividend, divisor, temp); |
| 1276 return AssignEnvironment(DefineFixed(result, rax)); |
| 1277 } else { |
| 1278 ASSERT(instr->representation().IsTagged()); |
| 1279 return DoArithmeticT(Token::DIV, instr); |
| 1280 } |
| 1162 } | 1281 } |
| 1163 | 1282 |
| 1164 | 1283 |
| 1165 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1284 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1166 Abort("Unimplemented: %s", "DoMod"); | 1285 Abort("Unimplemented: %s", "DoMod"); |
| 1167 return NULL; | 1286 return NULL; |
| 1168 } | 1287 } |
| 1169 | 1288 |
| 1170 | 1289 |
| 1171 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1290 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1172 Abort("Unimplemented: %s", "DoMul"); | 1291 if (instr->representation().IsInteger32()) { |
| 1173 return NULL; | 1292 ASSERT(instr->left()->representation().IsInteger32()); |
| 1293 ASSERT(instr->right()->representation().IsInteger32()); |
| 1294 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 1295 LOperand* right = UseOrConstant(instr->MostConstantOperand()); |
| 1296 LMulI* mul = new LMulI(left, right); |
| 1297 return AssignEnvironment(DefineSameAsFirst(mul)); |
| 1298 } else if (instr->representation().IsDouble()) { |
| 1299 return DoArithmeticD(Token::MUL, instr); |
| 1300 } else { |
| 1301 ASSERT(instr->representation().IsTagged()); |
| 1302 return DoArithmeticT(Token::MUL, instr); |
| 1303 } |
| 1174 } | 1304 } |
| 1175 | 1305 |
| 1176 | 1306 |
| 1177 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1307 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 1178 if (instr->representation().IsInteger32()) { | 1308 if (instr->representation().IsInteger32()) { |
| 1179 ASSERT(instr->left()->representation().IsInteger32()); | 1309 ASSERT(instr->left()->representation().IsInteger32()); |
| 1180 ASSERT(instr->right()->representation().IsInteger32()); | 1310 ASSERT(instr->right()->representation().IsInteger32()); |
| 1181 LOperand* left = UseRegisterAtStart(instr->left()); | 1311 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1182 LOperand* right = UseOrConstantAtStart(instr->right()); | 1312 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1183 LSubI* sub = new LSubI(left, right); | 1313 LSubI* sub = new LSubI(left, right); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1296 } | 1426 } |
| 1297 | 1427 |
| 1298 | 1428 |
| 1299 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { | 1429 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { |
| 1300 Abort("Unimplemented: %s", "DoClassOfTest"); | 1430 Abort("Unimplemented: %s", "DoClassOfTest"); |
| 1301 return NULL; | 1431 return NULL; |
| 1302 } | 1432 } |
| 1303 | 1433 |
| 1304 | 1434 |
| 1305 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { | 1435 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { |
| 1306 Abort("Unimplemented: %s", "DoJSArrayLength"); | 1436 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1307 return NULL; | 1437 return DefineAsRegister(new LJSArrayLength(array)); |
| 1308 } | 1438 } |
| 1309 | 1439 |
| 1310 | 1440 |
| 1311 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { | 1441 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
| 1312 Abort("Unimplemented: %s", "DoFixedArrayLength"); | 1442 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1313 return NULL; | 1443 return DefineAsRegister(new LFixedArrayLength(array)); |
| 1314 } | 1444 } |
| 1315 | 1445 |
| 1316 | 1446 |
| 1317 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1447 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
| 1318 Abort("Unimplemented: %s", "DoValueOf"); | 1448 Abort("Unimplemented: %s", "DoValueOf"); |
| 1319 return NULL; | 1449 return NULL; |
| 1320 } | 1450 } |
| 1321 | 1451 |
| 1322 | 1452 |
| 1323 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1453 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1324 Abort("Unimplemented: %s", "DoBoundsCheck"); | 1454 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
| 1455 Use(instr->length()))); |
| 1456 } |
| 1457 |
| 1458 |
| 1459 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| 1460 // The control instruction marking the end of a block that completed |
| 1461 // abruptly (e.g., threw an exception). There is nothing specific to do. |
| 1325 return NULL; | 1462 return NULL; |
| 1326 } | 1463 } |
| 1327 | 1464 |
| 1328 | 1465 |
| 1329 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1466 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
| 1330 Abort("Unimplemented: %s", "DoThrow"); | 1467 LOperand* value = UseFixed(instr->value(), rax); |
| 1331 return NULL; | 1468 return MarkAsCall(new LThrow(value), instr); |
| 1332 } | 1469 } |
| 1333 | 1470 |
| 1334 | 1471 |
| 1335 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1472 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
| 1336 Representation from = instr->from(); | 1473 Representation from = instr->from(); |
| 1337 Representation to = instr->to(); | 1474 Representation to = instr->to(); |
| 1338 if (from.IsTagged()) { | 1475 if (from.IsTagged()) { |
| 1339 if (to.IsDouble()) { | 1476 if (to.IsDouble()) { |
| 1340 LOperand* value = UseRegister(instr->value()); | 1477 LOperand* value = UseRegister(instr->value()); |
| 1341 LNumberUntagD* res = new LNumberUntagD(value); | 1478 LNumberUntagD* res = new LNumberUntagD(value); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1388 ASSERT(to.IsDouble()); | 1525 ASSERT(to.IsDouble()); |
| 1389 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); | 1526 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); |
| 1390 } | 1527 } |
| 1391 } | 1528 } |
| 1392 UNREACHABLE(); | 1529 UNREACHABLE(); |
| 1393 return NULL; | 1530 return NULL; |
| 1394 } | 1531 } |
| 1395 | 1532 |
| 1396 | 1533 |
| 1397 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { | 1534 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { |
| 1398 Abort("Unimplemented: %s", "DoCheckNonSmi"); | 1535 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1399 return NULL; | 1536 return AssignEnvironment(new LCheckSmi(value, zero)); |
| 1400 } | 1537 } |
| 1401 | 1538 |
| 1402 | 1539 |
| 1403 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 1540 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
| 1404 Abort("Unimplemented: %s", "DoCheckInstanceType"); | 1541 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1405 return NULL; | 1542 LCheckInstanceType* result = new LCheckInstanceType(value); |
| 1543 return AssignEnvironment(result); |
| 1406 } | 1544 } |
| 1407 | 1545 |
| 1408 | 1546 |
| 1409 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { | 1547 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
| 1410 Abort("Unimplemented: %s", "DoCheckPrototypeMaps"); | 1548 LOperand* temp = TempRegister(); |
| 1411 return NULL; | 1549 LCheckPrototypeMaps* result = new LCheckPrototypeMaps(temp); |
| 1550 return AssignEnvironment(result); |
| 1412 } | 1551 } |
| 1413 | 1552 |
| 1414 | 1553 |
| 1415 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { | 1554 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { |
| 1416 Abort("Unimplemented: %s", "DoCheckSmi"); | 1555 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1417 return NULL; | 1556 return AssignEnvironment(new LCheckSmi(value, not_zero)); |
| 1418 } | 1557 } |
| 1419 | 1558 |
| 1420 | 1559 |
| 1421 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { | 1560 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { |
| 1422 Abort("Unimplemented: %s", "DoCheckFunction"); | 1561 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1423 return NULL; | 1562 return AssignEnvironment(new LCheckFunction(value)); |
| 1424 } | 1563 } |
| 1425 | 1564 |
| 1426 | 1565 |
| 1427 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { | 1566 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { |
| 1428 Abort("Unimplemented: %s", "DoCheckMap"); | 1567 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1429 return NULL; | 1568 LCheckMap* result = new LCheckMap(value); |
| 1569 return AssignEnvironment(result); |
| 1430 } | 1570 } |
| 1431 | 1571 |
| 1432 | 1572 |
| 1433 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1573 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
| 1434 return new LReturn(UseFixed(instr->value(), rax)); | 1574 return new LReturn(UseFixed(instr->value(), rax)); |
| 1435 } | 1575 } |
| 1436 | 1576 |
| 1437 | 1577 |
| 1438 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1578 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1439 Representation r = instr->representation(); | 1579 Representation r = instr->representation(); |
| 1440 if (r.IsInteger32()) { | 1580 if (r.IsInteger32()) { |
| 1441 int32_t value = instr->Integer32Value(); | 1581 return DefineAsRegister(new LConstantI); |
| 1442 return DefineAsRegister(new LConstantI(value)); | |
| 1443 } else if (r.IsDouble()) { | 1582 } else if (r.IsDouble()) { |
| 1444 double value = instr->DoubleValue(); | |
| 1445 LOperand* temp = TempRegister(); | 1583 LOperand* temp = TempRegister(); |
| 1446 return DefineAsRegister(new LConstantD(value, temp)); | 1584 return DefineAsRegister(new LConstantD(temp)); |
| 1447 } else if (r.IsTagged()) { | 1585 } else if (r.IsTagged()) { |
| 1448 return DefineAsRegister(new LConstantT(instr->handle())); | 1586 return DefineAsRegister(new LConstantT); |
| 1449 } else { | 1587 } else { |
| 1450 UNREACHABLE(); | 1588 UNREACHABLE(); |
| 1451 return NULL; | 1589 return NULL; |
| 1452 } | 1590 } |
| 1453 } | 1591 } |
| 1454 | 1592 |
| 1455 | 1593 |
| 1456 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1594 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
| 1457 Abort("Unimplemented: %s", "DoLoadGlobal"); | 1595 LLoadGlobal* result = new LLoadGlobal; |
| 1458 return NULL; | 1596 return instr->check_hole_value() |
| 1597 ? AssignEnvironment(DefineAsRegister(result)) |
| 1598 : DefineAsRegister(result); |
| 1459 } | 1599 } |
| 1460 | 1600 |
| 1461 | 1601 |
| 1462 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1602 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
| 1463 Abort("Unimplemented: %s", "DoStoreGlobal"); | 1603 LStoreGlobal* result = new LStoreGlobal(UseRegister(instr->value()), |
| 1464 return NULL; | 1604 TempRegister()); |
| 1605 return instr->check_hole_value() ? AssignEnvironment(result) : result; |
| 1465 } | 1606 } |
| 1466 | 1607 |
| 1467 | 1608 |
| 1468 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { | 1609 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { |
| 1469 Abort("Unimplemented: %s", "DoLoadContextSlot"); | 1610 Abort("Unimplemented: %s", "DoLoadContextSlot"); |
| 1470 return NULL; | 1611 return NULL; |
| 1471 } | 1612 } |
| 1472 | 1613 |
| 1473 | 1614 |
| 1615 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { |
| 1616 Abort("Unimplemented: DoStoreContextSlot"); |
| 1617 return NULL; |
| 1618 } |
| 1619 |
| 1620 |
| 1474 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1621 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 1475 Abort("Unimplemented: %s", "DoLoadNamedField"); | 1622 ASSERT(instr->representation().IsTagged()); |
| 1476 return NULL; | 1623 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1624 return DefineAsRegister(new LLoadNamedField(obj)); |
| 1477 } | 1625 } |
| 1478 | 1626 |
| 1479 | 1627 |
| 1480 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1628 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 1481 Abort("Unimplemented: %s", "DoLoadNamedGeneric"); | 1629 LOperand* object = UseFixed(instr->object(), rax); |
| 1482 return NULL; | 1630 LLoadNamedGeneric* result = new LLoadNamedGeneric(object); |
| 1631 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1483 } | 1632 } |
| 1484 | 1633 |
| 1485 | 1634 |
| 1486 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( | 1635 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
| 1487 HLoadFunctionPrototype* instr) { | 1636 HLoadFunctionPrototype* instr) { |
| 1488 Abort("Unimplemented: %s", "DoLoadFunctionPrototype"); | 1637 Abort("Unimplemented: %s", "DoLoadFunctionPrototype"); |
| 1489 return NULL; | 1638 return NULL; |
| 1490 } | 1639 } |
| 1491 | 1640 |
| 1492 | 1641 |
| 1493 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { | 1642 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { |
| 1494 Abort("Unimplemented: %s", "DoLoadElements"); | 1643 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1495 return NULL; | 1644 return DefineSameAsFirst(new LLoadElements(input)); |
| 1496 } | 1645 } |
| 1497 | 1646 |
| 1498 | 1647 |
| 1499 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1648 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
| 1500 HLoadKeyedFastElement* instr) { | 1649 HLoadKeyedFastElement* instr) { |
| 1501 Abort("Unimplemented: %s", "DoLoadKeyedFastElement"); | 1650 ASSERT(instr->representation().IsTagged()); |
| 1502 return NULL; | 1651 ASSERT(instr->key()->representation().IsInteger32()); |
| 1652 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1653 LOperand* key = UseRegisterAtStart(instr->key()); |
| 1654 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); |
| 1655 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1503 } | 1656 } |
| 1504 | 1657 |
| 1505 | 1658 |
| 1506 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1659 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 1507 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); | 1660 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); |
| 1508 return NULL; | 1661 return NULL; |
| 1509 } | 1662 } |
| 1510 | 1663 |
| 1511 | 1664 |
| 1512 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( | 1665 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( |
| 1513 HStoreKeyedFastElement* instr) { | 1666 HStoreKeyedFastElement* instr) { |
| 1514 Abort("Unimplemented: %s", "DoStoreKeyedFastElement"); | 1667 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 1515 return NULL; | 1668 ASSERT(instr->value()->representation().IsTagged()); |
| 1669 ASSERT(instr->object()->representation().IsTagged()); |
| 1670 ASSERT(instr->key()->representation().IsInteger32()); |
| 1671 |
| 1672 LOperand* obj = UseTempRegister(instr->object()); |
| 1673 LOperand* val = needs_write_barrier |
| 1674 ? UseTempRegister(instr->value()) |
| 1675 : UseRegisterAtStart(instr->value()); |
| 1676 LOperand* key = needs_write_barrier |
| 1677 ? UseTempRegister(instr->key()) |
| 1678 : UseRegisterOrConstantAtStart(instr->key()); |
| 1679 |
| 1680 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); |
| 1516 } | 1681 } |
| 1517 | 1682 |
| 1518 | 1683 |
| 1519 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 1684 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 1520 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); | 1685 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); |
| 1521 return NULL; | 1686 return NULL; |
| 1522 } | 1687 } |
| 1523 | 1688 |
| 1524 | 1689 |
| 1525 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 1690 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
| 1526 Abort("Unimplemented: %s", "DoStoreNamedField"); | 1691 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 1527 return NULL; | 1692 |
| 1693 LOperand* obj = needs_write_barrier |
| 1694 ? UseTempRegister(instr->object()) |
| 1695 : UseRegisterAtStart(instr->object()); |
| 1696 |
| 1697 LOperand* val = needs_write_barrier |
| 1698 ? UseTempRegister(instr->value()) |
| 1699 : UseRegister(instr->value()); |
| 1700 |
| 1701 // We only need a scratch register if we have a write barrier or we |
| 1702 // have a store into the properties array (not in-object-property). |
| 1703 LOperand* temp = (!instr->is_in_object() || needs_write_barrier) |
| 1704 ? TempRegister() : NULL; |
| 1705 |
| 1706 return new LStoreNamedField(obj, val, temp); |
| 1528 } | 1707 } |
| 1529 | 1708 |
| 1530 | 1709 |
| 1531 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1710 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 1532 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); | 1711 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); |
| 1533 return NULL; | 1712 return NULL; |
| 1534 } | 1713 } |
| 1535 | 1714 |
| 1536 | 1715 |
| 1537 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 1716 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 1538 Abort("Unimplemented: %s", "DoStringCharCodeAt"); | 1717 Abort("Unimplemented: %s", "DoStringCharCodeAt"); |
| 1539 return NULL; | 1718 return NULL; |
| 1540 } | 1719 } |
| 1541 | 1720 |
| 1542 | 1721 |
| 1543 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { | 1722 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 1544 Abort("Unimplemented: %s", "DoStringLength"); | 1723 Abort("Unimplemented: %s", "DoStringLength"); |
| 1545 return NULL; | 1724 return NULL; |
| 1546 } | 1725 } |
| 1547 | 1726 |
| 1548 | 1727 |
| 1549 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1728 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1550 Abort("Unimplemented: %s", "DoArrayLiteral"); | 1729 return MarkAsCall(DefineFixed(new LArrayLiteral, rax), instr); |
| 1551 return NULL; | |
| 1552 } | 1730 } |
| 1553 | 1731 |
| 1554 | 1732 |
| 1555 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1733 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 1556 Abort("Unimplemented: %s", "DoObjectLiteral"); | 1734 return MarkAsCall(DefineFixed(new LObjectLiteral, rax), instr); |
| 1557 return NULL; | |
| 1558 } | 1735 } |
| 1559 | 1736 |
| 1560 | 1737 |
| 1561 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 1738 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 1562 Abort("Unimplemented: %s", "DoRegExpLiteral"); | 1739 Abort("Unimplemented: %s", "DoRegExpLiteral"); |
| 1563 return NULL; | 1740 return NULL; |
| 1564 } | 1741 } |
| 1565 | 1742 |
| 1566 | 1743 |
| 1567 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 1744 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 1568 Abort("Unimplemented: %s", "DoFunctionLiteral"); | 1745 return MarkAsCall(DefineFixed(new LFunctionLiteral, rax), instr); |
| 1569 return NULL; | |
| 1570 } | 1746 } |
| 1571 | 1747 |
| 1572 | 1748 |
| 1573 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { | 1749 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { |
| 1574 Abort("Unimplemented: %s", "DoDeleteProperty"); | 1750 Abort("Unimplemented: %s", "DoDeleteProperty"); |
| 1575 return NULL; | 1751 return NULL; |
| 1576 } | 1752 } |
| 1577 | 1753 |
| 1578 | 1754 |
| 1579 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1755 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 1580 Abort("Unimplemented: %s", "DoOsrEntry"); | 1756 Abort("Unimplemented: %s", "DoOsrEntry"); |
| 1581 return NULL; | 1757 return NULL; |
| 1582 } | 1758 } |
| 1583 | 1759 |
| 1584 | 1760 |
| 1585 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 1761 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 1586 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 1762 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 1587 return DefineAsSpilled(new LParameter, spill_index); | 1763 return DefineAsSpilled(new LParameter, spill_index); |
| 1588 } | 1764 } |
| 1589 | 1765 |
| 1590 | 1766 |
| 1591 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 1767 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| 1592 Abort("Unimplemented: %s", "DoUnknownOSRValue"); | 1768 Abort("Unimplemented: %s", "DoUnknownOSRValue"); |
| 1593 return NULL; | 1769 return NULL; |
| 1594 } | 1770 } |
| 1595 | 1771 |
| 1596 | 1772 |
| 1597 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 1773 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| 1598 Abort("Unimplemented: %s", "DoCallStub"); | 1774 argument_count_ -= instr->argument_count(); |
| 1599 return NULL; | 1775 return MarkAsCall(DefineFixed(new LCallStub, rax), instr); |
| 1600 } | 1776 } |
| 1601 | 1777 |
| 1602 | 1778 |
| 1603 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 1779 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 1604 Abort("Unimplemented: %s", "DoArgumentsObject"); | 1780 Abort("Unimplemented: %s", "DoArgumentsObject"); |
| 1605 return NULL; | 1781 return NULL; |
| 1606 } | 1782 } |
| 1607 | 1783 |
| 1608 | 1784 |
| 1609 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 1785 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
| 1610 Abort("Unimplemented: %s", "DoAccessArgumentsAt"); | 1786 Abort("Unimplemented: %s", "DoAccessArgumentsAt"); |
| 1611 return NULL; | 1787 return NULL; |
| 1612 } | 1788 } |
| 1613 | 1789 |
| 1614 | 1790 |
| 1615 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 1791 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 1616 Abort("Unimplemented: %s", "DoTypeof"); | 1792 Abort("Unimplemented: %s", "DoTypeof"); |
| 1617 return NULL; | 1793 return NULL; |
| 1618 } | 1794 } |
| 1619 | 1795 |
| 1620 | 1796 |
| 1621 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1797 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
| 1622 Abort("Unimplemented: %s", "DoTypeofIs"); | 1798 Abort("Unimplemented: %s", "DoTypeofIs"); |
| 1623 return NULL; | 1799 return NULL; |
| 1624 } | 1800 } |
| 1625 | 1801 |
| 1802 |
| 1803 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { |
| 1804 return DefineAsRegister(new LIsConstructCall); |
| 1805 } |
| 1806 |
| 1807 |
| 1626 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 1808 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 1627 HEnvironment* env = current_block_->last_environment(); | 1809 HEnvironment* env = current_block_->last_environment(); |
| 1628 ASSERT(env != NULL); | 1810 ASSERT(env != NULL); |
| 1629 | 1811 |
| 1630 env->set_ast_id(instr->ast_id()); | 1812 env->set_ast_id(instr->ast_id()); |
| 1631 | 1813 |
| 1632 env->Drop(instr->pop_count()); | 1814 env->Drop(instr->pop_count()); |
| 1633 for (int i = 0; i < instr->values()->length(); ++i) { | 1815 for (int i = 0; i < instr->values()->length(); ++i) { |
| 1634 HValue* value = instr->values()->at(i); | 1816 HValue* value = instr->values()->at(i); |
| 1635 if (instr->HasAssignedIndexAt(i)) { | 1817 if (instr->HasAssignedIndexAt(i)) { |
| 1636 env->Bind(instr->GetAssignedIndexAt(i), value); | 1818 env->Bind(instr->GetAssignedIndexAt(i), value); |
| 1637 } else { | 1819 } else { |
| 1638 env->Push(value); | 1820 env->Push(value); |
| 1639 } | 1821 } |
| 1640 } | 1822 } |
| 1641 ASSERT(env->length() == instr->environment_length()); | 1823 ASSERT(env->length() == instr->environment_length()); |
| 1642 | 1824 |
| 1643 // If there is an instruction pending deoptimization environment create a | 1825 // If there is an instruction pending deoptimization environment create a |
| 1644 // lazy bailout instruction to capture the environment. | 1826 // lazy bailout instruction to capture the environment. |
| 1645 if (pending_deoptimization_ast_id_ == instr->ast_id()) { | 1827 if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
| 1646 LLazyBailout* lazy_bailout = new LLazyBailout; | 1828 LLazyBailout* lazy_bailout = new LLazyBailout; |
| 1647 LInstruction* result = AssignEnvironment(lazy_bailout); | 1829 LInstruction* result = AssignEnvironment(lazy_bailout); |
| 1648 instructions_pending_deoptimization_environment_-> | 1830 instruction_pending_deoptimization_environment_-> |
| 1649 set_deoptimization_environment(result->environment()); | 1831 set_deoptimization_environment(result->environment()); |
| 1650 ClearInstructionPendingDeoptimizationEnvironment(); | 1832 ClearInstructionPendingDeoptimizationEnvironment(); |
| 1651 return result; | 1833 return result; |
| 1652 } | 1834 } |
| 1653 | 1835 |
| 1654 return NULL; | 1836 return NULL; |
| 1655 } | 1837 } |
| 1656 | 1838 |
| 1657 | 1839 |
| 1658 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 1840 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 1659 return MarkAsCall(new LStackCheck, instr); | 1841 return MarkAsCall(new LStackCheck, instr); |
| 1660 } | 1842 } |
| 1661 | 1843 |
| 1662 | 1844 |
| 1663 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 1845 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
| 1664 Abort("Unimplemented: %s", "DoEnterInlined"); | 1846 HEnvironment* outer = current_block_->last_environment(); |
| 1847 HConstant* undefined = graph()->GetConstantUndefined(); |
| 1848 HEnvironment* inner = outer->CopyForInlining(instr->closure(), |
| 1849 instr->function(), |
| 1850 false, |
| 1851 undefined); |
| 1852 current_block_->UpdateEnvironment(inner); |
| 1853 chunk_->AddInlinedClosure(instr->closure()); |
| 1665 return NULL; | 1854 return NULL; |
| 1666 } | 1855 } |
| 1667 | 1856 |
| 1668 | 1857 |
| 1669 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1858 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 1670 Abort("Unimplemented: %s", "DoLeaveInlined"); | 1859 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 1860 current_block_->UpdateEnvironment(outer); |
| 1671 return NULL; | 1861 return NULL; |
| 1672 } | 1862 } |
| 1673 | 1863 |
| 1674 } } // namespace v8::internal | 1864 } } // namespace v8::internal |
| 1675 | 1865 |
| 1676 #endif // V8_TARGET_ARCH_X64 | 1866 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |