Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Side by Side Diff: src/arm/lithium-arm.cc

Issue 6606006: [Isolates] Merge 6500:6700 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
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 "lithium-allocator-inl.h"
28 #include "arm/lithium-arm.h" 29 #include "arm/lithium-arm.h"
29 #include "arm/lithium-codegen-arm.h" 30 #include "arm/lithium-codegen-arm.h"
30 31
31 namespace v8 { 32 namespace v8 {
32 namespace internal { 33 namespace internal {
33 34
34 #define DEFINE_COMPILE(type) \ 35 #define DEFINE_COMPILE(type) \
35 void L##type::CompileToNative(LCodeGen* generator) { \ 36 void L##type::CompileToNative(LCodeGen* generator) { \
36 generator->Do##type(this); \ 37 generator->Do##type(this); \
37 } 38 }
(...skipping 11 matching lines...) Expand all
49 50
50 51
51 void LOsrEntry::MarkSpilledRegister(int allocation_index, 52 void LOsrEntry::MarkSpilledRegister(int allocation_index,
52 LOperand* spill_operand) { 53 LOperand* spill_operand) {
53 ASSERT(spill_operand->IsStackSlot()); 54 ASSERT(spill_operand->IsStackSlot());
54 ASSERT(register_spills_[allocation_index] == NULL); 55 ASSERT(register_spills_[allocation_index] == NULL);
55 register_spills_[allocation_index] = spill_operand; 56 register_spills_[allocation_index] = spill_operand;
56 } 57 }
57 58
58 59
60 #ifdef DEBUG
61 void LInstruction::VerifyCall() {
62 // Call instructions can use only fixed registers as
63 // temporaries and outputs because all registers
64 // are blocked by the calling convention.
65 // Inputs can use either fixed register or have a short lifetime (be
66 // used at start of the instruction).
67 ASSERT(Output() == NULL ||
68 LUnallocated::cast(Output())->HasFixedPolicy() ||
69 !LUnallocated::cast(Output())->HasRegisterPolicy());
70 for (UseIterator it(this); it.HasNext(); it.Advance()) {
71 LOperand* operand = it.Next();
72 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
73 LUnallocated::cast(operand)->IsUsedAtStart() ||
74 !LUnallocated::cast(operand)->HasRegisterPolicy());
75 }
76 for (TempIterator it(this); it.HasNext(); it.Advance()) {
77 LOperand* operand = it.Next();
78 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
79 !LUnallocated::cast(operand)->HasRegisterPolicy());
80 }
81 }
82 #endif
83
84
59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, 85 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
60 LOperand* spill_operand) { 86 LOperand* spill_operand) {
61 ASSERT(spill_operand->IsDoubleStackSlot()); 87 ASSERT(spill_operand->IsDoubleStackSlot());
62 ASSERT(double_register_spills_[allocation_index] == NULL); 88 ASSERT(double_register_spills_[allocation_index] == NULL);
63 double_register_spills_[allocation_index] = spill_operand; 89 double_register_spills_[allocation_index] = spill_operand;
64 } 90 }
65 91
66 92
67 void LInstruction::PrintTo(StringStream* stream) { 93 void LInstruction::PrintTo(StringStream* stream) {
68 stream->Add("%s ", this->Mnemonic()); 94 stream->Add("%s ", this->Mnemonic());
69 if (HasResult()) { 95
70 PrintOutputOperandTo(stream); 96 PrintOutputOperandTo(stream);
71 }
72 97
73 PrintDataTo(stream); 98 PrintDataTo(stream);
74 99
75 if (HasEnvironment()) { 100 if (HasEnvironment()) {
76 stream->Add(" "); 101 stream->Add(" ");
77 environment()->PrintTo(stream); 102 environment()->PrintTo(stream);
78 } 103 }
79 104
80 if (HasPointerMap()) { 105 if (HasPointerMap()) {
81 stream->Add(" "); 106 stream->Add(" ");
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 } 176 }
152 177
153 178
154 const char* LArithmeticT::Mnemonic() const { 179 const char* LArithmeticT::Mnemonic() const {
155 switch (op()) { 180 switch (op()) {
156 case Token::ADD: return "add-t"; 181 case Token::ADD: return "add-t";
157 case Token::SUB: return "sub-t"; 182 case Token::SUB: return "sub-t";
158 case Token::MUL: return "mul-t"; 183 case Token::MUL: return "mul-t";
159 case Token::MOD: return "mod-t"; 184 case Token::MOD: return "mod-t";
160 case Token::DIV: return "div-t"; 185 case Token::DIV: return "div-t";
186 case Token::BIT_AND: return "bit-and-t";
187 case Token::BIT_OR: return "bit-or-t";
188 case Token::BIT_XOR: return "bit-xor-t";
161 default: 189 default:
162 UNREACHABLE(); 190 UNREACHABLE();
163 return NULL; 191 return NULL;
164 } 192 }
165 } 193 }
166 194
167 195
168 void LGoto::PrintDataTo(StringStream* stream) { 196 void LGoto::PrintDataTo(StringStream* stream) {
169 stream->Add("B%d", block_id()); 197 stream->Add("B%d", block_id());
170 } 198 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 279 }
252 280
253 281
254 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { 282 void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
255 stream->Add("/%s ", hydrogen()->OpName()); 283 stream->Add("/%s ", hydrogen()->OpName());
256 InputAt(0)->PrintTo(stream); 284 InputAt(0)->PrintTo(stream);
257 } 285 }
258 286
259 287
260 void LLoadContextSlot::PrintDataTo(StringStream* stream) { 288 void LLoadContextSlot::PrintDataTo(StringStream* stream) {
261 stream->Add("(%d, %d)", context_chain_length(), slot_index()); 289 InputAt(0)->PrintTo(stream);
290 stream->Add("[%d]", slot_index());
291 }
292
293
294 void LStoreContextSlot::PrintDataTo(StringStream* stream) {
295 InputAt(0)->PrintTo(stream);
296 stream->Add("[%d] <- ", slot_index());
297 InputAt(1)->PrintTo(stream);
262 } 298 }
263 299
264 300
265 void LCallKeyed::PrintDataTo(StringStream* stream) { 301 void LCallKeyed::PrintDataTo(StringStream* stream) {
266 stream->Add("[r2] #%d / ", arity()); 302 stream->Add("[r2] #%d / ", arity());
267 } 303 }
268 304
269 305
270 void LCallNamed::PrintDataTo(StringStream* stream) { 306 void LCallNamed::PrintDataTo(StringStream* stream) {
271 SmartPointer<char> name_string = name()->ToCString(); 307 SmartPointer<char> name_string = name()->ToCString();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 419
384 if (can_eliminate) { 420 if (can_eliminate) {
385 label->set_replacement(GetLabel(goto_instr->block_id())); 421 label->set_replacement(GetLabel(goto_instr->block_id()));
386 } 422 }
387 } 423 }
388 } 424 }
389 } 425 }
390 } 426 }
391 427
392 428
393 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { 429 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
394 LGap* gap = new LGap(block); 430 LGap* gap = new LGap(block);
395 int index = -1; 431 int index = -1;
396 if (instr->IsControl()) { 432 if (instr->IsControl()) {
397 instructions_.Add(gap); 433 instructions_.Add(gap);
398 index = instructions_.length(); 434 index = instructions_.length();
399 instructions_.Add(instr); 435 instructions_.Add(instr);
400 } else { 436 } else {
401 index = instructions_.length(); 437 index = instructions_.length();
402 instructions_.Add(instr); 438 instructions_.Add(instr);
403 instructions_.Add(gap); 439 instructions_.Add(gap);
404 } 440 }
405 if (instr->HasPointerMap()) { 441 if (instr->HasPointerMap()) {
406 pointer_maps_.Add(instr->pointer_map()); 442 pointer_maps_.Add(instr->pointer_map());
407 instr->pointer_map()->set_lithium_position(index); 443 instr->pointer_map()->set_lithium_position(index);
408 } 444 }
409 return index;
410 } 445 }
411 446
412 447
413 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { 448 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
414 return LConstantOperand::Create(constant->id()); 449 return LConstantOperand::Create(constant->id());
415 } 450 }
416 451
417 452
418 int LChunk::GetParameterStackSlot(int index) const { 453 int LChunk::GetParameterStackSlot(int index) const {
419 // The receiver is at index 0, the first parameter at index 1, so we 454 // The receiver is at index 0, the first parameter at index 1, so we
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 683
649 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 684 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
650 HEnvironment* hydrogen_env = current_block_->last_environment(); 685 HEnvironment* hydrogen_env = current_block_->last_environment();
651 instr->set_environment(CreateEnvironment(hydrogen_env)); 686 instr->set_environment(CreateEnvironment(hydrogen_env));
652 return instr; 687 return instr;
653 } 688 }
654 689
655 690
656 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( 691 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment(
657 LInstruction* instr, int ast_id) { 692 LInstruction* instr, int ast_id) {
658 ASSERT(instructions_pending_deoptimization_environment_ == NULL); 693 ASSERT(instruction_pending_deoptimization_environment_ == NULL);
659 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); 694 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
660 instructions_pending_deoptimization_environment_ = instr; 695 instruction_pending_deoptimization_environment_ = instr;
661 pending_deoptimization_ast_id_ = ast_id; 696 pending_deoptimization_ast_id_ = ast_id;
662 return instr; 697 return instr;
663 } 698 }
664 699
665 700
666 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { 701 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
667 instructions_pending_deoptimization_environment_ = NULL; 702 instruction_pending_deoptimization_environment_ = NULL;
668 pending_deoptimization_ast_id_ = AstNode::kNoNumber; 703 pending_deoptimization_ast_id_ = AstNode::kNoNumber;
669 } 704 }
670 705
671 706
672 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, 707 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
673 HInstruction* hinstr, 708 HInstruction* hinstr,
674 CanDeoptimize can_deoptimize) { 709 CanDeoptimize can_deoptimize) {
675 allocator_->MarkAsCall(); 710 #ifdef DEBUG
711 instr->VerifyCall();
712 #endif
713 instr->MarkAsCall();
676 instr = AssignPointerMap(instr); 714 instr = AssignPointerMap(instr);
677 715
678 if (hinstr->HasSideEffects()) { 716 if (hinstr->HasSideEffects()) {
679 ASSERT(hinstr->next()->IsSimulate()); 717 ASSERT(hinstr->next()->IsSimulate());
680 HSimulate* sim = HSimulate::cast(hinstr->next()); 718 HSimulate* sim = HSimulate::cast(hinstr->next());
681 instr = SetInstructionPendingDeoptimizationEnvironment( 719 instr = SetInstructionPendingDeoptimizationEnvironment(
682 instr, sim->ast_id()); 720 instr, sim->ast_id());
683 } 721 }
684 722
685 // If instruction does not have side-effects lazy deoptimization 723 // If instruction does not have side-effects lazy deoptimization
686 // after the call will try to deoptimize to the point before the call. 724 // after the call will try to deoptimize to the point before the call.
687 // Thus we still need to attach environment to this call even if 725 // Thus we still need to attach environment to this call even if
688 // call sequence can not deoptimize eagerly. 726 // call sequence can not deoptimize eagerly.
689 bool needs_environment = 727 bool needs_environment =
690 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); 728 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
691 if (needs_environment && !instr->HasEnvironment()) { 729 if (needs_environment && !instr->HasEnvironment()) {
692 instr = AssignEnvironment(instr); 730 instr = AssignEnvironment(instr);
693 } 731 }
694 732
695 return instr; 733 return instr;
696 } 734 }
697 735
698 736
699 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { 737 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
700 allocator_->MarkAsSaveDoubles(); 738 instr->MarkAsSaveDoubles();
701 return instr; 739 return instr;
702 } 740 }
703 741
704 742
705 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { 743 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
706 ASSERT(!instr->HasPointerMap()); 744 ASSERT(!instr->HasPointerMap());
707 instr->set_pointer_map(new LPointerMap(position_)); 745 instr->set_pointer_map(new LPointerMap(position_));
708 return instr; 746 return instr;
709 } 747 }
710 748
(...skipping 24 matching lines...) Expand all
735 } 773 }
736 774
737 775
738 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { 776 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
739 return AssignEnvironment(new LDeoptimize); 777 return AssignEnvironment(new LDeoptimize);
740 } 778 }
741 779
742 780
743 LInstruction* LChunkBuilder::DoBit(Token::Value op, 781 LInstruction* LChunkBuilder::DoBit(Token::Value op,
744 HBitwiseBinaryOperation* instr) { 782 HBitwiseBinaryOperation* instr) {
745 ASSERT(instr->representation().IsInteger32()); 783 if (instr->representation().IsInteger32()) {
746 ASSERT(instr->left()->representation().IsInteger32()); 784 ASSERT(instr->left()->representation().IsInteger32());
747 ASSERT(instr->right()->representation().IsInteger32()); 785 ASSERT(instr->right()->representation().IsInteger32());
748 786
749 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 787 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
750 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); 788 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
751 return DefineSameAsFirst(new LBitI(op, left, right)); 789 return DefineSameAsFirst(new LBitI(op, left, right));
790 } else {
791 ASSERT(instr->representation().IsTagged());
792 ASSERT(instr->left()->representation().IsTagged());
793 ASSERT(instr->right()->representation().IsTagged());
794
795 LOperand* left = UseFixed(instr->left(), r1);
796 LOperand* right = UseFixed(instr->right(), r0);
797 LArithmeticT* result = new LArithmeticT(op, left, right);
798 return MarkAsCall(DefineFixed(result, r0), instr);
799 }
752 } 800 }
753 801
754 802
755 LInstruction* LChunkBuilder::DoShift(Token::Value op, 803 LInstruction* LChunkBuilder::DoShift(Token::Value op,
756 HBitwiseBinaryOperation* instr) { 804 HBitwiseBinaryOperation* instr) {
757 ASSERT(instr->representation().IsInteger32()); 805 ASSERT(instr->representation().IsInteger32());
758 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); 806 ASSERT(instr->OperandAt(0)->representation().IsInteger32());
759 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); 807 ASSERT(instr->OperandAt(1)->representation().IsInteger32());
760 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); 808 LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
761 809
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 } 928 }
881 block->set_argument_count(argument_count_); 929 block->set_argument_count(argument_count_);
882 next_block_ = NULL; 930 next_block_ = NULL;
883 current_block_ = NULL; 931 current_block_ = NULL;
884 } 932 }
885 933
886 934
887 void LChunkBuilder::VisitInstruction(HInstruction* current) { 935 void LChunkBuilder::VisitInstruction(HInstruction* current) {
888 HInstruction* old_current = current_instruction_; 936 HInstruction* old_current = current_instruction_;
889 current_instruction_ = current; 937 current_instruction_ = current;
890 allocator_->BeginInstruction();
891 if (current->has_position()) position_ = current->position(); 938 if (current->has_position()) position_ = current->position();
892 LInstruction* instr = current->CompileToLithium(this); 939 LInstruction* instr = current->CompileToLithium(this);
893 940
894 if (instr != NULL) { 941 if (instr != NULL) {
895 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 942 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
896 instr = AssignPointerMap(instr); 943 instr = AssignPointerMap(instr);
897 } 944 }
898 if (FLAG_stress_environments && !instr->HasEnvironment()) { 945 if (FLAG_stress_environments && !instr->HasEnvironment()) {
899 instr = AssignEnvironment(instr); 946 instr = AssignEnvironment(instr);
900 } 947 }
901 if (current->IsTest() && !instr->IsGoto()) { 948 if (current->IsTest() && !instr->IsGoto()) {
902 ASSERT(instr->IsControl()); 949 ASSERT(instr->IsControl());
903 HTest* test = HTest::cast(current); 950 HTest* test = HTest::cast(current);
904 instr->set_hydrogen_value(test->value()); 951 instr->set_hydrogen_value(test->value());
905 HBasicBlock* first = test->FirstSuccessor(); 952 HBasicBlock* first = test->FirstSuccessor();
906 HBasicBlock* second = test->SecondSuccessor(); 953 HBasicBlock* second = test->SecondSuccessor();
907 ASSERT(first != NULL && second != NULL); 954 ASSERT(first != NULL && second != NULL);
908 instr->SetBranchTargets(first->block_id(), second->block_id()); 955 instr->SetBranchTargets(first->block_id(), second->block_id());
909 } else { 956 } else {
910 instr->set_hydrogen_value(current); 957 instr->set_hydrogen_value(current);
911 } 958 }
912 959
913 int index = chunk_->AddInstruction(instr, current_block_); 960 chunk_->AddInstruction(instr, current_block_);
914 allocator_->SummarizeInstruction(index);
915 } else {
916 // This instruction should be omitted.
917 allocator_->OmitInstruction();
918 } 961 }
919 current_instruction_ = old_current; 962 current_instruction_ = old_current;
920 } 963 }
921 964
922 965
923 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { 966 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
924 if (hydrogen_env == NULL) return NULL; 967 if (hydrogen_env == NULL) return NULL;
925 968
926 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); 969 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
927 int ast_id = hydrogen_env->ast_id(); 970 int ast_id = hydrogen_env->ast_id();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 1064
1022 LOperand* temp = TempRegister(); 1065 LOperand* temp = TempRegister();
1023 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp); 1066 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp);
1024 } else if (v->IsCompareJSObjectEq()) { 1067 } else if (v->IsCompareJSObjectEq()) {
1025 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); 1068 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1026 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), 1069 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1027 UseRegisterAtStart(compare->right())); 1070 UseRegisterAtStart(compare->right()));
1028 } else if (v->IsInstanceOf()) { 1071 } else if (v->IsInstanceOf()) {
1029 HInstanceOf* instance_of = HInstanceOf::cast(v); 1072 HInstanceOf* instance_of = HInstanceOf::cast(v);
1030 LInstruction* result = 1073 LInstruction* result =
1031 new LInstanceOfAndBranch(Use(instance_of->left()), 1074 new LInstanceOfAndBranch(UseFixed(instance_of->left(), r0),
1032 Use(instance_of->right())); 1075 UseFixed(instance_of->right(), r1));
1033 return MarkAsCall(result, instr); 1076 return MarkAsCall(result, instr);
1034 } else if (v->IsTypeofIs()) { 1077 } else if (v->IsTypeofIs()) {
1035 HTypeofIs* typeof_is = HTypeofIs::cast(v); 1078 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1036 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); 1079 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1080 } else if (v->IsIsConstructCall()) {
1081 return new LIsConstructCallAndBranch(TempRegister());
1037 } else { 1082 } else {
1038 if (v->IsConstant()) { 1083 if (v->IsConstant()) {
1039 if (HConstant::cast(v)->handle()->IsTrue()) { 1084 if (HConstant::cast(v)->handle()->IsTrue()) {
1040 return new LGoto(instr->FirstSuccessor()->block_id()); 1085 return new LGoto(instr->FirstSuccessor()->block_id());
1041 } else if (HConstant::cast(v)->handle()->IsFalse()) { 1086 } else if (HConstant::cast(v)->handle()->IsFalse()) {
1042 return new LGoto(instr->SecondSuccessor()->block_id()); 1087 return new LGoto(instr->SecondSuccessor()->block_id());
1043 } 1088 }
1044 } 1089 }
1045 Abort("Undefined compare before branch"); 1090 Abort("Undefined compare before branch");
1046 return NULL; 1091 return NULL;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 } 1143 }
1099 1144
1100 1145
1101 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1146 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1102 ++argument_count_; 1147 ++argument_count_;
1103 LOperand* argument = Use(instr->argument()); 1148 LOperand* argument = Use(instr->argument());
1104 return new LPushArgument(argument); 1149 return new LPushArgument(argument);
1105 } 1150 }
1106 1151
1107 1152
1153 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1154 return DefineAsRegister(new LContext);
1155 }
1156
1157
1158 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1159 LOperand* context = UseRegisterAtStart(instr->value());
1160 return DefineAsRegister(new LOuterContext(context));
1161 }
1162
1163
1108 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { 1164 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
1109 return DefineAsRegister(new LGlobalObject); 1165 LOperand* context = UseRegisterAtStart(instr->value());
1166 return DefineAsRegister(new LGlobalObject(context));
1110 } 1167 }
1111 1168
1112 1169
1113 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { 1170 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
1114 return DefineAsRegister(new LGlobalReceiver); 1171 LOperand* global_object = UseRegisterAtStart(instr->value());
1172 return DefineAsRegister(new LGlobalReceiver(global_object));
1115 } 1173 }
1116 1174
1117 1175
1118 LInstruction* LChunkBuilder::DoCallConstantFunction( 1176 LInstruction* LChunkBuilder::DoCallConstantFunction(
1119 HCallConstantFunction* instr) { 1177 HCallConstantFunction* instr) {
1120 argument_count_ -= instr->argument_count(); 1178 argument_count_ -= instr->argument_count();
1121 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr); 1179 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr);
1122 } 1180 }
1123 1181
1124 1182
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 1299
1242 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1300 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1243 if (instr->representation().IsDouble()) { 1301 if (instr->representation().IsDouble()) {
1244 return DoArithmeticD(Token::DIV, instr); 1302 return DoArithmeticD(Token::DIV, instr);
1245 } else if (instr->representation().IsInteger32()) { 1303 } else if (instr->representation().IsInteger32()) {
1246 // TODO(1042) The fixed register allocation 1304 // TODO(1042) The fixed register allocation
1247 // is needed because we call GenericBinaryOpStub from 1305 // is needed because we call GenericBinaryOpStub from
1248 // the generated code, which requires registers r0 1306 // the generated code, which requires registers r0
1249 // and r1 to be used. We should remove that 1307 // and r1 to be used. We should remove that
1250 // when we provide a native implementation. 1308 // when we provide a native implementation.
1251 LOperand* value = UseFixed(instr->left(), r0); 1309 LOperand* dividend = UseFixed(instr->left(), r0);
1252 LOperand* divisor = UseFixed(instr->right(), r1); 1310 LOperand* divisor = UseFixed(instr->right(), r1);
1253 return AssignEnvironment(AssignPointerMap( 1311 return AssignEnvironment(AssignPointerMap(
1254 DefineFixed(new LDivI(value, divisor), r0))); 1312 DefineFixed(new LDivI(dividend, divisor), r0)));
1255 } else { 1313 } else {
1256 return DoArithmeticT(Token::DIV, instr); 1314 return DoArithmeticT(Token::DIV, instr);
1257 } 1315 }
1258 } 1316 }
1259 1317
1260 1318
1261 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1319 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1262 if (instr->representation().IsInteger32()) { 1320 if (instr->representation().IsInteger32()) {
1263 // TODO(1042) The fixed register allocation 1321 // TODO(1042) The fixed register allocation
1264 // is needed because we call GenericBinaryOpStub from 1322 // is needed because we call GenericBinaryOpStub from
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 return AssignEnvironment(DefineSameAsFirst(result)); 1514 return AssignEnvironment(DefineSameAsFirst(result));
1457 } 1515 }
1458 1516
1459 1517
1460 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1518 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1461 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1519 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1462 UseRegister(instr->length()))); 1520 UseRegister(instr->length())));
1463 } 1521 }
1464 1522
1465 1523
1524 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1525 // The control instruction marking the end of a block that completed
1526 // abruptly (e.g., threw an exception). There is nothing specific to do.
1527 return NULL;
1528 }
1529
1530
1466 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1531 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1467 LOperand* value = UseFixed(instr->value(), r0); 1532 LOperand* value = UseFixed(instr->value(), r0);
1468 return MarkAsCall(new LThrow(value), instr); 1533 return MarkAsCall(new LThrow(value), instr);
1469 } 1534 }
1470 1535
1471 1536
1472 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1537 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1473 Representation from = instr->from(); 1538 Representation from = instr->from();
1474 Representation to = instr->to(); 1539 Representation to = instr->to();
1475 if (from.IsTagged()) { 1540 if (from.IsTagged()) {
(...skipping 24 matching lines...) Expand all
1500 1565
1501 // Make sure that the temp and result_temp registers are 1566 // Make sure that the temp and result_temp registers are
1502 // different. 1567 // different.
1503 LUnallocated* result_temp = TempRegister(); 1568 LUnallocated* result_temp = TempRegister();
1504 LNumberTagD* result = new LNumberTagD(value, temp1, temp2); 1569 LNumberTagD* result = new LNumberTagD(value, temp1, temp2);
1505 Define(result, result_temp); 1570 Define(result, result_temp);
1506 return AssignPointerMap(result); 1571 return AssignPointerMap(result);
1507 } else { 1572 } else {
1508 ASSERT(to.IsInteger32()); 1573 ASSERT(to.IsInteger32());
1509 LOperand* value = UseRegister(instr->value()); 1574 LOperand* value = UseRegister(instr->value());
1510 LDoubleToI* res = new LDoubleToI(value); 1575 LDoubleToI* res = new LDoubleToI(value, TempRegister());
1511 return AssignEnvironment(DefineAsRegister(res)); 1576 return AssignEnvironment(DefineAsRegister(res));
1512 } 1577 }
1513 } else if (from.IsInteger32()) { 1578 } else if (from.IsInteger32()) {
1514 if (to.IsTagged()) { 1579 if (to.IsTagged()) {
1515 HValue* val = instr->value(); 1580 HValue* val = instr->value();
1516 LOperand* value = UseRegister(val); 1581 LOperand* value = UseRegister(val);
1517 if (val->HasRange() && val->range()->IsInSmiRange()) { 1582 if (val->HasRange() && val->range()->IsInSmiRange()) {
1518 return DefineSameAsFirst(new LSmiTag(value)); 1583 return DefineSameAsFirst(new LSmiTag(value));
1519 } else { 1584 } else {
1520 LNumberTagI* result = new LNumberTagI(value); 1585 LNumberTagI* result = new LNumberTagI(value);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1572 1637
1573 1638
1574 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1639 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1575 return new LReturn(UseFixed(instr->value(), r0)); 1640 return new LReturn(UseFixed(instr->value(), r0));
1576 } 1641 }
1577 1642
1578 1643
1579 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1644 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1580 Representation r = instr->representation(); 1645 Representation r = instr->representation();
1581 if (r.IsInteger32()) { 1646 if (r.IsInteger32()) {
1582 int32_t value = instr->Integer32Value(); 1647 return DefineAsRegister(new LConstantI);
1583 return DefineAsRegister(new LConstantI(value));
1584 } else if (r.IsDouble()) { 1648 } else if (r.IsDouble()) {
1585 double value = instr->DoubleValue(); 1649 return DefineAsRegister(new LConstantD);
1586 return DefineAsRegister(new LConstantD(value));
1587 } else if (r.IsTagged()) { 1650 } else if (r.IsTagged()) {
1588 return DefineAsRegister(new LConstantT(instr->handle())); 1651 return DefineAsRegister(new LConstantT);
1589 } else { 1652 } else {
1590 UNREACHABLE(); 1653 UNREACHABLE();
1591 return NULL; 1654 return NULL;
1592 } 1655 }
1593 } 1656 }
1594 1657
1595 1658
1596 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { 1659 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) {
1597 LLoadGlobal* result = new LLoadGlobal(); 1660 LLoadGlobal* result = new LLoadGlobal();
1598 return instr->check_hole_value() 1661 return instr->check_hole_value()
1599 ? AssignEnvironment(DefineAsRegister(result)) 1662 ? AssignEnvironment(DefineAsRegister(result))
1600 : DefineAsRegister(result); 1663 : DefineAsRegister(result);
1601 } 1664 }
1602 1665
1603 1666
1604 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { 1667 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) {
1605 return new LStoreGlobal(UseRegisterAtStart(instr->value())); 1668 if (instr->check_hole_value()) {
1669 LOperand* temp = TempRegister();
1670 LOperand* value = UseRegister(instr->value());
1671 return AssignEnvironment(new LStoreGlobal(value, temp));
1672 } else {
1673 LOperand* value = UseRegisterAtStart(instr->value());
1674 return new LStoreGlobal(value, NULL);
1675 }
1606 } 1676 }
1607 1677
1608 1678
1609 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 1679 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1610 return DefineAsRegister(new LLoadContextSlot); 1680 LOperand* context = UseRegisterAtStart(instr->value());
1681 return DefineAsRegister(new LLoadContextSlot(context));
1682 }
1683
1684
1685 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
1686 LOperand* context = UseTempRegister(instr->context());
1687 LOperand* value;
1688 if (instr->NeedsWriteBarrier()) {
1689 value = UseTempRegister(instr->value());
1690 } else {
1691 value = UseRegister(instr->value());
1692 }
1693 return new LStoreContextSlot(context, value);
1611 } 1694 }
1612 1695
1613 1696
1614 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 1697 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1615 return DefineAsRegister( 1698 return DefineAsRegister(
1616 new LLoadNamedField(UseRegisterAtStart(instr->object()))); 1699 new LLoadNamedField(UseRegisterAtStart(instr->object())));
1617 } 1700 }
1618 1701
1619 1702
1620 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 1703 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1800 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 1883 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
1801 LTypeof* result = new LTypeof(UseRegisterAtStart(instr->value())); 1884 LTypeof* result = new LTypeof(UseRegisterAtStart(instr->value()));
1802 return MarkAsCall(DefineFixed(result, r0), instr); 1885 return MarkAsCall(DefineFixed(result, r0), instr);
1803 } 1886 }
1804 1887
1805 1888
1806 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 1889 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
1807 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 1890 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
1808 } 1891 }
1809 1892
1893
1894 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
1895 return DefineAsRegister(new LIsConstructCall());
1896 }
1897
1898
1810 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 1899 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
1811 HEnvironment* env = current_block_->last_environment(); 1900 HEnvironment* env = current_block_->last_environment();
1812 ASSERT(env != NULL); 1901 ASSERT(env != NULL);
1813 1902
1814 env->set_ast_id(instr->ast_id()); 1903 env->set_ast_id(instr->ast_id());
1815 1904
1816 env->Drop(instr->pop_count()); 1905 env->Drop(instr->pop_count());
1817 for (int i = 0; i < instr->values()->length(); ++i) { 1906 for (int i = 0; i < instr->values()->length(); ++i) {
1818 HValue* value = instr->values()->at(i); 1907 HValue* value = instr->values()->at(i);
1819 if (instr->HasAssignedIndexAt(i)) { 1908 if (instr->HasAssignedIndexAt(i)) {
1820 env->Bind(instr->GetAssignedIndexAt(i), value); 1909 env->Bind(instr->GetAssignedIndexAt(i), value);
1821 } else { 1910 } else {
1822 env->Push(value); 1911 env->Push(value);
1823 } 1912 }
1824 } 1913 }
1825 1914
1826 ASSERT(env->length() == instr->environment_length()); 1915 ASSERT(env->length() == instr->environment_length());
1827 1916
1828 // If there is an instruction pending deoptimization environment create a 1917 // If there is an instruction pending deoptimization environment create a
1829 // lazy bailout instruction to capture the environment. 1918 // lazy bailout instruction to capture the environment.
1830 if (pending_deoptimization_ast_id_ == instr->ast_id()) { 1919 if (pending_deoptimization_ast_id_ == instr->ast_id()) {
1831 LInstruction* result = new LLazyBailout; 1920 LInstruction* result = new LLazyBailout;
1832 result = AssignEnvironment(result); 1921 result = AssignEnvironment(result);
1833 instructions_pending_deoptimization_environment_-> 1922 instruction_pending_deoptimization_environment_->
1834 set_deoptimization_environment(result->environment()); 1923 set_deoptimization_environment(result->environment());
1835 ClearInstructionPendingDeoptimizationEnvironment(); 1924 ClearInstructionPendingDeoptimizationEnvironment();
1836 return result; 1925 return result;
1837 } 1926 }
1838 1927
1839 return NULL; 1928 return NULL;
1840 } 1929 }
1841 1930
1842 1931
1843 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 1932 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
(...skipping 15 matching lines...) Expand all
1859 1948
1860 1949
1861 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 1950 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
1862 HEnvironment* outer = current_block_->last_environment()->outer(); 1951 HEnvironment* outer = current_block_->last_environment()->outer();
1863 current_block_->UpdateEnvironment(outer); 1952 current_block_->UpdateEnvironment(outer);
1864 return NULL; 1953 return NULL;
1865 } 1954 }
1866 1955
1867 1956
1868 } } // namespace v8::internal 1957 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698