| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 | 71 |
| 72 #ifdef DEBUG | 72 #ifdef DEBUG |
| 73 void LInstruction::VerifyCall() { | 73 void LInstruction::VerifyCall() { |
| 74 // Call instructions can use only fixed registers as temporaries and | 74 // Call instructions can use only fixed registers as temporaries and |
| 75 // outputs because all registers are blocked by the calling convention. | 75 // outputs because all registers are blocked by the calling convention. |
| 76 // Inputs operands must use a fixed register or use-at-start policy or | 76 // Inputs operands must use a fixed register or use-at-start policy or |
| 77 // a non-register policy. | 77 // a non-register policy. |
| 78 ASSERT(Output() == NULL || | 78 ASSERT(Output() == NULL || |
| 79 LUnallocated::cast(Output())->HasFixedPolicy() || | 79 LUnallocated::cast(Output())->HasFixedPolicy() || |
| 80 !LUnallocated::cast(Output())->HasRegisterPolicy()); | 80 !LUnallocated::cast(Output())->HasRegisterPolicy()); |
| 81 for (UseIterator it(this); it.HasNext(); it.Advance()) { | 81 for (UseIterator it(this); !it.Done(); it.Advance()) { |
| 82 LUnallocated* operand = LUnallocated::cast(it.Next()); | 82 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 83 ASSERT(operand->HasFixedPolicy() || | 83 ASSERT(operand->HasFixedPolicy() || |
| 84 operand->IsUsedAtStart()); | 84 operand->IsUsedAtStart()); |
| 85 } | 85 } |
| 86 for (TempIterator it(this); it.HasNext(); it.Advance()) { | 86 for (TempIterator it(this); !it.Done(); it.Advance()) { |
| 87 LUnallocated* operand = LUnallocated::cast(it.Next()); | 87 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 88 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); | 88 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 #endif | 91 #endif |
| 92 | 92 |
| 93 | 93 |
| 94 void LInstruction::PrintTo(StringStream* stream) { | 94 void LInstruction::PrintTo(StringStream* stream) { |
| 95 stream->Add("%s ", this->Mnemonic()); | 95 stream->Add("%s ", this->Mnemonic()); |
| 96 | 96 |
| 97 PrintOutputOperandTo(stream); | 97 PrintOutputOperandTo(stream); |
| 98 | 98 |
| 99 PrintDataTo(stream); | 99 PrintDataTo(stream); |
| 100 | 100 |
| 101 if (HasEnvironment()) { | 101 if (HasEnvironment()) { |
| 102 stream->Add(" "); | 102 stream->Add(" "); |
| 103 environment()->PrintTo(stream); | 103 environment()->PrintTo(stream); |
| 104 } | 104 } |
| 105 | 105 |
| 106 if (HasPointerMap()) { | 106 if (HasPointerMap()) { |
| 107 stream->Add(" "); | 107 stream->Add(" "); |
| 108 pointer_map()->PrintTo(stream); | 108 pointer_map()->PrintTo(stream); |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 | 111 |
| 112 | 112 |
| 113 template<int R, int I, int T> | 113 template<int R, int I, int T> |
| 114 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { | 114 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { |
| 115 stream->Add("= "); | 115 stream->Add("= "); |
| 116 inputs_.PrintOperandsTo(stream); | 116 for (int i = 0; i < inputs_.length(); i++) { |
| 117 if (i > 0) stream->Add(" "); |
| 118 inputs_[i]->PrintTo(stream); |
| 119 } |
| 117 } | 120 } |
| 118 | 121 |
| 119 | 122 |
| 120 template<int R, int I, int T> | 123 template<int R, int I, int T> |
| 121 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { | 124 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { |
| 122 results_.PrintOperandsTo(stream); | 125 for (int i = 0; i < results_.length(); i++) { |
| 123 } | |
| 124 | |
| 125 | |
| 126 template<typename T, int N> | |
| 127 void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) { | |
| 128 for (int i = 0; i < N; i++) { | |
| 129 if (i > 0) stream->Add(" "); | 126 if (i > 0) stream->Add(" "); |
| 130 elems_[i]->PrintTo(stream); | 127 results_[i]->PrintTo(stream); |
| 131 } | 128 } |
| 132 } | 129 } |
| 133 | 130 |
| 134 | 131 |
| 135 void LLabel::PrintDataTo(StringStream* stream) { | 132 void LLabel::PrintDataTo(StringStream* stream) { |
| 136 LGap::PrintDataTo(stream); | 133 LGap::PrintDataTo(stream); |
| 137 LLabel* rep = replacement(); | 134 LLabel* rep = replacement(); |
| 138 if (rep != NULL) { | 135 if (rep != NULL) { |
| 139 stream->Add(" Dead block replaced with B%d", rep->block_id()); | 136 stream->Add(" Dead block replaced with B%d", rep->block_id()); |
| 140 } | 137 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { | 260 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { |
| 264 stream->Add("if class_of_test("); | 261 stream->Add("if class_of_test("); |
| 265 InputAt(0)->PrintTo(stream); | 262 InputAt(0)->PrintTo(stream); |
| 266 stream->Add(", \"%o\") then B%d else B%d", | 263 stream->Add(", \"%o\") then B%d else B%d", |
| 267 *hydrogen()->class_name(), | 264 *hydrogen()->class_name(), |
| 268 true_block_id(), | 265 true_block_id(), |
| 269 false_block_id()); | 266 false_block_id()); |
| 270 } | 267 } |
| 271 | 268 |
| 272 | 269 |
| 273 void LTypeofIs::PrintDataTo(StringStream* stream) { | |
| 274 InputAt(0)->PrintTo(stream); | |
| 275 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); | |
| 276 } | |
| 277 | |
| 278 | |
| 279 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 270 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
| 280 stream->Add("if typeof "); | 271 stream->Add("if typeof "); |
| 281 InputAt(0)->PrintTo(stream); | 272 InputAt(0)->PrintTo(stream); |
| 282 stream->Add(" == \"%s\" then B%d else B%d", | 273 stream->Add(" == \"%s\" then B%d else B%d", |
| 283 *hydrogen()->type_literal()->ToCString(), | 274 *hydrogen()->type_literal()->ToCString(), |
| 284 true_block_id(), false_block_id()); | 275 true_block_id(), false_block_id()); |
| 285 } | 276 } |
| 286 | 277 |
| 287 | 278 |
| 288 void LCallConstantFunction::PrintDataTo(StringStream* stream) { | 279 void LCallConstantFunction::PrintDataTo(StringStream* stream) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 } | 331 } |
| 341 | 332 |
| 342 | 333 |
| 343 void LCallNew::PrintDataTo(StringStream* stream) { | 334 void LCallNew::PrintDataTo(StringStream* stream) { |
| 344 stream->Add("= "); | 335 stream->Add("= "); |
| 345 InputAt(0)->PrintTo(stream); | 336 InputAt(0)->PrintTo(stream); |
| 346 stream->Add(" #%d / ", arity()); | 337 stream->Add(" #%d / ", arity()); |
| 347 } | 338 } |
| 348 | 339 |
| 349 | 340 |
| 350 void LClassOfTest::PrintDataTo(StringStream* stream) { | |
| 351 stream->Add("= class_of_test("); | |
| 352 InputAt(0)->PrintTo(stream); | |
| 353 stream->Add(", \"%o\")", *hydrogen()->class_name()); | |
| 354 } | |
| 355 | |
| 356 | |
| 357 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { | 341 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { |
| 358 arguments()->PrintTo(stream); | 342 arguments()->PrintTo(stream); |
| 359 | 343 |
| 360 stream->Add(" length "); | 344 stream->Add(" length "); |
| 361 length()->PrintTo(stream); | 345 length()->PrintTo(stream); |
| 362 | 346 |
| 363 stream->Add(" index "); | 347 stream->Add(" index "); |
| 364 index()->PrintTo(stream); | 348 index()->PrintTo(stream); |
| 365 } | 349 } |
| 366 | 350 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 387 for (int i = 0; i < graph()->blocks()->length(); ++i) { | 371 for (int i = 0; i < graph()->blocks()->length(); ++i) { |
| 388 HBasicBlock* block = graph()->blocks()->at(i); | 372 HBasicBlock* block = graph()->blocks()->at(i); |
| 389 int first = block->first_instruction_index(); | 373 int first = block->first_instruction_index(); |
| 390 int last = block->last_instruction_index(); | 374 int last = block->last_instruction_index(); |
| 391 LInstruction* first_instr = instructions()->at(first); | 375 LInstruction* first_instr = instructions()->at(first); |
| 392 LInstruction* last_instr = instructions()->at(last); | 376 LInstruction* last_instr = instructions()->at(last); |
| 393 | 377 |
| 394 LLabel* label = LLabel::cast(first_instr); | 378 LLabel* label = LLabel::cast(first_instr); |
| 395 if (last_instr->IsGoto()) { | 379 if (last_instr->IsGoto()) { |
| 396 LGoto* goto_instr = LGoto::cast(last_instr); | 380 LGoto* goto_instr = LGoto::cast(last_instr); |
| 397 if (!goto_instr->include_stack_check() && | 381 if (label->IsRedundant() && |
| 398 label->IsRedundant() && | |
| 399 !label->is_loop_header()) { | 382 !label->is_loop_header()) { |
| 400 bool can_eliminate = true; | 383 bool can_eliminate = true; |
| 401 for (int i = first + 1; i < last && can_eliminate; ++i) { | 384 for (int i = first + 1; i < last && can_eliminate; ++i) { |
| 402 LInstruction* cur = instructions()->at(i); | 385 LInstruction* cur = instructions()->at(i); |
| 403 if (cur->IsGap()) { | 386 if (cur->IsGap()) { |
| 404 LGap* gap = LGap::cast(cur); | 387 LGap* gap = LGap::cast(cur); |
| 405 if (!gap->IsRedundant()) { | 388 if (!gap->IsRedundant()) { |
| 406 can_eliminate = false; | 389 can_eliminate = false; |
| 407 } | 390 } |
| 408 } else { | 391 } else { |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 allocator_->RecordTemporary(operand); | 780 allocator_->RecordTemporary(operand); |
| 798 return operand; | 781 return operand; |
| 799 } | 782 } |
| 800 | 783 |
| 801 | 784 |
| 802 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { | 785 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { |
| 803 return new LLabel(instr->block()); | 786 return new LLabel(instr->block()); |
| 804 } | 787 } |
| 805 | 788 |
| 806 | 789 |
| 790 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) { |
| 791 return AssignEnvironment(new LDeoptimize); |
| 792 } |
| 793 |
| 794 |
| 807 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 795 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 808 return AssignEnvironment(new LDeoptimize); | 796 return AssignEnvironment(new LDeoptimize); |
| 809 } | 797 } |
| 810 | 798 |
| 811 | 799 |
| 812 LInstruction* LChunkBuilder::DoBit(Token::Value op, | 800 LInstruction* LChunkBuilder::DoBit(Token::Value op, |
| 813 HBitwiseBinaryOperation* instr) { | 801 HBitwiseBinaryOperation* instr) { |
| 814 if (instr->representation().IsInteger32()) { | 802 if (instr->representation().IsInteger32()) { |
| 815 ASSERT(instr->left()->representation().IsInteger32()); | 803 ASSERT(instr->left()->representation().IsInteger32()); |
| 816 ASSERT(instr->right()->representation().IsInteger32()); | 804 ASSERT(instr->right()->representation().IsInteger32()); |
| 817 | 805 |
| 818 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); | 806 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 819 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); | 807 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); |
| 820 return DefineSameAsFirst(new LBitI(op, left, right)); | 808 return DefineSameAsFirst(new LBitI(op, left, right)); |
| 821 } else { | 809 } else { |
| 822 ASSERT(instr->representation().IsTagged()); | 810 ASSERT(instr->representation().IsTagged()); |
| 823 ASSERT(instr->left()->representation().IsTagged()); | 811 ASSERT(instr->left()->representation().IsTagged()); |
| 824 ASSERT(instr->right()->representation().IsTagged()); | 812 ASSERT(instr->right()->representation().IsTagged()); |
| 825 | 813 |
| 814 LOperand* context = UseFixed(instr->context(), esi); |
| 826 LOperand* left = UseFixed(instr->left(), edx); | 815 LOperand* left = UseFixed(instr->left(), edx); |
| 827 LOperand* right = UseFixed(instr->right(), eax); | 816 LOperand* right = UseFixed(instr->right(), eax); |
| 828 LArithmeticT* result = new LArithmeticT(op, left, right); | 817 LArithmeticT* result = new LArithmeticT(op, context, left, right); |
| 829 return MarkAsCall(DefineFixed(result, eax), instr); | 818 return MarkAsCall(DefineFixed(result, eax), instr); |
| 830 } | 819 } |
| 831 } | 820 } |
| 832 | 821 |
| 833 | 822 |
| 834 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 823 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 835 HBitwiseBinaryOperation* instr) { | 824 HBitwiseBinaryOperation* instr) { |
| 836 if (instr->representation().IsTagged()) { | 825 if (instr->representation().IsTagged()) { |
| 837 ASSERT(instr->left()->representation().IsTagged()); | 826 ASSERT(instr->left()->representation().IsTagged()); |
| 838 ASSERT(instr->right()->representation().IsTagged()); | 827 ASSERT(instr->right()->representation().IsTagged()); |
| 839 | 828 |
| 829 LOperand* context = UseFixed(instr->context(), esi); |
| 840 LOperand* left = UseFixed(instr->left(), edx); | 830 LOperand* left = UseFixed(instr->left(), edx); |
| 841 LOperand* right = UseFixed(instr->right(), eax); | 831 LOperand* right = UseFixed(instr->right(), eax); |
| 842 LArithmeticT* result = new LArithmeticT(op, left, right); | 832 LArithmeticT* result = new LArithmeticT(op, context, left, right); |
| 843 return MarkAsCall(DefineFixed(result, eax), instr); | 833 return MarkAsCall(DefineFixed(result, eax), instr); |
| 844 } | 834 } |
| 845 | 835 |
| 846 ASSERT(instr->representation().IsInteger32()); | 836 ASSERT(instr->representation().IsInteger32()); |
| 847 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); | 837 ASSERT(instr->left()->representation().IsInteger32()); |
| 848 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); | 838 ASSERT(instr->right()->representation().IsInteger32()); |
| 849 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); | 839 LOperand* left = UseRegisterAtStart(instr->left()); |
| 850 | 840 |
| 851 HValue* right_value = instr->OperandAt(1); | 841 HValue* right_value = instr->right(); |
| 852 LOperand* right = NULL; | 842 LOperand* right = NULL; |
| 853 int constant_value = 0; | 843 int constant_value = 0; |
| 854 if (right_value->IsConstant()) { | 844 if (right_value->IsConstant()) { |
| 855 HConstant* constant = HConstant::cast(right_value); | 845 HConstant* constant = HConstant::cast(right_value); |
| 856 right = chunk_->DefineConstantOperand(constant); | 846 right = chunk_->DefineConstantOperand(constant); |
| 857 constant_value = constant->Integer32Value() & 0x1f; | 847 constant_value = constant->Integer32Value() & 0x1f; |
| 858 } else { | 848 } else { |
| 859 right = UseFixed(right_value, ecx); | 849 right = UseFixed(right_value, ecx); |
| 860 } | 850 } |
| 861 | 851 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 HArithmeticBinaryOperation* instr) { | 885 HArithmeticBinaryOperation* instr) { |
| 896 ASSERT(op == Token::ADD || | 886 ASSERT(op == Token::ADD || |
| 897 op == Token::DIV || | 887 op == Token::DIV || |
| 898 op == Token::MOD || | 888 op == Token::MOD || |
| 899 op == Token::MUL || | 889 op == Token::MUL || |
| 900 op == Token::SUB); | 890 op == Token::SUB); |
| 901 HValue* left = instr->left(); | 891 HValue* left = instr->left(); |
| 902 HValue* right = instr->right(); | 892 HValue* right = instr->right(); |
| 903 ASSERT(left->representation().IsTagged()); | 893 ASSERT(left->representation().IsTagged()); |
| 904 ASSERT(right->representation().IsTagged()); | 894 ASSERT(right->representation().IsTagged()); |
| 895 LOperand* context = UseFixed(instr->context(), esi); |
| 905 LOperand* left_operand = UseFixed(left, edx); | 896 LOperand* left_operand = UseFixed(left, edx); |
| 906 LOperand* right_operand = UseFixed(right, eax); | 897 LOperand* right_operand = UseFixed(right, eax); |
| 907 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand); | 898 LArithmeticT* result = |
| 899 new LArithmeticT(op, context, left_operand, right_operand); |
| 908 return MarkAsCall(DefineFixed(result, eax), instr); | 900 return MarkAsCall(DefineFixed(result, eax), instr); |
| 909 } | 901 } |
| 910 | 902 |
| 903 |
| 911 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 904 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| 912 ASSERT(is_building()); | 905 ASSERT(is_building()); |
| 913 current_block_ = block; | 906 current_block_ = block; |
| 914 next_block_ = next_block; | 907 next_block_ = next_block; |
| 915 if (block->IsStartBlock()) { | 908 if (block->IsStartBlock()) { |
| 916 block->UpdateEnvironment(graph_->start_environment()); | 909 block->UpdateEnvironment(graph_->start_environment()); |
| 917 argument_count_ = 0; | 910 argument_count_ = 0; |
| 918 } else if (block->predecessors()->length() == 1) { | 911 } else if (block->predecessors()->length() == 1) { |
| 919 // We have a single predecessor => copy environment and outgoing | 912 // We have a single predecessor => copy environment and outgoing |
| 920 // argument count from the predecessor. | 913 // argument count from the predecessor. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 if (current->has_position()) position_ = current->position(); | 970 if (current->has_position()) position_ = current->position(); |
| 978 LInstruction* instr = current->CompileToLithium(this); | 971 LInstruction* instr = current->CompileToLithium(this); |
| 979 | 972 |
| 980 if (instr != NULL) { | 973 if (instr != NULL) { |
| 981 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 974 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 982 instr = AssignPointerMap(instr); | 975 instr = AssignPointerMap(instr); |
| 983 } | 976 } |
| 984 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 977 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 985 instr = AssignEnvironment(instr); | 978 instr = AssignEnvironment(instr); |
| 986 } | 979 } |
| 987 if (current->IsTest() && !instr->IsGoto()) { | 980 instr->set_hydrogen_value(current); |
| 988 ASSERT(instr->IsControl()); | |
| 989 HTest* test = HTest::cast(current); | |
| 990 instr->set_hydrogen_value(test->value()); | |
| 991 HBasicBlock* first = test->FirstSuccessor(); | |
| 992 HBasicBlock* second = test->SecondSuccessor(); | |
| 993 ASSERT(first != NULL && second != NULL); | |
| 994 instr->SetBranchTargets(first->block_id(), second->block_id()); | |
| 995 } else { | |
| 996 instr->set_hydrogen_value(current); | |
| 997 } | |
| 998 | |
| 999 chunk_->AddInstruction(instr, current_block_); | 981 chunk_->AddInstruction(instr, current_block_); |
| 1000 } | 982 } |
| 1001 current_instruction_ = old_current; | 983 current_instruction_ = old_current; |
| 1002 } | 984 } |
| 1003 | 985 |
| 1004 | 986 |
| 1005 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { | 987 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { |
| 1006 if (hydrogen_env == NULL) return NULL; | 988 if (hydrogen_env == NULL) return NULL; |
| 1007 | 989 |
| 1008 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); | 990 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1029 op = UseAny(value); | 1011 op = UseAny(value); |
| 1030 } | 1012 } |
| 1031 result->AddValue(op, value->representation()); | 1013 result->AddValue(op, value->representation()); |
| 1032 } | 1014 } |
| 1033 | 1015 |
| 1034 return result; | 1016 return result; |
| 1035 } | 1017 } |
| 1036 | 1018 |
| 1037 | 1019 |
| 1038 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 1020 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 1039 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), | 1021 return new LGoto(instr->FirstSuccessor()->block_id()); |
| 1040 instr->include_stack_check()); | |
| 1041 return (instr->include_stack_check()) | |
| 1042 ? AssignPointerMap(result) | |
| 1043 : result; | |
| 1044 } | 1022 } |
| 1045 | 1023 |
| 1046 | 1024 |
| 1047 LInstruction* LChunkBuilder::DoTest(HTest* instr) { | 1025 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
| 1048 HValue* v = instr->value(); | 1026 HValue* v = instr->value(); |
| 1049 if (!v->EmitAtUses()) { | 1027 if (v->EmitAtUses()) { |
| 1050 return new LBranch(UseRegisterAtStart(v)); | 1028 ASSERT(v->IsConstant()); |
| 1051 } else if (v->IsClassOfTest()) { | 1029 ASSERT(!v->representation().IsDouble()); |
| 1052 HClassOfTest* compare = HClassOfTest::cast(v); | |
| 1053 ASSERT(compare->value()->representation().IsTagged()); | |
| 1054 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), | |
| 1055 TempRegister(), | |
| 1056 TempRegister()); | |
| 1057 } else if (v->IsCompare()) { | |
| 1058 HCompare* compare = HCompare::cast(v); | |
| 1059 Token::Value op = compare->token(); | |
| 1060 HValue* left = compare->left(); | |
| 1061 HValue* right = compare->right(); | |
| 1062 Representation r = compare->GetInputRepresentation(); | |
| 1063 if (r.IsInteger32()) { | |
| 1064 ASSERT(left->representation().IsInteger32()); | |
| 1065 ASSERT(right->representation().IsInteger32()); | |
| 1066 return new LCmpIDAndBranch(UseRegisterAtStart(left), | |
| 1067 UseOrConstantAtStart(right)); | |
| 1068 } else if (r.IsDouble()) { | |
| 1069 ASSERT(left->representation().IsDouble()); | |
| 1070 ASSERT(right->representation().IsDouble()); | |
| 1071 return new LCmpIDAndBranch(UseRegisterAtStart(left), | |
| 1072 UseRegisterAtStart(right)); | |
| 1073 } else { | |
| 1074 ASSERT(left->representation().IsTagged()); | |
| 1075 ASSERT(right->representation().IsTagged()); | |
| 1076 bool reversed = op == Token::GT || op == Token::LTE; | |
| 1077 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); | |
| 1078 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); | |
| 1079 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, right_operand); | |
| 1080 return MarkAsCall(result, instr); | |
| 1081 } | |
| 1082 } else if (v->IsIsSmi()) { | |
| 1083 HIsSmi* compare = HIsSmi::cast(v); | |
| 1084 ASSERT(compare->value()->representation().IsTagged()); | |
| 1085 return new LIsSmiAndBranch(Use(compare->value())); | |
| 1086 } else if (v->IsIsUndetectable()) { | |
| 1087 HIsUndetectable* compare = HIsUndetectable::cast(v); | |
| 1088 ASSERT(compare->value()->representation().IsTagged()); | |
| 1089 return new LIsUndetectableAndBranch(UseRegisterAtStart(compare->value()), | |
| 1090 TempRegister()); | |
| 1091 } else if (v->IsHasInstanceType()) { | |
| 1092 HHasInstanceType* compare = HHasInstanceType::cast(v); | |
| 1093 ASSERT(compare->value()->representation().IsTagged()); | |
| 1094 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()), | |
| 1095 TempRegister()); | |
| 1096 } else if (v->IsHasCachedArrayIndex()) { | |
| 1097 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); | |
| 1098 ASSERT(compare->value()->representation().IsTagged()); | |
| 1099 return new LHasCachedArrayIndexAndBranch( | |
| 1100 UseRegisterAtStart(compare->value())); | |
| 1101 } else if (v->IsIsNull()) { | |
| 1102 HIsNull* compare = HIsNull::cast(v); | |
| 1103 ASSERT(compare->value()->representation().IsTagged()); | |
| 1104 // We only need a temp register for non-strict compare. | |
| 1105 LOperand* temp = compare->is_strict() ? NULL : TempRegister(); | |
| 1106 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), temp); | |
| 1107 } else if (v->IsIsObject()) { | |
| 1108 HIsObject* compare = HIsObject::cast(v); | |
| 1109 ASSERT(compare->value()->representation().IsTagged()); | |
| 1110 LOperand* temp1 = TempRegister(); | |
| 1111 LOperand* temp2 = TempRegister(); | |
| 1112 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), | |
| 1113 temp1, | |
| 1114 temp2); | |
| 1115 } else if (v->IsCompareJSObjectEq()) { | |
| 1116 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | |
| 1117 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | |
| 1118 UseRegisterAtStart(compare->right())); | |
| 1119 } else if (v->IsCompareSymbolEq()) { | |
| 1120 HCompareSymbolEq* compare = HCompareSymbolEq::cast(v); | |
| 1121 return new LCmpSymbolEqAndBranch(UseRegisterAtStart(compare->left()), | |
| 1122 UseRegisterAtStart(compare->right())); | |
| 1123 } else if (v->IsInstanceOf()) { | |
| 1124 HInstanceOf* instance_of = HInstanceOf::cast(v); | |
| 1125 LOperand* left = UseFixed(instance_of->left(), InstanceofStub::left()); | |
| 1126 LOperand* right = UseFixed(instance_of->right(), InstanceofStub::right()); | |
| 1127 LOperand* context = UseFixed(instance_of->context(), esi); | |
| 1128 LInstanceOfAndBranch* result = | |
| 1129 new LInstanceOfAndBranch(context, left, right); | |
| 1130 return MarkAsCall(result, instr); | |
| 1131 } else if (v->IsTypeofIs()) { | |
| 1132 HTypeofIs* typeof_is = HTypeofIs::cast(v); | |
| 1133 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); | |
| 1134 } else if (v->IsIsConstructCall()) { | |
| 1135 return new LIsConstructCallAndBranch(TempRegister()); | |
| 1136 } else if (v->IsConstant()) { | |
| 1137 HBasicBlock* successor = HConstant::cast(v)->ToBoolean() | 1030 HBasicBlock* successor = HConstant::cast(v)->ToBoolean() |
| 1138 ? instr->FirstSuccessor() | 1031 ? instr->FirstSuccessor() |
| 1139 : instr->SecondSuccessor(); | 1032 : instr->SecondSuccessor(); |
| 1140 return new LGoto(successor->block_id()); | 1033 return new LGoto(successor->block_id()); |
| 1141 } else { | |
| 1142 Abort("Undefined compare before branch"); | |
| 1143 return NULL; | |
| 1144 } | 1034 } |
| 1035 return new LBranch(UseRegisterAtStart(v)); |
| 1145 } | 1036 } |
| 1146 | 1037 |
| 1147 | 1038 |
| 1148 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 1039 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1149 ASSERT(instr->value()->representation().IsTagged()); | 1040 ASSERT(instr->value()->representation().IsTagged()); |
| 1150 LOperand* value = UseRegisterAtStart(instr->value()); | 1041 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1151 return new LCmpMapAndBranch(value); | 1042 return new LCmpMapAndBranch(value); |
| 1152 } | 1043 } |
| 1153 | 1044 |
| 1154 | 1045 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1168 LOperand* context = UseFixed(instr->context(), esi); | 1059 LOperand* context = UseFixed(instr->context(), esi); |
| 1169 LInstanceOf* result = new LInstanceOf(context, left, right); | 1060 LInstanceOf* result = new LInstanceOf(context, left, right); |
| 1170 return MarkAsCall(DefineFixed(result, eax), instr); | 1061 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1171 } | 1062 } |
| 1172 | 1063 |
| 1173 | 1064 |
| 1174 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( | 1065 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
| 1175 HInstanceOfKnownGlobal* instr) { | 1066 HInstanceOfKnownGlobal* instr) { |
| 1176 LInstanceOfKnownGlobal* result = | 1067 LInstanceOfKnownGlobal* result = |
| 1177 new LInstanceOfKnownGlobal( | 1068 new LInstanceOfKnownGlobal( |
| 1178 UseFixed(instr->value(), InstanceofStub::left()), | 1069 UseFixed(instr->context(), esi), |
| 1070 UseFixed(instr->left(), InstanceofStub::left()), |
| 1179 FixedTemp(edi)); | 1071 FixedTemp(edi)); |
| 1180 return MarkAsCall(DefineFixed(result, eax), instr); | 1072 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1181 } | 1073 } |
| 1182 | 1074 |
| 1183 | 1075 |
| 1184 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { | 1076 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
| 1185 LOperand* function = UseFixed(instr->function(), edi); | 1077 LOperand* function = UseFixed(instr->function(), edi); |
| 1186 LOperand* receiver = UseFixed(instr->receiver(), eax); | 1078 LOperand* receiver = UseFixed(instr->receiver(), eax); |
| 1187 LOperand* length = UseFixed(instr->length(), ebx); | 1079 LOperand* length = UseFixed(instr->length(), ebx); |
| 1188 LOperand* elements = UseFixed(instr->elements(), ecx); | 1080 LOperand* elements = UseFixed(instr->elements(), ecx); |
| 1189 LOperand* temp = FixedTemp(edx); | 1081 LOperand* temp = FixedTemp(edx); |
| 1190 LApplyArguments* result = new LApplyArguments(function, | 1082 LApplyArguments* result = new LApplyArguments(function, |
| 1191 receiver, | 1083 receiver, |
| 1192 length, | 1084 length, |
| 1193 elements, | 1085 elements, |
| 1194 temp); | 1086 temp); |
| 1195 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1087 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1196 } | 1088 } |
| 1197 | 1089 |
| 1198 | 1090 |
| 1199 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1091 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1200 ++argument_count_; | 1092 ++argument_count_; |
| 1201 LOperand* argument = UseAny(instr->argument()); | 1093 LOperand* argument = UseAny(instr->argument()); |
| 1202 return new LPushArgument(argument); | 1094 return new LPushArgument(argument); |
| 1203 } | 1095 } |
| 1204 | 1096 |
| 1205 | 1097 |
| 1098 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { |
| 1099 return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction); |
| 1100 } |
| 1101 |
| 1102 |
| 1206 LInstruction* LChunkBuilder::DoContext(HContext* instr) { | 1103 LInstruction* LChunkBuilder::DoContext(HContext* instr) { |
| 1207 return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext); | 1104 return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext); |
| 1208 } | 1105 } |
| 1209 | 1106 |
| 1210 | 1107 |
| 1211 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { | 1108 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { |
| 1212 LOperand* context = UseRegisterAtStart(instr->value()); | 1109 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1213 return DefineAsRegister(new LOuterContext(context)); | 1110 return DefineAsRegister(new LOuterContext(context)); |
| 1214 } | 1111 } |
| 1215 | 1112 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1240 LInvokeFunction* result = new LInvokeFunction(context, function); | 1137 LInvokeFunction* result = new LInvokeFunction(context, function); |
| 1241 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY); | 1138 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY); |
| 1242 } | 1139 } |
| 1243 | 1140 |
| 1244 | 1141 |
| 1245 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1142 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1246 BuiltinFunctionId op = instr->op(); | 1143 BuiltinFunctionId op = instr->op(); |
| 1247 if (op == kMathLog) { | 1144 if (op == kMathLog) { |
| 1248 ASSERT(instr->representation().IsDouble()); | 1145 ASSERT(instr->representation().IsDouble()); |
| 1249 ASSERT(instr->value()->representation().IsDouble()); | 1146 ASSERT(instr->value()->representation().IsDouble()); |
| 1147 LOperand* context = UseAny(instr->context()); // Not actually used. |
| 1250 LOperand* input = UseRegisterAtStart(instr->value()); | 1148 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1251 LUnaryMathOperation* result = new LUnaryMathOperation(input); | 1149 LUnaryMathOperation* result = new LUnaryMathOperation(context, input); |
| 1252 return DefineSameAsFirst(result); | 1150 return DefineSameAsFirst(result); |
| 1253 } else if (op == kMathSin || op == kMathCos) { | 1151 } else if (op == kMathSin || op == kMathCos) { |
| 1152 LOperand* context = UseFixed(instr->context(), esi); |
| 1254 LOperand* input = UseFixedDouble(instr->value(), xmm1); | 1153 LOperand* input = UseFixedDouble(instr->value(), xmm1); |
| 1255 LUnaryMathOperation* result = new LUnaryMathOperation(input); | 1154 LUnaryMathOperation* result = new LUnaryMathOperation(context, input); |
| 1256 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1155 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
| 1257 } else { | 1156 } else { |
| 1258 LOperand* input = UseRegisterAtStart(instr->value()); | 1157 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1259 LUnaryMathOperation* result = new LUnaryMathOperation(input); | 1158 LOperand* context = UseAny(instr->context()); // Deferred use by MathAbs. |
| 1159 LUnaryMathOperation* result = new LUnaryMathOperation(context, input); |
| 1260 switch (op) { | 1160 switch (op) { |
| 1261 case kMathAbs: | 1161 case kMathAbs: |
| 1262 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1162 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1263 case kMathFloor: | 1163 case kMathFloor: |
| 1264 return AssignEnvironment(DefineAsRegister(result)); | 1164 return AssignEnvironment(DefineAsRegister(result)); |
| 1265 case kMathRound: | 1165 case kMathRound: |
| 1266 return AssignEnvironment(DefineAsRegister(result)); | 1166 return AssignEnvironment(DefineAsRegister(result)); |
| 1267 case kMathSqrt: | 1167 case kMathSqrt: |
| 1268 return DefineSameAsFirst(result); | 1168 return DefineSameAsFirst(result); |
| 1269 case kMathPowHalf: | 1169 case kMathPowHalf: |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1220 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1321 LOperand* context = UseFixed(instr->context(), esi); | 1221 LOperand* context = UseFixed(instr->context(), esi); |
| 1322 argument_count_ -= instr->argument_count(); | 1222 argument_count_ -= instr->argument_count(); |
| 1323 LCallFunction* result = new LCallFunction(context); | 1223 LCallFunction* result = new LCallFunction(context); |
| 1324 return MarkAsCall(DefineFixed(result, eax), instr); | 1224 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1325 } | 1225 } |
| 1326 | 1226 |
| 1327 | 1227 |
| 1328 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1228 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1329 argument_count_ -= instr->argument_count(); | 1229 argument_count_ -= instr->argument_count(); |
| 1330 return MarkAsCall(DefineFixed(new LCallRuntime, eax), instr); | 1230 LOperand* context = UseFixed(instr->context(), esi); |
| 1231 return MarkAsCall(DefineFixed(new LCallRuntime(context), eax), instr); |
| 1331 } | 1232 } |
| 1332 | 1233 |
| 1333 | 1234 |
| 1334 LInstruction* LChunkBuilder::DoShr(HShr* instr) { | 1235 LInstruction* LChunkBuilder::DoShr(HShr* instr) { |
| 1335 return DoShift(Token::SHR, instr); | 1236 return DoShift(Token::SHR, instr); |
| 1336 } | 1237 } |
| 1337 | 1238 |
| 1338 | 1239 |
| 1339 LInstruction* LChunkBuilder::DoSar(HSar* instr) { | 1240 LInstruction* LChunkBuilder::DoSar(HSar* instr) { |
| 1340 return DoShift(Token::SAR, instr); | 1241 return DoShift(Token::SAR, instr); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1500 LOperand* left = UseFixedDouble(instr->left(), xmm1); | 1401 LOperand* left = UseFixedDouble(instr->left(), xmm1); |
| 1501 LOperand* right = exponent_type.IsDouble() ? | 1402 LOperand* right = exponent_type.IsDouble() ? |
| 1502 UseFixedDouble(instr->right(), xmm2) : | 1403 UseFixedDouble(instr->right(), xmm2) : |
| 1503 UseFixed(instr->right(), eax); | 1404 UseFixed(instr->right(), eax); |
| 1504 LPower* result = new LPower(left, right); | 1405 LPower* result = new LPower(left, right); |
| 1505 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, | 1406 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, |
| 1506 CAN_DEOPTIMIZE_EAGERLY); | 1407 CAN_DEOPTIMIZE_EAGERLY); |
| 1507 } | 1408 } |
| 1508 | 1409 |
| 1509 | 1410 |
| 1510 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { | 1411 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
| 1511 Token::Value op = instr->token(); | 1412 Token::Value op = instr->token(); |
| 1413 ASSERT(instr->left()->representation().IsTagged()); |
| 1414 ASSERT(instr->right()->representation().IsTagged()); |
| 1415 bool reversed = (op == Token::GT || op == Token::LTE); |
| 1416 LOperand* context = UseFixed(instr->context(), esi); |
| 1417 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); |
| 1418 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); |
| 1419 LCmpT* result = new LCmpT(context, left, right); |
| 1420 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1421 } |
| 1422 |
| 1423 |
| 1424 LInstruction* LChunkBuilder::DoCompareIDAndBranch( |
| 1425 HCompareIDAndBranch* instr) { |
| 1512 Representation r = instr->GetInputRepresentation(); | 1426 Representation r = instr->GetInputRepresentation(); |
| 1513 if (r.IsInteger32()) { | 1427 if (r.IsInteger32()) { |
| 1514 ASSERT(instr->left()->representation().IsInteger32()); | 1428 ASSERT(instr->left()->representation().IsInteger32()); |
| 1515 ASSERT(instr->right()->representation().IsInteger32()); | 1429 ASSERT(instr->right()->representation().IsInteger32()); |
| 1516 LOperand* left = UseRegisterAtStart(instr->left()); | 1430 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1517 LOperand* right = UseOrConstantAtStart(instr->right()); | 1431 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1518 return DefineAsRegister(new LCmpID(left, right)); | 1432 return new LCmpIDAndBranch(left, right); |
| 1519 } else if (r.IsDouble()) { | 1433 } else { |
| 1434 ASSERT(r.IsDouble()); |
| 1520 ASSERT(instr->left()->representation().IsDouble()); | 1435 ASSERT(instr->left()->representation().IsDouble()); |
| 1521 ASSERT(instr->right()->representation().IsDouble()); | 1436 ASSERT(instr->right()->representation().IsDouble()); |
| 1522 LOperand* left = UseRegisterAtStart(instr->left()); | 1437 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1523 LOperand* right = UseRegisterAtStart(instr->right()); | 1438 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1524 return DefineAsRegister(new LCmpID(left, right)); | 1439 return new LCmpIDAndBranch(left, right); |
| 1525 } else { | |
| 1526 ASSERT(instr->left()->representation().IsTagged()); | |
| 1527 ASSERT(instr->right()->representation().IsTagged()); | |
| 1528 bool reversed = (op == Token::GT || op == Token::LTE); | |
| 1529 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); | |
| 1530 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); | |
| 1531 LCmpT* result = new LCmpT(left, right); | |
| 1532 return MarkAsCall(DefineFixed(result, eax), instr); | |
| 1533 } | 1440 } |
| 1534 } | 1441 } |
| 1535 | 1442 |
| 1536 | 1443 |
| 1537 LInstruction* LChunkBuilder::DoCompareJSObjectEq( | 1444 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
| 1538 HCompareJSObjectEq* instr) { | 1445 HCompareObjectEqAndBranch* instr) { |
| 1539 LOperand* left = UseRegisterAtStart(instr->left()); | 1446 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1540 LOperand* right = UseRegisterAtStart(instr->right()); | 1447 LOperand* right = UseAtStart(instr->right()); |
| 1541 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right); | 1448 return new LCmpObjectEqAndBranch(left, right); |
| 1542 return DefineAsRegister(result); | |
| 1543 } | 1449 } |
| 1544 | 1450 |
| 1545 | 1451 |
| 1546 LInstruction* LChunkBuilder::DoCompareSymbolEq( | 1452 LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch( |
| 1547 HCompareSymbolEq* instr) { | 1453 HCompareConstantEqAndBranch* instr) { |
| 1548 LOperand* left = UseRegisterAtStart(instr->left()); | 1454 return new LCmpConstantEqAndBranch(UseRegisterAtStart(instr->value())); |
| 1549 LOperand* right = UseRegisterAtStart(instr->right()); | |
| 1550 LCmpSymbolEq* result = new LCmpSymbolEq(left, right); | |
| 1551 return DefineAsRegister(result); | |
| 1552 } | 1455 } |
| 1553 | 1456 |
| 1554 | 1457 |
| 1555 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { | 1458 LInstruction* LChunkBuilder::DoIsNullAndBranch(HIsNullAndBranch* instr) { |
| 1556 ASSERT(instr->value()->representation().IsTagged()); | 1459 // We only need a temp register for non-strict compare. |
| 1557 LOperand* value = UseRegisterAtStart(instr->value()); | 1460 LOperand* temp = instr->is_strict() ? NULL : TempRegister(); |
| 1558 | 1461 return new LIsNullAndBranch(UseRegisterAtStart(instr->value()), temp); |
| 1559 return DefineAsRegister(new LIsNull(value)); | |
| 1560 } | 1462 } |
| 1561 | 1463 |
| 1562 | 1464 |
| 1563 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { | 1465 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
| 1564 ASSERT(instr->value()->representation().IsTagged()); | 1466 ASSERT(instr->value()->representation().IsTagged()); |
| 1565 LOperand* value = UseRegister(instr->value()); | 1467 LOperand* temp = TempRegister(); |
| 1566 | 1468 return new LIsObjectAndBranch(UseRegister(instr->value()), temp); |
| 1567 return DefineAsRegister(new LIsObject(value, TempRegister())); | |
| 1568 } | 1469 } |
| 1569 | 1470 |
| 1570 | 1471 |
| 1571 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { | 1472 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { |
| 1572 ASSERT(instr->value()->representation().IsTagged()); | 1473 ASSERT(instr->value()->representation().IsTagged()); |
| 1573 LOperand* value = UseAtStart(instr->value()); | 1474 return new LIsSmiAndBranch(Use(instr->value())); |
| 1574 | |
| 1575 return DefineAsRegister(new LIsSmi(value)); | |
| 1576 } | 1475 } |
| 1577 | 1476 |
| 1578 | 1477 |
| 1579 LInstruction* LChunkBuilder::DoIsUndetectable(HIsUndetectable* instr) { | 1478 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( |
| 1580 ASSERT(instr->value()->representation().IsTagged()); | 1479 HIsUndetectableAndBranch* instr) { |
| 1581 LOperand* value = UseRegisterAtStart(instr->value()); | 1480 ASSERT(instr ->value()->representation().IsTagged()); |
| 1582 | 1481 return new LIsUndetectableAndBranch(UseRegisterAtStart(instr->value()), |
| 1583 return DefineAsRegister(new LIsUndetectable(value)); | 1482 TempRegister()); |
| 1584 } | 1483 } |
| 1585 | 1484 |
| 1586 | 1485 |
| 1587 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { | 1486 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( |
| 1487 HHasInstanceTypeAndBranch* instr) { |
| 1588 ASSERT(instr->value()->representation().IsTagged()); | 1488 ASSERT(instr->value()->representation().IsTagged()); |
| 1589 LOperand* value = UseRegisterAtStart(instr->value()); | 1489 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(instr->value()), |
| 1590 | 1490 TempRegister()); |
| 1591 return DefineAsRegister(new LHasInstanceType(value)); | |
| 1592 } | 1491 } |
| 1593 | 1492 |
| 1594 | 1493 |
| 1595 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( | 1494 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
| 1596 HGetCachedArrayIndex* instr) { | 1495 HGetCachedArrayIndex* instr) { |
| 1597 ASSERT(instr->value()->representation().IsTagged()); | 1496 ASSERT(instr->value()->representation().IsTagged()); |
| 1598 LOperand* value = UseRegisterAtStart(instr->value()); | 1497 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1599 | 1498 |
| 1600 return DefineAsRegister(new LGetCachedArrayIndex(value)); | 1499 return DefineAsRegister(new LGetCachedArrayIndex(value)); |
| 1601 } | 1500 } |
| 1602 | 1501 |
| 1603 | 1502 |
| 1604 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( | 1503 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( |
| 1605 HHasCachedArrayIndex* instr) { | 1504 HHasCachedArrayIndexAndBranch* instr) { |
| 1606 ASSERT(instr->value()->representation().IsTagged()); | 1505 ASSERT(instr->value()->representation().IsTagged()); |
| 1607 LOperand* value = UseRegister(instr->value()); | 1506 return new LHasCachedArrayIndexAndBranch( |
| 1608 | 1507 UseRegisterAtStart(instr->value())); |
| 1609 return DefineAsRegister(new LHasCachedArrayIndex(value)); | |
| 1610 } | 1508 } |
| 1611 | 1509 |
| 1612 | 1510 |
| 1613 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { | 1511 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
| 1512 HClassOfTestAndBranch* instr) { |
| 1614 ASSERT(instr->value()->representation().IsTagged()); | 1513 ASSERT(instr->value()->representation().IsTagged()); |
| 1615 LOperand* value = UseTempRegister(instr->value()); | 1514 return new LClassOfTestAndBranch(UseTempRegister(instr->value()), |
| 1616 | 1515 TempRegister(), |
| 1617 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); | 1516 TempRegister()); |
| 1618 } | 1517 } |
| 1619 | 1518 |
| 1620 | 1519 |
| 1621 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { | 1520 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { |
| 1622 LOperand* array = UseRegisterAtStart(instr->value()); | 1521 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1623 return DefineAsRegister(new LJSArrayLength(array)); | 1522 return DefineAsRegister(new LJSArrayLength(array)); |
| 1624 } | 1523 } |
| 1625 | 1524 |
| 1626 | 1525 |
| 1627 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { | 1526 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
| 1628 LOperand* array = UseRegisterAtStart(instr->value()); | 1527 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1629 return DefineAsRegister(new LFixedArrayLength(array)); | 1528 return DefineAsRegister(new LFixedArrayLength(array)); |
| 1630 } | 1529 } |
| 1631 | 1530 |
| 1632 | 1531 |
| 1633 LInstruction* LChunkBuilder::DoExternalArrayLength( | 1532 LInstruction* LChunkBuilder::DoExternalArrayLength( |
| 1634 HExternalArrayLength* instr) { | 1533 HExternalArrayLength* instr) { |
| 1635 LOperand* array = UseRegisterAtStart(instr->value()); | 1534 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1636 return DefineAsRegister(new LExternalArrayLength(array)); | 1535 return DefineAsRegister(new LExternalArrayLength(array)); |
| 1637 } | 1536 } |
| 1638 | 1537 |
| 1639 | 1538 |
| 1539 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) { |
| 1540 LOperand* object = UseRegisterAtStart(instr->value()); |
| 1541 return DefineAsRegister(new LElementsKind(object)); |
| 1542 } |
| 1543 |
| 1544 |
| 1640 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1545 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
| 1641 LOperand* object = UseRegister(instr->value()); | 1546 LOperand* object = UseRegister(instr->value()); |
| 1642 LValueOf* result = new LValueOf(object, TempRegister()); | 1547 LValueOf* result = new LValueOf(object, TempRegister()); |
| 1643 return AssignEnvironment(DefineSameAsFirst(result)); | 1548 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1644 } | 1549 } |
| 1645 | 1550 |
| 1646 | 1551 |
| 1647 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1552 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1648 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), | 1553 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
| 1649 Use(instr->length()))); | 1554 UseAtStart(instr->length()))); |
| 1650 } | 1555 } |
| 1651 | 1556 |
| 1652 | 1557 |
| 1653 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { | 1558 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| 1654 // The control instruction marking the end of a block that completed | 1559 // The control instruction marking the end of a block that completed |
| 1655 // abruptly (e.g., threw an exception). There is nothing specific to do. | 1560 // abruptly (e.g., threw an exception). There is nothing specific to do. |
| 1656 return NULL; | 1561 return NULL; |
| 1657 } | 1562 } |
| 1658 | 1563 |
| 1659 | 1564 |
| 1660 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1565 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
| 1566 LOperand* context = UseFixed(instr->context(), esi); |
| 1661 LOperand* value = UseFixed(instr->value(), eax); | 1567 LOperand* value = UseFixed(instr->value(), eax); |
| 1662 return MarkAsCall(new LThrow(value), instr); | 1568 return MarkAsCall(new LThrow(context, value), instr); |
| 1569 } |
| 1570 |
| 1571 |
| 1572 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { |
| 1573 return NULL; |
| 1663 } | 1574 } |
| 1664 | 1575 |
| 1665 | 1576 |
| 1666 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { | 1577 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { |
| 1667 // All HForceRepresentation instructions should be eliminated in the | 1578 // All HForceRepresentation instructions should be eliminated in the |
| 1668 // representation change phase of Hydrogen. | 1579 // representation change phase of Hydrogen. |
| 1669 UNREACHABLE(); | 1580 UNREACHABLE(); |
| 1670 return NULL; | 1581 return NULL; |
| 1671 } | 1582 } |
| 1672 | 1583 |
| 1673 | 1584 |
| 1674 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1585 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
| 1675 Representation from = instr->from(); | 1586 Representation from = instr->from(); |
| 1676 Representation to = instr->to(); | 1587 Representation to = instr->to(); |
| 1677 if (from.IsTagged()) { | 1588 if (from.IsTagged()) { |
| 1678 if (to.IsDouble()) { | 1589 if (to.IsDouble()) { |
| 1679 LOperand* value = UseRegister(instr->value()); | 1590 LOperand* value = UseRegister(instr->value()); |
| 1680 LNumberUntagD* res = new LNumberUntagD(value); | 1591 LNumberUntagD* res = new LNumberUntagD(value); |
| 1681 return AssignEnvironment(DefineAsRegister(res)); | 1592 return AssignEnvironment(DefineAsRegister(res)); |
| 1682 } else { | 1593 } else { |
| 1683 ASSERT(to.IsInteger32()); | 1594 ASSERT(to.IsInteger32()); |
| 1684 LOperand* value = UseRegister(instr->value()); | 1595 LOperand* value = UseRegister(instr->value()); |
| 1685 bool needs_check = !instr->value()->type().IsSmi(); | 1596 bool needs_check = !instr->value()->type().IsSmi(); |
| 1686 if (needs_check) { | 1597 if (needs_check) { |
| 1598 bool truncating = instr->CanTruncateToInt32(); |
| 1687 LOperand* xmm_temp = | 1599 LOperand* xmm_temp = |
| 1688 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) | 1600 (truncating && CpuFeatures::IsSupported(SSE3)) |
| 1689 ? NULL | 1601 ? NULL |
| 1690 : FixedTemp(xmm1); | 1602 : FixedTemp(xmm1); |
| 1691 LTaggedToI* res = new LTaggedToI(value, xmm_temp); | 1603 LTaggedToI* res = new LTaggedToI(value, xmm_temp); |
| 1692 return AssignEnvironment(DefineSameAsFirst(res)); | 1604 return AssignEnvironment(DefineSameAsFirst(res)); |
| 1693 } else { | 1605 } else { |
| 1694 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); | 1606 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); |
| 1695 } | 1607 } |
| 1696 } | 1608 } |
| 1697 } else if (from.IsDouble()) { | 1609 } else if (from.IsDouble()) { |
| 1698 if (to.IsTagged()) { | 1610 if (to.IsTagged()) { |
| 1699 LOperand* value = UseRegister(instr->value()); | 1611 LOperand* value = UseRegister(instr->value()); |
| 1700 LOperand* temp = TempRegister(); | 1612 LOperand* temp = TempRegister(); |
| 1701 | 1613 |
| 1702 // Make sure that temp and result_temp are different registers. | 1614 // Make sure that temp and result_temp are different registers. |
| 1703 LUnallocated* result_temp = TempRegister(); | 1615 LUnallocated* result_temp = TempRegister(); |
| 1704 LNumberTagD* result = new LNumberTagD(value, temp); | 1616 LNumberTagD* result = new LNumberTagD(value, temp); |
| 1705 return AssignPointerMap(Define(result, result_temp)); | 1617 return AssignPointerMap(Define(result, result_temp)); |
| 1706 } else { | 1618 } else { |
| 1707 ASSERT(to.IsInteger32()); | 1619 ASSERT(to.IsInteger32()); |
| 1708 bool needs_temp = instr->CanTruncateToInt32() && | 1620 bool truncating = instr->CanTruncateToInt32(); |
| 1709 !CpuFeatures::IsSupported(SSE3); | 1621 bool needs_temp = truncating && !CpuFeatures::IsSupported(SSE3); |
| 1710 LOperand* value = needs_temp ? | 1622 LOperand* value = needs_temp ? |
| 1711 UseTempRegister(instr->value()) : UseRegister(instr->value()); | 1623 UseTempRegister(instr->value()) : UseRegister(instr->value()); |
| 1712 LOperand* temp = needs_temp ? TempRegister() : NULL; | 1624 LOperand* temp = needs_temp ? TempRegister() : NULL; |
| 1713 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp))); | 1625 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp))); |
| 1714 } | 1626 } |
| 1715 } else if (from.IsInteger32()) { | 1627 } else if (from.IsInteger32()) { |
| 1716 if (to.IsTagged()) { | 1628 if (to.IsTagged()) { |
| 1717 HValue* val = instr->value(); | 1629 HValue* val = instr->value(); |
| 1718 LOperand* value = UseRegister(val); | 1630 LOperand* value = UseRegister(val); |
| 1719 if (val->HasRange() && val->range()->IsInSmiRange()) { | 1631 if (val->HasRange() && val->range()->IsInSmiRange()) { |
| 1720 return DefineSameAsFirst(new LSmiTag(value)); | 1632 return DefineSameAsFirst(new LSmiTag(value)); |
| 1721 } else { | 1633 } else { |
| 1722 LNumberTagI* result = new LNumberTagI(value); | 1634 LNumberTagI* result = new LNumberTagI(value); |
| 1723 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1635 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1724 } | 1636 } |
| 1725 } else { | 1637 } else { |
| 1726 ASSERT(to.IsDouble()); | 1638 ASSERT(to.IsDouble()); |
| 1727 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); | 1639 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); |
| 1728 } | 1640 } |
| 1729 } | 1641 } |
| 1730 UNREACHABLE(); | 1642 UNREACHABLE(); |
| 1731 return NULL; | 1643 return NULL; |
| 1732 } | 1644 } |
| 1733 | 1645 |
| 1734 | 1646 |
| 1735 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { | 1647 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { |
| 1736 LOperand* value = UseRegisterAtStart(instr->value()); | 1648 LOperand* value = UseAtStart(instr->value()); |
| 1737 return AssignEnvironment(new LCheckNonSmi(value)); | 1649 return AssignEnvironment(new LCheckNonSmi(value)); |
| 1738 } | 1650 } |
| 1739 | 1651 |
| 1740 | 1652 |
| 1741 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 1653 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
| 1742 LOperand* value = UseRegisterAtStart(instr->value()); | 1654 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1743 LOperand* temp = TempRegister(); | 1655 LOperand* temp = TempRegister(); |
| 1744 LCheckInstanceType* result = new LCheckInstanceType(value, temp); | 1656 LCheckInstanceType* result = new LCheckInstanceType(value, temp); |
| 1745 return AssignEnvironment(result); | 1657 return AssignEnvironment(result); |
| 1746 } | 1658 } |
| 1747 | 1659 |
| 1748 | 1660 |
| 1749 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { | 1661 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
| 1750 LOperand* temp = TempRegister(); | 1662 LOperand* temp = TempRegister(); |
| 1751 LCheckPrototypeMaps* result = new LCheckPrototypeMaps(temp); | 1663 LCheckPrototypeMaps* result = new LCheckPrototypeMaps(temp); |
| 1752 return AssignEnvironment(result); | 1664 return AssignEnvironment(result); |
| 1753 } | 1665 } |
| 1754 | 1666 |
| 1755 | 1667 |
| 1756 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { | 1668 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { |
| 1757 LOperand* value = UseRegisterAtStart(instr->value()); | 1669 LOperand* value = UseAtStart(instr->value()); |
| 1758 return AssignEnvironment(new LCheckSmi(value)); | 1670 return AssignEnvironment(new LCheckSmi(value)); |
| 1759 } | 1671 } |
| 1760 | 1672 |
| 1761 | 1673 |
| 1762 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { | 1674 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { |
| 1763 LOperand* value = UseRegisterAtStart(instr->value()); | 1675 LOperand* value = UseAtStart(instr->value()); |
| 1764 return AssignEnvironment(new LCheckFunction(value)); | 1676 return AssignEnvironment(new LCheckFunction(value)); |
| 1765 } | 1677 } |
| 1766 | 1678 |
| 1767 | 1679 |
| 1768 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { | 1680 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { |
| 1769 LOperand* value = UseRegisterAtStart(instr->value()); | 1681 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1770 LCheckMap* result = new LCheckMap(value); | 1682 LCheckMap* result = new LCheckMap(value); |
| 1771 return AssignEnvironment(result); | 1683 return AssignEnvironment(result); |
| 1772 } | 1684 } |
| 1773 | 1685 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1786 LOperand* reg = UseFixed(value, eax); | 1698 LOperand* reg = UseFixed(value, eax); |
| 1787 // Register allocator doesn't (yet) support allocation of double | 1699 // Register allocator doesn't (yet) support allocation of double |
| 1788 // temps. Reserve xmm1 explicitly. | 1700 // temps. Reserve xmm1 explicitly. |
| 1789 LOperand* temp = FixedTemp(xmm1); | 1701 LOperand* temp = FixedTemp(xmm1); |
| 1790 LClampTToUint8* result = new LClampTToUint8(reg, temp); | 1702 LClampTToUint8* result = new LClampTToUint8(reg, temp); |
| 1791 return AssignEnvironment(DefineFixed(result, eax)); | 1703 return AssignEnvironment(DefineFixed(result, eax)); |
| 1792 } | 1704 } |
| 1793 } | 1705 } |
| 1794 | 1706 |
| 1795 | 1707 |
| 1708 LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) { |
| 1709 HValue* value = instr->value(); |
| 1710 Representation input_rep = value->representation(); |
| 1711 |
| 1712 LInstruction* result; |
| 1713 if (input_rep.IsDouble()) { |
| 1714 LOperand* reg = UseRegister(value); |
| 1715 LOperand* temp_reg = |
| 1716 CpuFeatures::IsSupported(SSE3) ? NULL : TempRegister(); |
| 1717 result = DefineAsRegister(new LDoubleToI(reg, temp_reg)); |
| 1718 } else if (input_rep.IsInteger32()) { |
| 1719 // Canonicalization should already have removed the hydrogen instruction in |
| 1720 // this case, since it is a noop. |
| 1721 UNREACHABLE(); |
| 1722 return NULL; |
| 1723 } else { |
| 1724 ASSERT(input_rep.IsTagged()); |
| 1725 LOperand* reg = UseRegister(value); |
| 1726 // Register allocator doesn't (yet) support allocation of double |
| 1727 // temps. Reserve xmm1 explicitly. |
| 1728 LOperand* xmm_temp = |
| 1729 CpuFeatures::IsSupported(SSE3) ? NULL : FixedTemp(xmm1); |
| 1730 result = DefineSameAsFirst(new LTaggedToI(reg, xmm_temp)); |
| 1731 } |
| 1732 return AssignEnvironment(result); |
| 1733 } |
| 1734 |
| 1735 |
| 1796 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1736 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
| 1797 return new LReturn(UseFixed(instr->value(), eax)); | 1737 return new LReturn(UseFixed(instr->value(), eax)); |
| 1798 } | 1738 } |
| 1799 | 1739 |
| 1800 | 1740 |
| 1801 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1741 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1802 Representation r = instr->representation(); | 1742 Representation r = instr->representation(); |
| 1803 if (r.IsInteger32()) { | 1743 if (r.IsInteger32()) { |
| 1804 return DefineAsRegister(new LConstantI); | 1744 return DefineAsRegister(new LConstantI); |
| 1805 } else if (r.IsDouble()) { | 1745 } else if (r.IsDouble()) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1876 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1816 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 1877 ASSERT(instr->representation().IsTagged()); | 1817 ASSERT(instr->representation().IsTagged()); |
| 1878 LOperand* obj = UseRegisterAtStart(instr->object()); | 1818 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1879 return DefineAsRegister(new LLoadNamedField(obj)); | 1819 return DefineAsRegister(new LLoadNamedField(obj)); |
| 1880 } | 1820 } |
| 1881 | 1821 |
| 1882 | 1822 |
| 1883 LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( | 1823 LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( |
| 1884 HLoadNamedFieldPolymorphic* instr) { | 1824 HLoadNamedFieldPolymorphic* instr) { |
| 1885 ASSERT(instr->representation().IsTagged()); | 1825 ASSERT(instr->representation().IsTagged()); |
| 1826 LOperand* context = UseFixed(instr->context(), esi); |
| 1886 if (instr->need_generic()) { | 1827 if (instr->need_generic()) { |
| 1887 LOperand* obj = UseFixed(instr->object(), eax); | 1828 LOperand* obj = UseFixed(instr->object(), eax); |
| 1888 LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj); | 1829 LLoadNamedFieldPolymorphic* result = |
| 1830 new LLoadNamedFieldPolymorphic(context, obj); |
| 1889 return MarkAsCall(DefineFixed(result, eax), instr); | 1831 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1890 } else { | 1832 } else { |
| 1891 LOperand* obj = UseRegisterAtStart(instr->object()); | 1833 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1892 LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj); | 1834 LLoadNamedFieldPolymorphic* result = |
| 1835 new LLoadNamedFieldPolymorphic(context, obj); |
| 1893 return AssignEnvironment(DefineAsRegister(result)); | 1836 return AssignEnvironment(DefineAsRegister(result)); |
| 1894 } | 1837 } |
| 1895 } | 1838 } |
| 1896 | 1839 |
| 1897 | 1840 |
| 1898 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1841 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 1899 LOperand* context = UseFixed(instr->context(), esi); | 1842 LOperand* context = UseFixed(instr->context(), esi); |
| 1900 LOperand* object = UseFixed(instr->object(), eax); | 1843 LOperand* object = UseFixed(instr->object(), eax); |
| 1901 LLoadNamedGeneric* result = new LLoadNamedGeneric(context, object); | 1844 LLoadNamedGeneric* result = new LLoadNamedGeneric(context, object); |
| 1902 return MarkAsCall(DefineFixed(result, eax), instr); | 1845 return MarkAsCall(DefineFixed(result, eax), instr); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1930 ASSERT(instr->key()->representation().IsInteger32()); | 1873 ASSERT(instr->key()->representation().IsInteger32()); |
| 1931 LOperand* obj = UseRegisterAtStart(instr->object()); | 1874 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1932 LOperand* key = UseRegisterAtStart(instr->key()); | 1875 LOperand* key = UseRegisterAtStart(instr->key()); |
| 1933 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); | 1876 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); |
| 1934 return AssignEnvironment(DefineSameAsFirst(result)); | 1877 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1935 } | 1878 } |
| 1936 | 1879 |
| 1937 | 1880 |
| 1938 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( | 1881 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( |
| 1939 HLoadKeyedSpecializedArrayElement* instr) { | 1882 HLoadKeyedSpecializedArrayElement* instr) { |
| 1940 ExternalArrayType array_type = instr->array_type(); | 1883 JSObject::ElementsKind elements_kind = instr->elements_kind(); |
| 1941 Representation representation(instr->representation()); | 1884 Representation representation(instr->representation()); |
| 1942 ASSERT( | 1885 ASSERT( |
| 1943 (representation.IsInteger32() && (array_type != kExternalFloatArray && | 1886 (representation.IsInteger32() && |
| 1944 array_type != kExternalDoubleArray)) || | 1887 (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && |
| 1945 (representation.IsDouble() && (array_type == kExternalFloatArray || | 1888 (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || |
| 1946 array_type == kExternalDoubleArray))); | 1889 (representation.IsDouble() && |
| 1890 ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || |
| 1891 (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); |
| 1947 ASSERT(instr->key()->representation().IsInteger32()); | 1892 ASSERT(instr->key()->representation().IsInteger32()); |
| 1948 LOperand* external_pointer = UseRegister(instr->external_pointer()); | 1893 LOperand* external_pointer = UseRegister(instr->external_pointer()); |
| 1949 LOperand* key = UseRegisterOrConstant(instr->key()); | 1894 LOperand* key = UseRegisterOrConstant(instr->key()); |
| 1950 LLoadKeyedSpecializedArrayElement* result = | 1895 LLoadKeyedSpecializedArrayElement* result = |
| 1951 new LLoadKeyedSpecializedArrayElement(external_pointer, | 1896 new LLoadKeyedSpecializedArrayElement(external_pointer, |
| 1952 key); | 1897 key); |
| 1953 LInstruction* load_instr = DefineAsRegister(result); | 1898 LInstruction* load_instr = DefineAsRegister(result); |
| 1954 // An unsigned int array load might overflow and cause a deopt, make sure it | 1899 // An unsigned int array load might overflow and cause a deopt, make sure it |
| 1955 // has an environment. | 1900 // has an environment. |
| 1956 return (array_type == kExternalUnsignedIntArray) | 1901 return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) |
| 1957 ? AssignEnvironment(load_instr) | 1902 ? AssignEnvironment(load_instr) |
| 1958 : load_instr; | 1903 : load_instr; |
| 1959 } | 1904 } |
| 1960 | 1905 |
| 1961 | 1906 |
| 1962 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1907 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 1963 LOperand* context = UseFixed(instr->context(), esi); | 1908 LOperand* context = UseFixed(instr->context(), esi); |
| 1964 LOperand* object = UseFixed(instr->object(), edx); | 1909 LOperand* object = UseFixed(instr->object(), edx); |
| 1965 LOperand* key = UseFixed(instr->key(), eax); | 1910 LOperand* key = UseFixed(instr->key(), eax); |
| 1966 | 1911 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1984 ? UseTempRegister(instr->key()) | 1929 ? UseTempRegister(instr->key()) |
| 1985 : UseRegisterOrConstantAtStart(instr->key()); | 1930 : UseRegisterOrConstantAtStart(instr->key()); |
| 1986 | 1931 |
| 1987 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); | 1932 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); |
| 1988 } | 1933 } |
| 1989 | 1934 |
| 1990 | 1935 |
| 1991 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( | 1936 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( |
| 1992 HStoreKeyedSpecializedArrayElement* instr) { | 1937 HStoreKeyedSpecializedArrayElement* instr) { |
| 1993 Representation representation(instr->value()->representation()); | 1938 Representation representation(instr->value()->representation()); |
| 1994 ExternalArrayType array_type = instr->array_type(); | 1939 JSObject::ElementsKind elements_kind = instr->elements_kind(); |
| 1995 ASSERT( | 1940 ASSERT( |
| 1996 (representation.IsInteger32() && (array_type != kExternalFloatArray && | 1941 (representation.IsInteger32() && |
| 1997 array_type != kExternalDoubleArray)) || | 1942 (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && |
| 1998 (representation.IsDouble() && (array_type == kExternalFloatArray || | 1943 (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || |
| 1999 array_type == kExternalDoubleArray))); | 1944 (representation.IsDouble() && |
| 1945 ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || |
| 1946 (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); |
| 2000 ASSERT(instr->external_pointer()->representation().IsExternal()); | 1947 ASSERT(instr->external_pointer()->representation().IsExternal()); |
| 2001 ASSERT(instr->key()->representation().IsInteger32()); | 1948 ASSERT(instr->key()->representation().IsInteger32()); |
| 2002 | 1949 |
| 2003 LOperand* external_pointer = UseRegister(instr->external_pointer()); | 1950 LOperand* external_pointer = UseRegister(instr->external_pointer()); |
| 2004 LOperand* key = UseRegisterOrConstant(instr->key()); | 1951 LOperand* key = UseRegisterOrConstant(instr->key()); |
| 2005 LOperand* val = NULL; | 1952 LOperand* val = NULL; |
| 2006 if (array_type == kExternalByteArray || | 1953 if (elements_kind == JSObject::EXTERNAL_BYTE_ELEMENTS || |
| 2007 array_type == kExternalUnsignedByteArray || | 1954 elements_kind == JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS || |
| 2008 array_type == kExternalPixelArray) { | 1955 elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { |
| 2009 // We need a byte register in this case for the value. | 1956 // We need a byte register in this case for the value. |
| 2010 val = UseFixed(instr->value(), eax); | 1957 val = UseFixed(instr->value(), eax); |
| 2011 } else { | 1958 } else { |
| 2012 val = UseRegister(instr->value()); | 1959 val = UseRegister(instr->value()); |
| 2013 } | 1960 } |
| 2014 | 1961 |
| 2015 return new LStoreKeyedSpecializedArrayElement(external_pointer, | 1962 return new LStoreKeyedSpecializedArrayElement(external_pointer, |
| 2016 key, | 1963 key, |
| 2017 val); | 1964 val); |
| 2018 } | 1965 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2064 LOperand* context = UseFixed(instr->context(), esi); | 2011 LOperand* context = UseFixed(instr->context(), esi); |
| 2065 LOperand* object = UseFixed(instr->object(), edx); | 2012 LOperand* object = UseFixed(instr->object(), edx); |
| 2066 LOperand* value = UseFixed(instr->value(), eax); | 2013 LOperand* value = UseFixed(instr->value(), eax); |
| 2067 | 2014 |
| 2068 LStoreNamedGeneric* result = new LStoreNamedGeneric(context, object, value); | 2015 LStoreNamedGeneric* result = new LStoreNamedGeneric(context, object, value); |
| 2069 return MarkAsCall(result, instr); | 2016 return MarkAsCall(result, instr); |
| 2070 } | 2017 } |
| 2071 | 2018 |
| 2072 | 2019 |
| 2073 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { | 2020 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { |
| 2021 LOperand* context = UseFixed(instr->context(), esi); |
| 2074 LOperand* left = UseOrConstantAtStart(instr->left()); | 2022 LOperand* left = UseOrConstantAtStart(instr->left()); |
| 2075 LOperand* right = UseOrConstantAtStart(instr->right()); | 2023 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 2076 return MarkAsCall(DefineFixed(new LStringAdd(left, right), eax), instr); | 2024 LStringAdd* string_add = new LStringAdd(context, left, right); |
| 2025 return MarkAsCall(DefineFixed(string_add, eax), instr); |
| 2077 } | 2026 } |
| 2078 | 2027 |
| 2079 | 2028 |
| 2080 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 2029 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 2081 LOperand* string = UseRegister(instr->string()); | 2030 LOperand* string = UseRegister(instr->string()); |
| 2082 LOperand* index = UseRegisterOrConstant(instr->index()); | 2031 LOperand* index = UseRegisterOrConstant(instr->index()); |
| 2083 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); | 2032 LOperand* context = UseAny(instr->context()); |
| 2033 LStringCharCodeAt* result = new LStringCharCodeAt(context, string, index); |
| 2084 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 2034 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 2085 } | 2035 } |
| 2086 | 2036 |
| 2087 | 2037 |
| 2088 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { | 2038 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { |
| 2089 LOperand* char_code = UseRegister(instr->value()); | 2039 LOperand* char_code = UseRegister(instr->value()); |
| 2090 LStringCharFromCode* result = new LStringCharFromCode(char_code); | 2040 LOperand* context = UseAny(instr->context()); |
| 2041 LStringCharFromCode* result = new LStringCharFromCode(context, char_code); |
| 2091 return AssignPointerMap(DefineAsRegister(result)); | 2042 return AssignPointerMap(DefineAsRegister(result)); |
| 2092 } | 2043 } |
| 2093 | 2044 |
| 2094 | 2045 |
| 2095 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { | 2046 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 2096 LOperand* string = UseRegisterAtStart(instr->value()); | 2047 LOperand* string = UseRegisterAtStart(instr->value()); |
| 2097 return DefineAsRegister(new LStringLength(string)); | 2048 return DefineAsRegister(new LStringLength(string)); |
| 2098 } | 2049 } |
| 2099 | 2050 |
| 2100 | 2051 |
| 2101 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 2052 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 2102 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); | 2053 LOperand* context = UseFixed(instr->context(), esi); |
| 2054 return MarkAsCall(DefineFixed(new LArrayLiteral(context), eax), instr); |
| 2103 } | 2055 } |
| 2104 | 2056 |
| 2105 | 2057 |
| 2106 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 2058 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 2107 LOperand* context = UseFixed(instr->context(), esi); | 2059 LOperand* context = UseFixed(instr->context(), esi); |
| 2108 return MarkAsCall(DefineFixed(new LObjectLiteral(context), eax), instr); | 2060 return MarkAsCall(DefineFixed(new LObjectLiteral(context), eax), instr); |
| 2109 } | 2061 } |
| 2110 | 2062 |
| 2111 | 2063 |
| 2112 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 2064 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 2113 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); | 2065 LOperand* context = UseFixed(instr->context(), esi); |
| 2066 return MarkAsCall(DefineFixed(new LRegExpLiteral(context), eax), instr); |
| 2114 } | 2067 } |
| 2115 | 2068 |
| 2116 | 2069 |
| 2117 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 2070 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 2118 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); | 2071 LOperand* context = UseFixed(instr->context(), esi); |
| 2072 return MarkAsCall(DefineFixed(new LFunctionLiteral(context), eax), instr); |
| 2119 } | 2073 } |
| 2120 | 2074 |
| 2121 | 2075 |
| 2122 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { | 2076 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { |
| 2123 LDeleteProperty* result = | 2077 LOperand* context = UseFixed(instr->context(), esi); |
| 2124 new LDeleteProperty(UseAtStart(instr->object()), | 2078 LOperand* object = UseAtStart(instr->object()); |
| 2125 UseOrConstantAtStart(instr->key())); | 2079 LOperand* key = UseOrConstantAtStart(instr->key()); |
| 2080 LDeleteProperty* result = new LDeleteProperty(context, object, key); |
| 2126 return MarkAsCall(DefineFixed(result, eax), instr); | 2081 return MarkAsCall(DefineFixed(result, eax), instr); |
| 2127 } | 2082 } |
| 2128 | 2083 |
| 2129 | 2084 |
| 2130 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 2085 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 2131 allocator_->MarkAsOsrEntry(); | 2086 allocator_->MarkAsOsrEntry(); |
| 2132 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 2087 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 2133 return AssignEnvironment(new LOsrEntry); | 2088 return AssignEnvironment(new LOsrEntry); |
| 2134 } | 2089 } |
| 2135 | 2090 |
| 2136 | 2091 |
| 2137 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 2092 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 2138 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 2093 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 2139 return DefineAsSpilled(new LParameter, spill_index); | 2094 return DefineAsSpilled(new LParameter, spill_index); |
| 2140 } | 2095 } |
| 2141 | 2096 |
| 2142 | 2097 |
| 2143 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 2098 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| 2144 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. | 2099 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. |
| 2100 if (spill_index > LUnallocated::kMaxFixedIndex) { |
| 2101 Abort("Too many spill slots needed for OSR"); |
| 2102 spill_index = 0; |
| 2103 } |
| 2145 return DefineAsSpilled(new LUnknownOSRValue, spill_index); | 2104 return DefineAsSpilled(new LUnknownOSRValue, spill_index); |
| 2146 } | 2105 } |
| 2147 | 2106 |
| 2148 | 2107 |
| 2149 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 2108 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| 2150 LOperand* context = UseFixed(instr->context(), esi); | 2109 LOperand* context = UseFixed(instr->context(), esi); |
| 2151 argument_count_ -= instr->argument_count(); | 2110 argument_count_ -= instr->argument_count(); |
| 2152 LCallStub* result = new LCallStub(context); | 2111 LCallStub* result = new LCallStub(context); |
| 2153 return MarkAsCall(DefineFixed(result, eax), instr); | 2112 return MarkAsCall(DefineFixed(result, eax), instr); |
| 2154 } | 2113 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2173 | 2132 |
| 2174 | 2133 |
| 2175 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { | 2134 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { |
| 2176 LOperand* object = UseFixed(instr->value(), eax); | 2135 LOperand* object = UseFixed(instr->value(), eax); |
| 2177 LToFastProperties* result = new LToFastProperties(object); | 2136 LToFastProperties* result = new LToFastProperties(object); |
| 2178 return MarkAsCall(DefineFixed(result, eax), instr); | 2137 return MarkAsCall(DefineFixed(result, eax), instr); |
| 2179 } | 2138 } |
| 2180 | 2139 |
| 2181 | 2140 |
| 2182 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 2141 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 2183 LTypeof* result = new LTypeof(UseAtStart(instr->value())); | 2142 LOperand* context = UseFixed(instr->context(), esi); |
| 2143 LOperand* value = UseAtStart(instr->value()); |
| 2144 LTypeof* result = new LTypeof(context, value); |
| 2184 return MarkAsCall(DefineFixed(result, eax), instr); | 2145 return MarkAsCall(DefineFixed(result, eax), instr); |
| 2185 } | 2146 } |
| 2186 | 2147 |
| 2187 | 2148 |
| 2188 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 2149 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { |
| 2189 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); | 2150 return new LTypeofIsAndBranch(UseTempRegister(instr->value())); |
| 2190 } | 2151 } |
| 2191 | 2152 |
| 2192 | 2153 |
| 2193 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { | 2154 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
| 2194 return DefineAsRegister(new LIsConstructCall); | 2155 HIsConstructCallAndBranch* instr) { |
| 2156 return new LIsConstructCallAndBranch(TempRegister()); |
| 2195 } | 2157 } |
| 2196 | 2158 |
| 2197 | 2159 |
| 2198 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 2160 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 2199 HEnvironment* env = current_block_->last_environment(); | 2161 HEnvironment* env = current_block_->last_environment(); |
| 2200 ASSERT(env != NULL); | 2162 ASSERT(env != NULL); |
| 2201 | 2163 |
| 2202 env->set_ast_id(instr->ast_id()); | 2164 env->set_ast_id(instr->ast_id()); |
| 2203 | 2165 |
| 2204 env->Drop(instr->pop_count()); | 2166 env->Drop(instr->pop_count()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2221 set_deoptimization_environment(result->environment()); | 2183 set_deoptimization_environment(result->environment()); |
| 2222 ClearInstructionPendingDeoptimizationEnvironment(); | 2184 ClearInstructionPendingDeoptimizationEnvironment(); |
| 2223 return result; | 2185 return result; |
| 2224 } | 2186 } |
| 2225 | 2187 |
| 2226 return NULL; | 2188 return NULL; |
| 2227 } | 2189 } |
| 2228 | 2190 |
| 2229 | 2191 |
| 2230 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2192 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2231 return MarkAsCall(new LStackCheck, instr); | 2193 if (instr->is_function_entry()) { |
| 2194 LOperand* context = UseFixed(instr->context(), esi); |
| 2195 return MarkAsCall(new LStackCheck(context), instr); |
| 2196 } else { |
| 2197 ASSERT(instr->is_backwards_branch()); |
| 2198 LOperand* context = UseAny(instr->context()); |
| 2199 return AssignEnvironment(AssignPointerMap(new LStackCheck(context))); |
| 2200 } |
| 2232 } | 2201 } |
| 2233 | 2202 |
| 2234 | 2203 |
| 2235 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 2204 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
| 2236 HEnvironment* outer = current_block_->last_environment(); | 2205 HEnvironment* outer = current_block_->last_environment(); |
| 2237 HConstant* undefined = graph()->GetConstantUndefined(); | 2206 HConstant* undefined = graph()->GetConstantUndefined(); |
| 2238 HEnvironment* inner = outer->CopyForInlining(instr->closure(), | 2207 HEnvironment* inner = outer->CopyForInlining(instr->closure(), |
| 2239 instr->function(), | 2208 instr->function(), |
| 2240 HEnvironment::LITHIUM, | |
| 2241 undefined, | 2209 undefined, |
| 2242 instr->call_kind()); | 2210 instr->call_kind()); |
| 2243 current_block_->UpdateEnvironment(inner); | 2211 current_block_->UpdateEnvironment(inner); |
| 2244 chunk_->AddInlinedClosure(instr->closure()); | 2212 chunk_->AddInlinedClosure(instr->closure()); |
| 2245 return NULL; | 2213 return NULL; |
| 2246 } | 2214 } |
| 2247 | 2215 |
| 2248 | 2216 |
| 2249 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2217 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 2250 HEnvironment* outer = current_block_->last_environment()->outer(); | 2218 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 2251 current_block_->UpdateEnvironment(outer); | 2219 current_block_->UpdateEnvironment(outer); |
| 2252 return NULL; | 2220 return NULL; |
| 2253 } | 2221 } |
| 2254 | 2222 |
| 2255 | 2223 |
| 2256 LInstruction* LChunkBuilder::DoIn(HIn* instr) { | 2224 LInstruction* LChunkBuilder::DoIn(HIn* instr) { |
| 2225 LOperand* context = UseFixed(instr->context(), esi); |
| 2257 LOperand* key = UseOrConstantAtStart(instr->key()); | 2226 LOperand* key = UseOrConstantAtStart(instr->key()); |
| 2258 LOperand* object = UseOrConstantAtStart(instr->object()); | 2227 LOperand* object = UseOrConstantAtStart(instr->object()); |
| 2259 LIn* result = new LIn(key, object); | 2228 LIn* result = new LIn(context, key, object); |
| 2260 return MarkAsCall(DefineFixed(result, eax), instr); | 2229 return MarkAsCall(DefineFixed(result, eax), instr); |
| 2261 } | 2230 } |
| 2262 | 2231 |
| 2263 | 2232 |
| 2264 } } // namespace v8::internal | 2233 } } // namespace v8::internal |
| 2265 | 2234 |
| 2266 #endif // V8_TARGET_ARCH_IA32 | 2235 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |