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

Side by Side Diff: src/ia32/lithium-ia32.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
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
(...skipping 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #if defined(V8_TARGET_ARCH_IA32) 30 #if defined(V8_TARGET_ARCH_IA32)
31 31
32 #include "lithium-allocator-inl.h"
32 #include "ia32/lithium-ia32.h" 33 #include "ia32/lithium-ia32.h"
33 #include "ia32/lithium-codegen-ia32.h" 34 #include "ia32/lithium-codegen-ia32.h"
34 35
35 namespace v8 { 36 namespace v8 {
36 namespace internal { 37 namespace internal {
37 38
38 #define DEFINE_COMPILE(type) \ 39 #define DEFINE_COMPILE(type) \
39 void L##type::CompileToNative(LCodeGen* generator) { \ 40 void L##type::CompileToNative(LCodeGen* generator) { \
40 generator->Do##type(this); \ 41 generator->Do##type(this); \
41 } 42 }
(...skipping 19 matching lines...) Expand all
61 62
62 63
63 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, 64 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
64 LOperand* spill_operand) { 65 LOperand* spill_operand) {
65 ASSERT(spill_operand->IsDoubleStackSlot()); 66 ASSERT(spill_operand->IsDoubleStackSlot());
66 ASSERT(double_register_spills_[allocation_index] == NULL); 67 ASSERT(double_register_spills_[allocation_index] == NULL);
67 double_register_spills_[allocation_index] = spill_operand; 68 double_register_spills_[allocation_index] = spill_operand;
68 } 69 }
69 70
70 71
72 #ifdef DEBUG
73 void LInstruction::VerifyCall() {
74 // Call instructions can use only fixed registers as
75 // temporaries and outputs because all registers
76 // are blocked by the calling convention.
77 // Inputs can use either fixed register or have a short lifetime (be
78 // used at start of the instruction).
79 ASSERT(Output() == NULL ||
80 LUnallocated::cast(Output())->HasFixedPolicy() ||
81 !LUnallocated::cast(Output())->HasRegisterPolicy());
82 for (UseIterator it(this); it.HasNext(); it.Advance()) {
83 LOperand* operand = it.Next();
84 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
85 LUnallocated::cast(operand)->IsUsedAtStart() ||
86 !LUnallocated::cast(operand)->HasRegisterPolicy());
87 }
88 for (TempIterator it(this); it.HasNext(); it.Advance()) {
89 LOperand* operand = it.Next();
90 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
91 !LUnallocated::cast(operand)->HasRegisterPolicy());
92 }
93 }
94 #endif
95
96
71 void LInstruction::PrintTo(StringStream* stream) { 97 void LInstruction::PrintTo(StringStream* stream) {
72 stream->Add("%s ", this->Mnemonic()); 98 stream->Add("%s ", this->Mnemonic());
73 if (HasResult()) { 99
74 PrintOutputOperandTo(stream); 100 PrintOutputOperandTo(stream);
75 }
76 101
77 PrintDataTo(stream); 102 PrintDataTo(stream);
78 103
79 if (HasEnvironment()) { 104 if (HasEnvironment()) {
80 stream->Add(" "); 105 stream->Add(" ");
81 environment()->PrintTo(stream); 106 environment()->PrintTo(stream);
82 } 107 }
83 108
84 if (HasPointerMap()) { 109 if (HasPointerMap()) {
85 stream->Add(" "); 110 stream->Add(" ");
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 } 286 }
262 287
263 288
264 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { 289 void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
265 stream->Add("/%s ", hydrogen()->OpName()); 290 stream->Add("/%s ", hydrogen()->OpName());
266 InputAt(0)->PrintTo(stream); 291 InputAt(0)->PrintTo(stream);
267 } 292 }
268 293
269 294
270 void LLoadContextSlot::PrintDataTo(StringStream* stream) { 295 void LLoadContextSlot::PrintDataTo(StringStream* stream) {
271 stream->Add("(%d, %d)", context_chain_length(), slot_index()); 296 InputAt(0)->PrintTo(stream);
297 stream->Add("[%d]", slot_index());
298 }
299
300
301 void LStoreContextSlot::PrintDataTo(StringStream* stream) {
302 InputAt(0)->PrintTo(stream);
303 stream->Add("[%d] <- ", slot_index());
304 InputAt(1)->PrintTo(stream);
272 } 305 }
273 306
274 307
275 void LCallKeyed::PrintDataTo(StringStream* stream) { 308 void LCallKeyed::PrintDataTo(StringStream* stream) {
276 stream->Add("[ecx] #%d / ", arity()); 309 stream->Add("[ecx] #%d / ", arity());
277 } 310 }
278 311
279 312
280 void LCallNamed::PrintDataTo(StringStream* stream) { 313 void LCallNamed::PrintDataTo(StringStream* stream) {
281 SmartPointer<char> name_string = name()->ToCString(); 314 SmartPointer<char> name_string = name()->ToCString();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 417
385 void LStoreKeyed::PrintDataTo(StringStream* stream) { 418 void LStoreKeyed::PrintDataTo(StringStream* stream) {
386 object()->PrintTo(stream); 419 object()->PrintTo(stream);
387 stream->Add("["); 420 stream->Add("[");
388 key()->PrintTo(stream); 421 key()->PrintTo(stream);
389 stream->Add("] <- "); 422 stream->Add("] <- ");
390 value()->PrintTo(stream); 423 value()->PrintTo(stream);
391 } 424 }
392 425
393 426
394 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { 427 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
395 LGap* gap = new LGap(block); 428 LGap* gap = new LGap(block);
396 int index = -1; 429 int index = -1;
397 if (instr->IsControl()) { 430 if (instr->IsControl()) {
398 instructions_.Add(gap); 431 instructions_.Add(gap);
399 index = instructions_.length(); 432 index = instructions_.length();
400 instructions_.Add(instr); 433 instructions_.Add(instr);
401 } else { 434 } else {
402 index = instructions_.length(); 435 index = instructions_.length();
403 instructions_.Add(instr); 436 instructions_.Add(instr);
404 instructions_.Add(gap); 437 instructions_.Add(gap);
405 } 438 }
406 if (instr->HasPointerMap()) { 439 if (instr->HasPointerMap()) {
407 pointer_maps_.Add(instr->pointer_map()); 440 pointer_maps_.Add(instr->pointer_map());
408 instr->pointer_map()->set_lithium_position(index); 441 instr->pointer_map()->set_lithium_position(index);
409 } 442 }
410 return index;
411 } 443 }
412 444
413 445
414 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { 446 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
415 return LConstantOperand::Create(constant->id()); 447 return LConstantOperand::Create(constant->id());
416 } 448 }
417 449
418 450
419 int LChunk::GetParameterStackSlot(int index) const { 451 int LChunk::GetParameterStackSlot(int index) const {
420 // The receiver is at index 0, the first parameter at index 1, so we 452 // The receiver is at index 0, the first parameter at index 1, so we
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 683
652 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 684 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
653 HEnvironment* hydrogen_env = current_block_->last_environment(); 685 HEnvironment* hydrogen_env = current_block_->last_environment();
654 instr->set_environment(CreateEnvironment(hydrogen_env)); 686 instr->set_environment(CreateEnvironment(hydrogen_env));
655 return instr; 687 return instr;
656 } 688 }
657 689
658 690
659 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( 691 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment(
660 LInstruction* instr, int ast_id) { 692 LInstruction* instr, int ast_id) {
661 ASSERT(instructions_pending_deoptimization_environment_ == NULL); 693 ASSERT(instruction_pending_deoptimization_environment_ == NULL);
662 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); 694 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
663 instructions_pending_deoptimization_environment_ = instr; 695 instruction_pending_deoptimization_environment_ = instr;
664 pending_deoptimization_ast_id_ = ast_id; 696 pending_deoptimization_ast_id_ = ast_id;
665 return instr; 697 return instr;
666 } 698 }
667 699
668 700
669 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { 701 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
670 instructions_pending_deoptimization_environment_ = NULL; 702 instruction_pending_deoptimization_environment_ = NULL;
671 pending_deoptimization_ast_id_ = AstNode::kNoNumber; 703 pending_deoptimization_ast_id_ = AstNode::kNoNumber;
672 } 704 }
673 705
674 706
675 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, 707 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
676 HInstruction* hinstr, 708 HInstruction* hinstr,
677 CanDeoptimize can_deoptimize) { 709 CanDeoptimize can_deoptimize) {
678 allocator_->MarkAsCall(); 710 #ifdef DEBUG
711 instr->VerifyCall();
712 #endif
713 instr->MarkAsCall();
679 instr = AssignPointerMap(instr); 714 instr = AssignPointerMap(instr);
680 715
681 if (hinstr->HasSideEffects()) { 716 if (hinstr->HasSideEffects()) {
682 ASSERT(hinstr->next()->IsSimulate()); 717 ASSERT(hinstr->next()->IsSimulate());
683 HSimulate* sim = HSimulate::cast(hinstr->next()); 718 HSimulate* sim = HSimulate::cast(hinstr->next());
684 instr = SetInstructionPendingDeoptimizationEnvironment( 719 instr = SetInstructionPendingDeoptimizationEnvironment(
685 instr, sim->ast_id()); 720 instr, sim->ast_id());
686 } 721 }
687 722
688 // If instruction does not have side-effects lazy deoptimization 723 // If instruction does not have side-effects lazy deoptimization
689 // 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.
690 // 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
691 // call sequence can not deoptimize eagerly. 726 // call sequence can not deoptimize eagerly.
692 bool needs_environment = 727 bool needs_environment =
693 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); 728 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
694 if (needs_environment && !instr->HasEnvironment()) { 729 if (needs_environment && !instr->HasEnvironment()) {
695 instr = AssignEnvironment(instr); 730 instr = AssignEnvironment(instr);
696 } 731 }
697 732
698 return instr; 733 return instr;
699 } 734 }
700 735
701 736
702 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { 737 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
703 allocator_->MarkAsSaveDoubles(); 738 instr->MarkAsSaveDoubles();
704 return instr; 739 return instr;
705 } 740 }
706 741
707 742
708 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { 743 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
709 ASSERT(!instr->HasPointerMap()); 744 ASSERT(!instr->HasPointerMap());
710 instr->set_pointer_map(new LPointerMap(position_)); 745 instr->set_pointer_map(new LPointerMap(position_));
711 return instr; 746 return instr;
712 } 747 }
713 748
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 } 937 }
903 block->set_argument_count(argument_count_); 938 block->set_argument_count(argument_count_);
904 next_block_ = NULL; 939 next_block_ = NULL;
905 current_block_ = NULL; 940 current_block_ = NULL;
906 } 941 }
907 942
908 943
909 void LChunkBuilder::VisitInstruction(HInstruction* current) { 944 void LChunkBuilder::VisitInstruction(HInstruction* current) {
910 HInstruction* old_current = current_instruction_; 945 HInstruction* old_current = current_instruction_;
911 current_instruction_ = current; 946 current_instruction_ = current;
912 allocator_->BeginInstruction();
913 if (current->has_position()) position_ = current->position(); 947 if (current->has_position()) position_ = current->position();
914 LInstruction* instr = current->CompileToLithium(this); 948 LInstruction* instr = current->CompileToLithium(this);
915 949
916 if (instr != NULL) { 950 if (instr != NULL) {
917 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 951 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
918 instr = AssignPointerMap(instr); 952 instr = AssignPointerMap(instr);
919 } 953 }
920 if (FLAG_stress_environments && !instr->HasEnvironment()) { 954 if (FLAG_stress_environments && !instr->HasEnvironment()) {
921 instr = AssignEnvironment(instr); 955 instr = AssignEnvironment(instr);
922 } 956 }
923 if (current->IsTest() && !instr->IsGoto()) { 957 if (current->IsTest() && !instr->IsGoto()) {
924 ASSERT(instr->IsControl()); 958 ASSERT(instr->IsControl());
925 HTest* test = HTest::cast(current); 959 HTest* test = HTest::cast(current);
926 instr->set_hydrogen_value(test->value()); 960 instr->set_hydrogen_value(test->value());
927 HBasicBlock* first = test->FirstSuccessor(); 961 HBasicBlock* first = test->FirstSuccessor();
928 HBasicBlock* second = test->SecondSuccessor(); 962 HBasicBlock* second = test->SecondSuccessor();
929 ASSERT(first != NULL && second != NULL); 963 ASSERT(first != NULL && second != NULL);
930 instr->SetBranchTargets(first->block_id(), second->block_id()); 964 instr->SetBranchTargets(first->block_id(), second->block_id());
931 } else { 965 } else {
932 instr->set_hydrogen_value(current); 966 instr->set_hydrogen_value(current);
933 } 967 }
934 968
935 int index = chunk_->AddInstruction(instr, current_block_); 969 chunk_->AddInstruction(instr, current_block_);
936 allocator_->SummarizeInstruction(index);
937 } else {
938 // This instruction should be omitted.
939 allocator_->OmitInstruction();
940 } 970 }
941 current_instruction_ = old_current; 971 current_instruction_ = old_current;
942 } 972 }
943 973
944 974
945 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { 975 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
946 if (hydrogen_env == NULL) return NULL; 976 if (hydrogen_env == NULL) return NULL;
947 977
948 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); 978 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
949 int ast_id = hydrogen_env->ast_id(); 979 int ast_id = hydrogen_env->ast_id();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 } else if (v->IsInstanceOf()) { 1091 } else if (v->IsInstanceOf()) {
1062 HInstanceOf* instance_of = HInstanceOf::cast(v); 1092 HInstanceOf* instance_of = HInstanceOf::cast(v);
1063 LInstanceOfAndBranch* result = 1093 LInstanceOfAndBranch* result =
1064 new LInstanceOfAndBranch( 1094 new LInstanceOfAndBranch(
1065 UseFixed(instance_of->left(), InstanceofStub::left()), 1095 UseFixed(instance_of->left(), InstanceofStub::left()),
1066 UseFixed(instance_of->right(), InstanceofStub::right())); 1096 UseFixed(instance_of->right(), InstanceofStub::right()));
1067 return MarkAsCall(result, instr); 1097 return MarkAsCall(result, instr);
1068 } else if (v->IsTypeofIs()) { 1098 } else if (v->IsTypeofIs()) {
1069 HTypeofIs* typeof_is = HTypeofIs::cast(v); 1099 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1070 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); 1100 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1101 } else if (v->IsIsConstructCall()) {
1102 return new LIsConstructCallAndBranch(TempRegister());
1071 } else { 1103 } else {
1072 if (v->IsConstant()) { 1104 if (v->IsConstant()) {
1073 if (HConstant::cast(v)->handle()->IsTrue()) { 1105 if (HConstant::cast(v)->handle()->IsTrue()) {
1074 return new LGoto(instr->FirstSuccessor()->block_id()); 1106 return new LGoto(instr->FirstSuccessor()->block_id());
1075 } else if (HConstant::cast(v)->handle()->IsFalse()) { 1107 } else if (HConstant::cast(v)->handle()->IsFalse()) {
1076 return new LGoto(instr->SecondSuccessor()->block_id()); 1108 return new LGoto(instr->SecondSuccessor()->block_id());
1077 } 1109 }
1078 } 1110 }
1079 Abort("Undefined compare before branch"); 1111 Abort("Undefined compare before branch");
1080 return NULL; 1112 return NULL;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 } 1165 }
1134 1166
1135 1167
1136 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1168 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1137 ++argument_count_; 1169 ++argument_count_;
1138 LOperand* argument = UseOrConstant(instr->argument()); 1170 LOperand* argument = UseOrConstant(instr->argument());
1139 return new LPushArgument(argument); 1171 return new LPushArgument(argument);
1140 } 1172 }
1141 1173
1142 1174
1175 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1176 return DefineAsRegister(new LContext);
1177 }
1178
1179
1180 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1181 LOperand* context = UseRegisterAtStart(instr->value());
1182 return DefineAsRegister(new LOuterContext(context));
1183 }
1184
1185
1143 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { 1186 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
1144 return DefineAsRegister(new LGlobalObject); 1187 LOperand* context = UseRegisterAtStart(instr->value());
1188 return DefineAsRegister(new LGlobalObject(context));
1145 } 1189 }
1146 1190
1147 1191
1148 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { 1192 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
1149 return DefineAsRegister(new LGlobalReceiver); 1193 LOperand* global_object = UseRegisterAtStart(instr->value());
1194 return DefineAsRegister(new LGlobalReceiver(global_object));
1150 } 1195 }
1151 1196
1152 1197
1153 LInstruction* LChunkBuilder::DoCallConstantFunction( 1198 LInstruction* LChunkBuilder::DoCallConstantFunction(
1154 HCallConstantFunction* instr) { 1199 HCallConstantFunction* instr) {
1155 argument_count_ -= instr->argument_count(); 1200 argument_count_ -= instr->argument_count();
1156 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr); 1201 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr);
1157 } 1202 }
1158 1203
1159 1204
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 } 1315 }
1271 1316
1272 1317
1273 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1318 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1274 if (instr->representation().IsDouble()) { 1319 if (instr->representation().IsDouble()) {
1275 return DoArithmeticD(Token::DIV, instr); 1320 return DoArithmeticD(Token::DIV, instr);
1276 } else if (instr->representation().IsInteger32()) { 1321 } else if (instr->representation().IsInteger32()) {
1277 // The temporary operand is necessary to ensure that right is not allocated 1322 // The temporary operand is necessary to ensure that right is not allocated
1278 // into edx. 1323 // into edx.
1279 LOperand* temp = FixedTemp(edx); 1324 LOperand* temp = FixedTemp(edx);
1280 LOperand* value = UseFixed(instr->left(), eax); 1325 LOperand* dividend = UseFixed(instr->left(), eax);
1281 LOperand* divisor = UseRegister(instr->right()); 1326 LOperand* divisor = UseRegister(instr->right());
1282 LDivI* result = new LDivI(value, divisor, temp); 1327 LDivI* result = new LDivI(dividend, divisor, temp);
1283 return AssignEnvironment(DefineFixed(result, eax)); 1328 return AssignEnvironment(DefineFixed(result, eax));
1284 } else { 1329 } else {
1285 ASSERT(instr->representation().IsTagged()); 1330 ASSERT(instr->representation().IsTagged());
1286 return DoArithmeticT(Token::DIV, instr); 1331 return DoArithmeticT(Token::DIV, instr);
1287 } 1332 }
1288 } 1333 }
1289 1334
1290 1335
1291 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1336 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1292 if (instr->representation().IsInteger32()) { 1337 if (instr->representation().IsInteger32()) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1500 return AssignEnvironment(DefineSameAsFirst(result)); 1545 return AssignEnvironment(DefineSameAsFirst(result));
1501 } 1546 }
1502 1547
1503 1548
1504 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1549 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1505 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1550 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1506 Use(instr->length()))); 1551 Use(instr->length())));
1507 } 1552 }
1508 1553
1509 1554
1555 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1556 // The control instruction marking the end of a block that completed
1557 // abruptly (e.g., threw an exception). There is nothing specific to do.
1558 return NULL;
1559 }
1560
1561
1510 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1562 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1511 LOperand* value = UseFixed(instr->value(), eax); 1563 LOperand* value = UseFixed(instr->value(), eax);
1512 return MarkAsCall(new LThrow(value), instr); 1564 return MarkAsCall(new LThrow(value), instr);
1513 } 1565 }
1514 1566
1515 1567
1516 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1568 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1517 Representation from = instr->from(); 1569 Representation from = instr->from();
1518 Representation to = instr->to(); 1570 Representation to = instr->to();
1519 if (from.IsTagged()) { 1571 if (from.IsTagged()) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 1668
1617 1669
1618 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1670 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1619 return new LReturn(UseFixed(instr->value(), eax)); 1671 return new LReturn(UseFixed(instr->value(), eax));
1620 } 1672 }
1621 1673
1622 1674
1623 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1675 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1624 Representation r = instr->representation(); 1676 Representation r = instr->representation();
1625 if (r.IsInteger32()) { 1677 if (r.IsInteger32()) {
1626 int32_t value = instr->Integer32Value(); 1678 return DefineAsRegister(new LConstantI);
1627 return DefineAsRegister(new LConstantI(value));
1628 } else if (r.IsDouble()) { 1679 } else if (r.IsDouble()) {
1629 double value = instr->DoubleValue(); 1680 double value = instr->DoubleValue();
1630 return DefineAsRegister(new LConstantD(value)); 1681 LOperand* temp = (BitCast<uint64_t, double>(value) != 0)
1682 ? TempRegister()
1683 : NULL;
1684 return DefineAsRegister(new LConstantD(temp));
1631 } else if (r.IsTagged()) { 1685 } else if (r.IsTagged()) {
1632 return DefineAsRegister(new LConstantT(instr->handle())); 1686 return DefineAsRegister(new LConstantT);
1633 } else { 1687 } else {
1634 UNREACHABLE(); 1688 UNREACHABLE();
1635 return NULL; 1689 return NULL;
1636 } 1690 }
1637 } 1691 }
1638 1692
1639 1693
1640 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { 1694 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) {
1641 LLoadGlobal* result = new LLoadGlobal; 1695 LLoadGlobal* result = new LLoadGlobal;
1642 return instr->check_hole_value() 1696 return instr->check_hole_value()
1643 ? AssignEnvironment(DefineAsRegister(result)) 1697 ? AssignEnvironment(DefineAsRegister(result))
1644 : DefineAsRegister(result); 1698 : DefineAsRegister(result);
1645 } 1699 }
1646 1700
1647 1701
1648 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { 1702 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) {
1649 return new LStoreGlobal(UseRegisterAtStart(instr->value())); 1703 LStoreGlobal* result = new LStoreGlobal(UseRegisterAtStart(instr->value()));
1704 return instr->check_hole_value() ? AssignEnvironment(result) : result;
1650 } 1705 }
1651 1706
1652 1707
1653 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 1708 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1654 return DefineAsRegister(new LLoadContextSlot); 1709 LOperand* context = UseRegisterAtStart(instr->value());
1710 return DefineAsRegister(new LLoadContextSlot(context));
1711 }
1712
1713
1714 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
1715 LOperand* context;
1716 LOperand* value;
1717 LOperand* temp;
1718 if (instr->NeedsWriteBarrier()) {
1719 context = UseTempRegister(instr->context());
1720 value = UseTempRegister(instr->value());
1721 temp = TempRegister();
1722 } else {
1723 context = UseRegister(instr->context());
1724 value = UseRegister(instr->value());
1725 temp = NULL;
1726 }
1727 return new LStoreContextSlot(context, value, temp);
1655 } 1728 }
1656 1729
1657 1730
1658 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 1731 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1659 ASSERT(instr->representation().IsTagged()); 1732 ASSERT(instr->representation().IsTagged());
1660 LOperand* obj = UseRegisterAtStart(instr->object()); 1733 LOperand* obj = UseRegisterAtStart(instr->object());
1661 return DefineAsRegister(new LLoadNamedField(obj)); 1734 return DefineAsRegister(new LLoadNamedField(obj));
1662 } 1735 }
1663 1736
1664 1737
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 ? UseTempRegister(instr->object()) 1815 ? UseTempRegister(instr->object())
1743 : UseRegisterAtStart(instr->object()); 1816 : UseRegisterAtStart(instr->object());
1744 1817
1745 LOperand* val = needs_write_barrier 1818 LOperand* val = needs_write_barrier
1746 ? UseTempRegister(instr->value()) 1819 ? UseTempRegister(instr->value())
1747 : UseRegister(instr->value()); 1820 : UseRegister(instr->value());
1748 1821
1749 // We only need a scratch register if we have a write barrier or we 1822 // We only need a scratch register if we have a write barrier or we
1750 // have a store into the properties array (not in-object-property). 1823 // have a store into the properties array (not in-object-property).
1751 LOperand* temp = (!instr->is_in_object() || needs_write_barrier) 1824 LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
1752 ? TempRegister() : NULL; 1825 ? TempRegister()
1826 : NULL;
1753 1827
1754 return new LStoreNamedField(obj, val, temp); 1828 return new LStoreNamedField(obj, val, temp);
1755 } 1829 }
1756 1830
1757 1831
1758 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 1832 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
1759 LOperand* obj = UseFixed(instr->object(), edx); 1833 LOperand* obj = UseFixed(instr->object(), edx);
1760 LOperand* val = UseFixed(instr->value(), eax); 1834 LOperand* val = UseFixed(instr->value(), eax);
1761 1835
1762 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, val); 1836 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, val);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1849 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 1923 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
1850 LTypeof* result = new LTypeof(UseAtStart(instr->value())); 1924 LTypeof* result = new LTypeof(UseAtStart(instr->value()));
1851 return MarkAsCall(DefineFixed(result, eax), instr); 1925 return MarkAsCall(DefineFixed(result, eax), instr);
1852 } 1926 }
1853 1927
1854 1928
1855 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 1929 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
1856 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 1930 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
1857 } 1931 }
1858 1932
1933
1934 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
1935 return DefineAsRegister(new LIsConstructCall);
1936 }
1937
1938
1859 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 1939 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
1860 HEnvironment* env = current_block_->last_environment(); 1940 HEnvironment* env = current_block_->last_environment();
1861 ASSERT(env != NULL); 1941 ASSERT(env != NULL);
1862 1942
1863 env->set_ast_id(instr->ast_id()); 1943 env->set_ast_id(instr->ast_id());
1864 1944
1865 env->Drop(instr->pop_count()); 1945 env->Drop(instr->pop_count());
1866 for (int i = 0; i < instr->values()->length(); ++i) { 1946 for (int i = 0; i < instr->values()->length(); ++i) {
1867 HValue* value = instr->values()->at(i); 1947 HValue* value = instr->values()->at(i);
1868 if (instr->HasAssignedIndexAt(i)) { 1948 if (instr->HasAssignedIndexAt(i)) {
1869 env->Bind(instr->GetAssignedIndexAt(i), value); 1949 env->Bind(instr->GetAssignedIndexAt(i), value);
1870 } else { 1950 } else {
1871 env->Push(value); 1951 env->Push(value);
1872 } 1952 }
1873 } 1953 }
1874 ASSERT(env->length() == instr->environment_length()); 1954 ASSERT(env->length() == instr->environment_length());
1875 1955
1876 // If there is an instruction pending deoptimization environment create a 1956 // If there is an instruction pending deoptimization environment create a
1877 // lazy bailout instruction to capture the environment. 1957 // lazy bailout instruction to capture the environment.
1878 if (pending_deoptimization_ast_id_ == instr->ast_id()) { 1958 if (pending_deoptimization_ast_id_ != AstNode::kNoNumber) {
1959 ASSERT(pending_deoptimization_ast_id_ == instr->ast_id());
1879 LLazyBailout* lazy_bailout = new LLazyBailout; 1960 LLazyBailout* lazy_bailout = new LLazyBailout;
1880 LInstruction* result = AssignEnvironment(lazy_bailout); 1961 LInstruction* result = AssignEnvironment(lazy_bailout);
1881 instructions_pending_deoptimization_environment_-> 1962 instruction_pending_deoptimization_environment_->
1882 set_deoptimization_environment(result->environment()); 1963 set_deoptimization_environment(result->environment());
1883 ClearInstructionPendingDeoptimizationEnvironment(); 1964 ClearInstructionPendingDeoptimizationEnvironment();
1884 return result; 1965 return result;
1885 } 1966 }
1886 1967
1887 return NULL; 1968 return NULL;
1888 } 1969 }
1889 1970
1890 1971
1891 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 1972 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
(...skipping 17 matching lines...) Expand all
1909 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 1990 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
1910 HEnvironment* outer = current_block_->last_environment()->outer(); 1991 HEnvironment* outer = current_block_->last_environment()->outer();
1911 current_block_->UpdateEnvironment(outer); 1992 current_block_->UpdateEnvironment(outer);
1912 return NULL; 1993 return NULL;
1913 } 1994 }
1914 1995
1915 1996
1916 } } // namespace v8::internal 1997 } } // namespace v8::internal
1917 1998
1918 #endif // V8_TARGET_ARCH_IA32 1999 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | src/isolate.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698