| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 value()->PrintTo(stream); | 410 value()->PrintTo(stream); |
| 411 } | 411 } |
| 412 | 412 |
| 413 | 413 |
| 414 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { | 414 void LTransitionElementsKind::PrintDataTo(StringStream* stream) { |
| 415 object()->PrintTo(stream); | 415 object()->PrintTo(stream); |
| 416 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); | 416 stream->Add(" %p -> %p", *original_map(), *transitioned_map()); |
| 417 } | 417 } |
| 418 | 418 |
| 419 | 419 |
| 420 int LPlatformChunk::GetNextSpillIndex(bool is_double) { | 420 int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) { |
| 421 // Skip a slot if for a double-width slot. | 421 // Skip a slot if for a double-width slot. |
| 422 if (is_double) spill_slot_count_++; | 422 if (kind == DOUBLE_REGISTERS) spill_slot_count_++; |
| 423 return spill_slot_count_++; | 423 return spill_slot_count_++; |
| 424 } | 424 } |
| 425 | 425 |
| 426 | 426 |
| 427 LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) { | 427 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { |
| 428 int index = GetNextSpillIndex(is_double); | 428 int index = GetNextSpillIndex(kind); |
| 429 if (is_double) { | 429 if (kind == DOUBLE_REGISTERS) { |
| 430 return LDoubleStackSlot::Create(index, zone()); | 430 return LDoubleStackSlot::Create(index, zone()); |
| 431 } else { | 431 } else { |
| 432 ASSERT(kind == GENERAL_REGISTERS); |
| 432 return LStackSlot::Create(index, zone()); | 433 return LStackSlot::Create(index, zone()); |
| 433 } | 434 } |
| 434 } | 435 } |
| 435 | 436 |
| 436 | 437 |
| 437 LPlatformChunk* LChunkBuilder::Build() { | 438 LPlatformChunk* LChunkBuilder::Build() { |
| 438 ASSERT(is_unused()); | 439 ASSERT(is_unused()); |
| 439 chunk_ = new(zone()) LPlatformChunk(info(), graph()); | 440 chunk_ = new(zone()) LPlatformChunk(info(), graph()); |
| 440 LPhase phase("L_Building chunk", chunk_); | 441 LPhase phase("L_Building chunk", chunk_); |
| 441 status_ = BUILDING; | 442 status_ = BUILDING; |
| 442 | 443 |
| 443 // If compiling for OSR, reserve space for the unoptimized frame, | 444 // If compiling for OSR, reserve space for the unoptimized frame, |
| 444 // which will be subsumed into this frame. | 445 // which will be subsumed into this frame. |
| 445 if (graph()->has_osr()) { | 446 if (graph()->has_osr()) { |
| 446 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { | 447 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
| 447 chunk_->GetNextSpillIndex(false); | 448 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); |
| 448 } | 449 } |
| 449 } | 450 } |
| 450 | 451 |
| 451 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); | 452 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); |
| 452 for (int i = 0; i < blocks->length(); i++) { | 453 for (int i = 0; i < blocks->length(); i++) { |
| 453 HBasicBlock* next = NULL; | 454 HBasicBlock* next = NULL; |
| 454 if (i < blocks->length() - 1) next = blocks->at(i + 1); | 455 if (i < blocks->length() - 1) next = blocks->at(i + 1); |
| 455 DoBasicBlock(blocks->at(i), next); | 456 DoBasicBlock(blocks->at(i), next); |
| 456 if (is_aborted()) return NULL; | 457 if (is_aborted()) return NULL; |
| 457 } | 458 } |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 } | 778 } |
| 778 } | 779 } |
| 779 | 780 |
| 780 | 781 |
| 781 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 782 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 782 HBinaryOperation* instr) { | 783 HBinaryOperation* instr) { |
| 783 HValue* left = instr->left(); | 784 HValue* left = instr->left(); |
| 784 HValue* right = instr->right(); | 785 HValue* right = instr->right(); |
| 785 ASSERT(left->representation().IsTagged()); | 786 ASSERT(left->representation().IsTagged()); |
| 786 ASSERT(right->representation().IsTagged()); | 787 ASSERT(right->representation().IsTagged()); |
| 788 LOperand* context = UseFixed(instr->context(), cp); |
| 787 LOperand* left_operand = UseFixed(left, a1); | 789 LOperand* left_operand = UseFixed(left, a1); |
| 788 LOperand* right_operand = UseFixed(right, a0); | 790 LOperand* right_operand = UseFixed(right, a0); |
| 789 LArithmeticT* result = | 791 LArithmeticT* result = |
| 790 new(zone()) LArithmeticT(op, left_operand, right_operand); | 792 new(zone()) LArithmeticT(op, context, left_operand, right_operand); |
| 791 return MarkAsCall(DefineFixed(result, v0), instr); | 793 return MarkAsCall(DefineFixed(result, v0), instr); |
| 792 } | 794 } |
| 793 | 795 |
| 794 | 796 |
| 795 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 797 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| 796 ASSERT(is_building()); | 798 ASSERT(is_building()); |
| 797 current_block_ = block; | 799 current_block_ = block; |
| 798 next_block_ = next_block; | 800 next_block_ = next_block; |
| 799 if (block->IsStartBlock()) { | 801 if (block->IsStartBlock()) { |
| 800 block->UpdateEnvironment(graph_->start_environment()); | 802 block->UpdateEnvironment(graph_->start_environment()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 block->set_argument_count(argument_count_); | 858 block->set_argument_count(argument_count_); |
| 857 next_block_ = NULL; | 859 next_block_ = NULL; |
| 858 current_block_ = NULL; | 860 current_block_ = NULL; |
| 859 } | 861 } |
| 860 | 862 |
| 861 | 863 |
| 862 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 864 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 863 HInstruction* old_current = current_instruction_; | 865 HInstruction* old_current = current_instruction_; |
| 864 current_instruction_ = current; | 866 current_instruction_ = current; |
| 865 if (current->has_position()) position_ = current->position(); | 867 if (current->has_position()) position_ = current->position(); |
| 866 LInstruction* instr = current->CompileToLithium(this); | 868 |
| 869 LInstruction* instr = NULL; |
| 870 if (current->CanReplaceWithDummyUses()) { |
| 871 HValue* first_operand = current->OperandCount() == 0 |
| 872 ? graph()->GetConstant1() |
| 873 : current->OperandAt(0); |
| 874 instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); |
| 875 for (int i = 1; i < current->OperandCount(); ++i) { |
| 876 LInstruction* dummy = |
| 877 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 878 dummy->set_hydrogen_value(current); |
| 879 chunk_->AddInstruction(dummy, current_block_); |
| 880 } |
| 881 } else { |
| 882 instr = current->CompileToLithium(this); |
| 883 } |
| 884 |
| 885 argument_count_ += current->argument_delta(); |
| 886 ASSERT(argument_count_ >= 0); |
| 867 | 887 |
| 868 if (instr != NULL) { | 888 if (instr != NULL) { |
| 889 // Associate the hydrogen instruction first, since we may need it for |
| 890 // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below. |
| 891 instr->set_hydrogen_value(current); |
| 892 |
| 869 #if DEBUG | 893 #if DEBUG |
| 870 // Make sure that the lithium instruction has either no fixed register | 894 // Make sure that the lithium instruction has either no fixed register |
| 871 // constraints in temps or the result OR no uses that are only used at | 895 // constraints in temps or the result OR no uses that are only used at |
| 872 // start. If this invariant doesn't hold, the register allocator can decide | 896 // start. If this invariant doesn't hold, the register allocator can decide |
| 873 // to insert a split of a range immediately before the instruction due to an | 897 // to insert a split of a range immediately before the instruction due to an |
| 874 // already allocated register needing to be used for the instruction's fixed | 898 // already allocated register needing to be used for the instruction's fixed |
| 875 // register constraint. In this case, The register allocator won't see an | 899 // register constraint. In this case, The register allocator won't see an |
| 876 // interference between the split child and the use-at-start (it would if | 900 // interference between the split child and the use-at-start (it would if |
| 877 // the it was just a plain use), so it is free to move the split child into | 901 // the it was just a plain use), so it is free to move the split child into |
| 878 // the same register that is used for the use-at-start. | 902 // the same register that is used for the use-at-start. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 895 } | 919 } |
| 896 #endif | 920 #endif |
| 897 | 921 |
| 898 instr->set_position(position_); | 922 instr->set_position(position_); |
| 899 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 923 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 900 instr = AssignPointerMap(instr); | 924 instr = AssignPointerMap(instr); |
| 901 } | 925 } |
| 902 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 926 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 903 instr = AssignEnvironment(instr); | 927 instr = AssignEnvironment(instr); |
| 904 } | 928 } |
| 905 instr->set_hydrogen_value(current); | |
| 906 chunk_->AddInstruction(instr, current_block_); | 929 chunk_->AddInstruction(instr, current_block_); |
| 907 } | 930 } |
| 908 current_instruction_ = old_current; | 931 current_instruction_ = old_current; |
| 909 } | 932 } |
| 910 | 933 |
| 911 | 934 |
| 912 LEnvironment* LChunkBuilder::CreateEnvironment( | 935 LEnvironment* LChunkBuilder::CreateEnvironment( |
| 913 HEnvironment* hydrogen_env, | 936 HEnvironment* hydrogen_env, |
| 914 int* argument_index_accumulator, | 937 int* argument_index_accumulator, |
| 915 ZoneList<HValue*>* objects_to_materialize) { | 938 ZoneList<HValue*>* objects_to_materialize) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 | 1010 |
| 988 if (hydrogen_env->frame_type() == JS_FUNCTION) { | 1011 if (hydrogen_env->frame_type() == JS_FUNCTION) { |
| 989 *argument_index_accumulator = argument_index; | 1012 *argument_index_accumulator = argument_index; |
| 990 } | 1013 } |
| 991 | 1014 |
| 992 return result; | 1015 return result; |
| 993 } | 1016 } |
| 994 | 1017 |
| 995 | 1018 |
| 996 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 1019 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 997 return new(zone()) LGoto(instr->FirstSuccessor()->block_id()); | 1020 return new(zone()) LGoto(instr->FirstSuccessor()); |
| 998 } | 1021 } |
| 999 | 1022 |
| 1000 | 1023 |
| 1001 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 1024 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
| 1025 LInstruction* goto_instr = CheckElideControlInstruction(instr); |
| 1026 if (goto_instr != NULL) return goto_instr; |
| 1027 |
| 1002 HValue* value = instr->value(); | 1028 HValue* value = instr->value(); |
| 1003 if (value->EmitAtUses()) { | |
| 1004 HBasicBlock* successor = HConstant::cast(value)->BooleanValue() | |
| 1005 ? instr->FirstSuccessor() | |
| 1006 : instr->SecondSuccessor(); | |
| 1007 return new(zone()) LGoto(successor->block_id()); | |
| 1008 } | |
| 1009 | |
| 1010 LBranch* result = new(zone()) LBranch(UseRegister(value)); | 1029 LBranch* result = new(zone()) LBranch(UseRegister(value)); |
| 1011 // Tagged values that are not known smis or booleans require a | 1030 // Tagged values that are not known smis or booleans require a |
| 1012 // deoptimization environment. If the instruction is generic no | 1031 // deoptimization environment. If the instruction is generic no |
| 1013 // environment is needed since all cases are handled. | 1032 // environment is needed since all cases are handled. |
| 1014 Representation rep = value->representation(); | 1033 Representation rep = value->representation(); |
| 1015 HType type = value->type(); | 1034 HType type = value->type(); |
| 1016 ToBooleanStub::Types expected = instr->expected_input_types(); | 1035 ToBooleanStub::Types expected = instr->expected_input_types(); |
| 1017 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && | 1036 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && |
| 1018 !expected.IsGeneric()) { | 1037 !expected.IsGeneric()) { |
| 1019 return AssignEnvironment(result); | 1038 return AssignEnvironment(result); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1037 } | 1056 } |
| 1038 | 1057 |
| 1039 | 1058 |
| 1040 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1059 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
| 1041 info()->MarkAsRequiresFrame(); | 1060 info()->MarkAsRequiresFrame(); |
| 1042 return DefineAsRegister(new(zone()) LArgumentsElements); | 1061 return DefineAsRegister(new(zone()) LArgumentsElements); |
| 1043 } | 1062 } |
| 1044 | 1063 |
| 1045 | 1064 |
| 1046 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { | 1065 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
| 1066 LOperand* context = UseFixed(instr->context(), cp); |
| 1047 LInstanceOf* result = | 1067 LInstanceOf* result = |
| 1048 new(zone()) LInstanceOf(UseFixed(instr->left(), a0), | 1068 new(zone()) LInstanceOf(context, UseFixed(instr->left(), a0), |
| 1049 UseFixed(instr->right(), a1)); | 1069 UseFixed(instr->right(), a1)); |
| 1050 return MarkAsCall(DefineFixed(result, v0), instr); | 1070 return MarkAsCall(DefineFixed(result, v0), instr); |
| 1051 } | 1071 } |
| 1052 | 1072 |
| 1053 | 1073 |
| 1054 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( | 1074 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
| 1055 HInstanceOfKnownGlobal* instr) { | 1075 HInstanceOfKnownGlobal* instr) { |
| 1056 LInstanceOfKnownGlobal* result = | 1076 LInstanceOfKnownGlobal* result = |
| 1057 new(zone()) LInstanceOfKnownGlobal(UseFixed(instr->left(), a0), | 1077 new(zone()) LInstanceOfKnownGlobal( |
| 1058 FixedTemp(t0)); | 1078 UseFixed(instr->context(), cp), |
| 1079 UseFixed(instr->left(), a0), |
| 1080 FixedTemp(t0)); |
| 1059 return MarkAsCall(DefineFixed(result, v0), instr); | 1081 return MarkAsCall(DefineFixed(result, v0), instr); |
| 1060 } | 1082 } |
| 1061 | 1083 |
| 1062 | 1084 |
| 1063 LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) { | 1085 LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) { |
| 1064 LOperand* object = UseRegisterAtStart(instr->object()); | 1086 LOperand* object = UseRegisterAtStart(instr->object()); |
| 1065 return DefineAsRegister(new(zone()) LInstanceSize(object)); | 1087 return DefineAsRegister(new(zone()) LInstanceSize(object)); |
| 1066 } | 1088 } |
| 1067 | 1089 |
| 1068 | 1090 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1081 LOperand* elements = UseFixed(instr->elements(), a3); | 1103 LOperand* elements = UseFixed(instr->elements(), a3); |
| 1082 LApplyArguments* result = new(zone()) LApplyArguments(function, | 1104 LApplyArguments* result = new(zone()) LApplyArguments(function, |
| 1083 receiver, | 1105 receiver, |
| 1084 length, | 1106 length, |
| 1085 elements); | 1107 elements); |
| 1086 return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY); | 1108 return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1087 } | 1109 } |
| 1088 | 1110 |
| 1089 | 1111 |
| 1090 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1112 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1091 ++argument_count_; | |
| 1092 LOperand* argument = Use(instr->argument()); | 1113 LOperand* argument = Use(instr->argument()); |
| 1093 return new(zone()) LPushArgument(argument); | 1114 return new(zone()) LPushArgument(argument); |
| 1094 } | 1115 } |
| 1095 | 1116 |
| 1096 | 1117 |
| 1097 LInstruction* LChunkBuilder::DoStoreCodeEntry( | 1118 LInstruction* LChunkBuilder::DoStoreCodeEntry( |
| 1098 HStoreCodeEntry* store_code_entry) { | 1119 HStoreCodeEntry* store_code_entry) { |
| 1099 LOperand* function = UseRegister(store_code_entry->function()); | 1120 LOperand* function = UseRegister(store_code_entry->function()); |
| 1100 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); | 1121 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); |
| 1101 return new(zone()) LStoreCodeEntry(function, code_object); | 1122 return new(zone()) LStoreCodeEntry(function, code_object); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1112 | 1133 |
| 1113 | 1134 |
| 1114 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { | 1135 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { |
| 1115 return instr->HasNoUses() | 1136 return instr->HasNoUses() |
| 1116 ? NULL | 1137 ? NULL |
| 1117 : DefineAsRegister(new(zone()) LThisFunction); | 1138 : DefineAsRegister(new(zone()) LThisFunction); |
| 1118 } | 1139 } |
| 1119 | 1140 |
| 1120 | 1141 |
| 1121 LInstruction* LChunkBuilder::DoContext(HContext* instr) { | 1142 LInstruction* LChunkBuilder::DoContext(HContext* instr) { |
| 1122 // If there is a non-return use, the context must be allocated in a register. | 1143 if (instr->HasNoUses()) return NULL; |
| 1123 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { | 1144 |
| 1124 if (!it.value()->IsReturn()) { | 1145 if (info()->IsStub()) { |
| 1125 return DefineAsRegister(new(zone()) LContext); | 1146 return DefineFixed(new(zone()) LContext, cp); |
| 1126 } | |
| 1127 } | 1147 } |
| 1128 | 1148 |
| 1129 return NULL; | 1149 return DefineAsRegister(new(zone()) LContext); |
| 1130 } | 1150 } |
| 1131 | 1151 |
| 1132 | 1152 |
| 1133 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { | 1153 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { |
| 1134 LOperand* context = UseRegisterAtStart(instr->value()); | 1154 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1135 return DefineAsRegister(new(zone()) LOuterContext(context)); | 1155 return DefineAsRegister(new(zone()) LOuterContext(context)); |
| 1136 } | 1156 } |
| 1137 | 1157 |
| 1138 | 1158 |
| 1139 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { | 1159 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { |
| 1140 return MarkAsCall(new(zone()) LDeclareGlobals, instr); | 1160 LOperand* context = UseFixed(instr->context(), cp); |
| 1161 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); |
| 1141 } | 1162 } |
| 1142 | 1163 |
| 1143 | 1164 |
| 1144 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { | 1165 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { |
| 1145 LOperand* context = UseRegisterAtStart(instr->value()); | 1166 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1146 return DefineAsRegister(new(zone()) LGlobalObject(context)); | 1167 return DefineAsRegister(new(zone()) LGlobalObject(context)); |
| 1147 } | 1168 } |
| 1148 | 1169 |
| 1149 | 1170 |
| 1150 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1171 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
| 1151 LOperand* global_object = UseRegisterAtStart(instr->value()); | 1172 LOperand* global_object = UseRegisterAtStart(instr->value()); |
| 1152 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); | 1173 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); |
| 1153 } | 1174 } |
| 1154 | 1175 |
| 1155 | 1176 |
| 1156 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1177 LInstruction* LChunkBuilder::DoCallConstantFunction( |
| 1157 HCallConstantFunction* instr) { | 1178 HCallConstantFunction* instr) { |
| 1158 argument_count_ -= instr->argument_count(); | |
| 1159 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, v0), instr); | 1179 return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, v0), instr); |
| 1160 } | 1180 } |
| 1161 | 1181 |
| 1162 | 1182 |
| 1163 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { | 1183 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { |
| 1184 LOperand* context = UseFixed(instr->context(), cp); |
| 1164 LOperand* function = UseFixed(instr->function(), a1); | 1185 LOperand* function = UseFixed(instr->function(), a1); |
| 1165 argument_count_ -= instr->argument_count(); | 1186 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); |
| 1166 LInvokeFunction* result = new(zone()) LInvokeFunction(function); | |
| 1167 return MarkAsCall(DefineFixed(result, v0), instr, CANNOT_DEOPTIMIZE_EAGERLY); | 1187 return MarkAsCall(DefineFixed(result, v0), instr, CANNOT_DEOPTIMIZE_EAGERLY); |
| 1168 } | 1188 } |
| 1169 | 1189 |
| 1170 | 1190 |
| 1171 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1191 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1172 switch (instr->op()) { | 1192 switch (instr->op()) { |
| 1173 case kMathFloor: return DoMathFloor(instr); | 1193 case kMathFloor: return DoMathFloor(instr); |
| 1174 case kMathRound: return DoMathRound(instr); | 1194 case kMathRound: return DoMathRound(instr); |
| 1175 case kMathAbs: return DoMathAbs(instr); | 1195 case kMathAbs: return DoMathAbs(instr); |
| 1176 case kMathLog: return DoMathLog(instr); | 1196 case kMathLog: return DoMathLog(instr); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { | 1250 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { |
| 1231 // Input cannot be the same as the result, see LCodeGen::DoMathPowHalf. | 1251 // Input cannot be the same as the result, see LCodeGen::DoMathPowHalf. |
| 1232 LOperand* input = UseFixedDouble(instr->value(), f8); | 1252 LOperand* input = UseFixedDouble(instr->value(), f8); |
| 1233 LOperand* temp = FixedTemp(f6); | 1253 LOperand* temp = FixedTemp(f6); |
| 1234 LMathPowHalf* result = new(zone()) LMathPowHalf(input, temp); | 1254 LMathPowHalf* result = new(zone()) LMathPowHalf(input, temp); |
| 1235 return DefineFixedDouble(result, f4); | 1255 return DefineFixedDouble(result, f4); |
| 1236 } | 1256 } |
| 1237 | 1257 |
| 1238 | 1258 |
| 1239 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { | 1259 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { |
| 1260 Representation r = instr->value()->representation(); |
| 1261 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) |
| 1262 ? NULL |
| 1263 : UseFixed(instr->context(), cp); |
| 1240 LOperand* input = UseRegister(instr->value()); | 1264 LOperand* input = UseRegister(instr->value()); |
| 1241 LMathAbs* result = new(zone()) LMathAbs(input); | 1265 LMathAbs* result = new(zone()) LMathAbs(context, input); |
| 1242 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1266 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1243 } | 1267 } |
| 1244 | 1268 |
| 1245 | 1269 |
| 1246 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { | 1270 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { |
| 1247 LOperand* input = UseRegister(instr->value()); | 1271 LOperand* input = UseRegister(instr->value()); |
| 1248 LOperand* temp = TempRegister(); | 1272 LOperand* temp = TempRegister(); |
| 1249 LMathFloor* result = new(zone()) LMathFloor(input, temp); | 1273 LMathFloor* result = new(zone()) LMathFloor(input, temp); |
| 1250 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1274 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1251 } | 1275 } |
| 1252 | 1276 |
| 1253 | 1277 |
| 1254 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { | 1278 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { |
| 1255 LOperand* input = UseRegister(instr->value()); | 1279 LOperand* input = UseRegister(instr->value()); |
| 1256 LMathSqrt* result = new(zone()) LMathSqrt(input); | 1280 LMathSqrt* result = new(zone()) LMathSqrt(input); |
| 1257 return DefineAsRegister(result); | 1281 return DefineAsRegister(result); |
| 1258 } | 1282 } |
| 1259 | 1283 |
| 1260 | 1284 |
| 1261 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { | 1285 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { |
| 1262 LOperand* input = UseRegister(instr->value()); | 1286 LOperand* input = UseRegister(instr->value()); |
| 1263 LOperand* temp = FixedTemp(f6); | 1287 LOperand* temp = FixedTemp(f6); |
| 1264 LMathRound* result = new(zone()) LMathRound(input, temp); | 1288 LMathRound* result = new(zone()) LMathRound(input, temp); |
| 1265 return AssignEnvironment(DefineAsRegister(result)); | 1289 return AssignEnvironment(DefineAsRegister(result)); |
| 1266 } | 1290 } |
| 1267 | 1291 |
| 1268 | 1292 |
| 1269 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1293 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
| 1270 ASSERT(instr->key()->representation().IsTagged()); | 1294 ASSERT(instr->key()->representation().IsTagged()); |
| 1271 argument_count_ -= instr->argument_count(); | 1295 LOperand* context = UseFixed(instr->context(), cp); |
| 1272 LOperand* key = UseFixed(instr->key(), a2); | 1296 LOperand* key = UseFixed(instr->key(), a2); |
| 1273 return MarkAsCall(DefineFixed(new(zone()) LCallKeyed(key), v0), instr); | 1297 return MarkAsCall( |
| 1298 DefineFixed(new(zone()) LCallKeyed(context, key), v0), instr); |
| 1274 } | 1299 } |
| 1275 | 1300 |
| 1276 | 1301 |
| 1277 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1302 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
| 1278 argument_count_ -= instr->argument_count(); | 1303 LOperand* context = UseFixed(instr->context(), cp); |
| 1279 return MarkAsCall(DefineFixed(new(zone()) LCallNamed, v0), instr); | 1304 return MarkAsCall(DefineFixed(new(zone()) LCallNamed(context), v0), instr); |
| 1280 } | 1305 } |
| 1281 | 1306 |
| 1282 | 1307 |
| 1283 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1308 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
| 1284 argument_count_ -= instr->argument_count(); | 1309 LOperand* context = UseFixed(instr->context(), cp); |
| 1285 return MarkAsCall(DefineFixed(new(zone()) LCallGlobal, v0), instr); | 1310 return MarkAsCall(DefineFixed(new(zone()) LCallGlobal(context), v0), instr); |
| 1286 } | 1311 } |
| 1287 | 1312 |
| 1288 | 1313 |
| 1289 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1314 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
| 1290 argument_count_ -= instr->argument_count(); | |
| 1291 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, v0), instr); | 1315 return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, v0), instr); |
| 1292 } | 1316 } |
| 1293 | 1317 |
| 1294 | 1318 |
| 1295 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1319 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
| 1320 LOperand* context = UseFixed(instr->context(), cp); |
| 1296 LOperand* constructor = UseFixed(instr->constructor(), a1); | 1321 LOperand* constructor = UseFixed(instr->constructor(), a1); |
| 1297 argument_count_ -= instr->argument_count(); | 1322 LCallNew* result = new(zone()) LCallNew(context, constructor); |
| 1298 LCallNew* result = new(zone()) LCallNew(constructor); | |
| 1299 return MarkAsCall(DefineFixed(result, v0), instr); | 1323 return MarkAsCall(DefineFixed(result, v0), instr); |
| 1300 } | 1324 } |
| 1301 | 1325 |
| 1302 | 1326 |
| 1303 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { | 1327 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { |
| 1328 LOperand* context = UseFixed(instr->context(), cp); |
| 1304 LOperand* constructor = UseFixed(instr->constructor(), a1); | 1329 LOperand* constructor = UseFixed(instr->constructor(), a1); |
| 1305 argument_count_ -= instr->argument_count(); | 1330 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); |
| 1306 LCallNewArray* result = new(zone()) LCallNewArray(constructor); | |
| 1307 return MarkAsCall(DefineFixed(result, v0), instr); | 1331 return MarkAsCall(DefineFixed(result, v0), instr); |
| 1308 } | 1332 } |
| 1309 | 1333 |
| 1310 | 1334 |
| 1311 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1335 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1336 LOperand* context = UseFixed(instr->context(), cp); |
| 1312 LOperand* function = UseFixed(instr->function(), a1); | 1337 LOperand* function = UseFixed(instr->function(), a1); |
| 1313 argument_count_ -= instr->argument_count(); | 1338 return MarkAsCall( |
| 1314 return MarkAsCall(DefineFixed(new(zone()) LCallFunction(function), v0), | 1339 DefineFixed(new(zone()) LCallFunction(context, function), v0), instr); |
| 1315 instr); | |
| 1316 } | 1340 } |
| 1317 | 1341 |
| 1318 | 1342 |
| 1319 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1343 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1320 argument_count_ -= instr->argument_count(); | 1344 LOperand* context = UseFixed(instr->context(), cp); |
| 1321 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, v0), instr); | 1345 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), v0), instr); |
| 1322 } | 1346 } |
| 1323 | 1347 |
| 1324 | 1348 |
| 1325 LInstruction* LChunkBuilder::DoRor(HRor* instr) { | 1349 LInstruction* LChunkBuilder::DoRor(HRor* instr) { |
| 1326 return DoShift(Token::ROR, instr); | 1350 return DoShift(Token::ROR, instr); |
| 1327 } | 1351 } |
| 1328 | 1352 |
| 1329 | 1353 |
| 1330 LInstruction* LChunkBuilder::DoShr(HShr* instr) { | 1354 LInstruction* LChunkBuilder::DoShr(HShr* instr) { |
| 1331 return DoShift(Token::SHR, instr); | 1355 return DoShift(Token::SHR, instr); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1462 } else { | 1486 } else { |
| 1463 return DoArithmeticT(Token::MOD, instr); | 1487 return DoArithmeticT(Token::MOD, instr); |
| 1464 } | 1488 } |
| 1465 } | 1489 } |
| 1466 | 1490 |
| 1467 | 1491 |
| 1468 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1492 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1469 if (instr->representation().IsSmiOrInteger32()) { | 1493 if (instr->representation().IsSmiOrInteger32()) { |
| 1470 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1494 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1471 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1495 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1472 LOperand* left; | 1496 HValue* left = instr->BetterLeftOperand(); |
| 1473 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1497 HValue* right = instr->BetterRightOperand(); |
| 1474 LOperand* temp = NULL; | 1498 LOperand* left_op; |
| 1475 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) && | 1499 LOperand* right_op; |
| 1476 (instr->CheckFlag(HValue::kCanOverflow) || | 1500 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| 1477 !right->IsConstantOperand())) { | 1501 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); |
| 1478 left = UseRegister(instr->BetterLeftOperand()); | 1502 |
| 1479 temp = TempRegister(); | 1503 if (right->IsConstant()) { |
| 1504 HConstant* constant = HConstant::cast(right); |
| 1505 int32_t constant_value = constant->Integer32Value(); |
| 1506 // Constants -1, 0 and 1 can be optimized if the result can overflow. |
| 1507 // For other constants, it can be optimized only without overflow. |
| 1508 if (!can_overflow || ((constant_value >= -1) && (constant_value <= 1))) { |
| 1509 left_op = UseRegisterAtStart(left); |
| 1510 right_op = UseConstant(right); |
| 1511 } else { |
| 1512 if (bailout_on_minus_zero) { |
| 1513 left_op = UseRegister(left); |
| 1514 } else { |
| 1515 left_op = UseRegisterAtStart(left); |
| 1516 } |
| 1517 right_op = UseRegister(right); |
| 1518 } |
| 1480 } else { | 1519 } else { |
| 1481 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1520 if (bailout_on_minus_zero) { |
| 1521 left_op = UseRegister(left); |
| 1522 } else { |
| 1523 left_op = UseRegisterAtStart(left); |
| 1524 } |
| 1525 right_op = UseRegister(right); |
| 1482 } | 1526 } |
| 1483 LMulI* mul = new(zone()) LMulI(left, right, temp); | 1527 LMulI* mul = new(zone()) LMulI(left_op, right_op); |
| 1484 if (instr->CheckFlag(HValue::kCanOverflow) || | 1528 if (can_overflow || bailout_on_minus_zero) { |
| 1485 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 1486 AssignEnvironment(mul); | 1529 AssignEnvironment(mul); |
| 1487 } | 1530 } |
| 1488 return DefineAsRegister(mul); | 1531 return DefineAsRegister(mul); |
| 1489 | 1532 |
| 1490 } else if (instr->representation().IsDouble()) { | 1533 } else if (instr->representation().IsDouble()) { |
| 1491 if (kArchVariant == kMips32r2) { | 1534 if (kArchVariant == kMips32r2) { |
| 1492 if (instr->UseCount() == 1 && instr->uses().value()->IsAdd()) { | 1535 if (instr->UseCount() == 1 && instr->uses().value()->IsAdd()) { |
| 1493 HAdd* add = HAdd::cast(instr->uses().value()); | 1536 HAdd* add = HAdd::cast(instr->uses().value()); |
| 1494 if (instr == add->left()) { | 1537 if (instr == add->left()) { |
| 1495 // This mul is the lhs of an add. The add and mul will be folded | 1538 // This mul is the lhs of an add. The add and mul will be folded |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1613 LOperand* scratch3 = TempRegister(); | 1656 LOperand* scratch3 = TempRegister(); |
| 1614 LRandom* result = new(zone()) LRandom( | 1657 LRandom* result = new(zone()) LRandom( |
| 1615 global_object, scratch, scratch2, scratch3); | 1658 global_object, scratch, scratch2, scratch3); |
| 1616 return DefineFixedDouble(result, f0); | 1659 return DefineFixedDouble(result, f0); |
| 1617 } | 1660 } |
| 1618 | 1661 |
| 1619 | 1662 |
| 1620 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { | 1663 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
| 1621 ASSERT(instr->left()->representation().IsTagged()); | 1664 ASSERT(instr->left()->representation().IsTagged()); |
| 1622 ASSERT(instr->right()->representation().IsTagged()); | 1665 ASSERT(instr->right()->representation().IsTagged()); |
| 1666 LOperand* context = UseFixed(instr->context(), cp); |
| 1623 LOperand* left = UseFixed(instr->left(), a1); | 1667 LOperand* left = UseFixed(instr->left(), a1); |
| 1624 LOperand* right = UseFixed(instr->right(), a0); | 1668 LOperand* right = UseFixed(instr->right(), a0); |
| 1625 LCmpT* result = new(zone()) LCmpT(left, right); | 1669 LCmpT* result = new(zone()) LCmpT(context, left, right); |
| 1626 return MarkAsCall(DefineFixed(result, v0), instr); | 1670 return MarkAsCall(DefineFixed(result, v0), instr); |
| 1627 } | 1671 } |
| 1628 | 1672 |
| 1629 | 1673 |
| 1630 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1674 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
| 1631 HCompareNumericAndBranch* instr) { | 1675 HCompareNumericAndBranch* instr) { |
| 1632 Representation r = instr->representation(); | 1676 Representation r = instr->representation(); |
| 1633 if (r.IsSmiOrInteger32()) { | 1677 if (r.IsSmiOrInteger32()) { |
| 1634 ASSERT(instr->left()->representation().Equals(r)); | 1678 ASSERT(instr->left()->representation().Equals(r)); |
| 1635 ASSERT(instr->right()->representation().Equals(r)); | 1679 ASSERT(instr->right()->representation().Equals(r)); |
| 1636 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1680 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
| 1637 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); | 1681 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); |
| 1638 return new(zone()) LCompareNumericAndBranch(left, right); | 1682 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1639 } else { | 1683 } else { |
| 1640 ASSERT(r.IsDouble()); | 1684 ASSERT(r.IsDouble()); |
| 1641 ASSERT(instr->left()->representation().IsDouble()); | 1685 ASSERT(instr->left()->representation().IsDouble()); |
| 1642 ASSERT(instr->right()->representation().IsDouble()); | 1686 ASSERT(instr->right()->representation().IsDouble()); |
| 1643 LOperand* left = UseRegisterAtStart(instr->left()); | 1687 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1644 LOperand* right = UseRegisterAtStart(instr->right()); | 1688 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1645 return new(zone()) LCompareNumericAndBranch(left, right); | 1689 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1646 } | 1690 } |
| 1647 } | 1691 } |
| 1648 | 1692 |
| 1649 | 1693 |
| 1650 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1694 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
| 1651 HCompareObjectEqAndBranch* instr) { | 1695 HCompareObjectEqAndBranch* instr) { |
| 1696 LInstruction* goto_instr = CheckElideControlInstruction(instr); |
| 1697 if (goto_instr != NULL) return goto_instr; |
| 1652 LOperand* left = UseRegisterAtStart(instr->left()); | 1698 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1653 LOperand* right = UseRegisterAtStart(instr->right()); | 1699 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1654 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1700 return new(zone()) LCmpObjectEqAndBranch(left, right); |
| 1655 } | 1701 } |
| 1656 | 1702 |
| 1657 | 1703 |
| 1658 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( | 1704 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( |
| 1659 HCompareHoleAndBranch* instr) { | 1705 HCompareHoleAndBranch* instr) { |
| 1660 LOperand* value = UseRegisterAtStart(instr->value()); | 1706 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1661 return new(zone()) LCmpHoleAndBranch(value); | 1707 return new(zone()) LCmpHoleAndBranch(value); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1689 ASSERT(instr->value()->representation().IsTagged()); | 1735 ASSERT(instr->value()->representation().IsTagged()); |
| 1690 return new(zone()) LIsUndetectableAndBranch( | 1736 return new(zone()) LIsUndetectableAndBranch( |
| 1691 UseRegisterAtStart(instr->value()), TempRegister()); | 1737 UseRegisterAtStart(instr->value()), TempRegister()); |
| 1692 } | 1738 } |
| 1693 | 1739 |
| 1694 | 1740 |
| 1695 LInstruction* LChunkBuilder::DoStringCompareAndBranch( | 1741 LInstruction* LChunkBuilder::DoStringCompareAndBranch( |
| 1696 HStringCompareAndBranch* instr) { | 1742 HStringCompareAndBranch* instr) { |
| 1697 ASSERT(instr->left()->representation().IsTagged()); | 1743 ASSERT(instr->left()->representation().IsTagged()); |
| 1698 ASSERT(instr->right()->representation().IsTagged()); | 1744 ASSERT(instr->right()->representation().IsTagged()); |
| 1745 LOperand* context = UseFixed(instr->context(), cp); |
| 1699 LOperand* left = UseFixed(instr->left(), a1); | 1746 LOperand* left = UseFixed(instr->left(), a1); |
| 1700 LOperand* right = UseFixed(instr->right(), a0); | 1747 LOperand* right = UseFixed(instr->right(), a0); |
| 1701 LStringCompareAndBranch* result = | 1748 LStringCompareAndBranch* result = |
| 1702 new(zone()) LStringCompareAndBranch(left, right); | 1749 new(zone()) LStringCompareAndBranch(context, left, right); |
| 1703 return MarkAsCall(result, instr); | 1750 return MarkAsCall(result, instr); |
| 1704 } | 1751 } |
| 1705 | 1752 |
| 1706 | 1753 |
| 1707 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( | 1754 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( |
| 1708 HHasInstanceTypeAndBranch* instr) { | 1755 HHasInstanceTypeAndBranch* instr) { |
| 1709 ASSERT(instr->value()->representation().IsTagged()); | 1756 ASSERT(instr->value()->representation().IsTagged()); |
| 1710 LOperand* value = UseRegisterAtStart(instr->value()); | 1757 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1711 return new(zone()) LHasInstanceTypeAndBranch(value); | 1758 return new(zone()) LHasInstanceTypeAndBranch(value); |
| 1712 } | 1759 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1787 | 1834 |
| 1788 | 1835 |
| 1789 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { | 1836 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| 1790 // The control instruction marking the end of a block that completed | 1837 // The control instruction marking the end of a block that completed |
| 1791 // abruptly (e.g., threw an exception). There is nothing specific to do. | 1838 // abruptly (e.g., threw an exception). There is nothing specific to do. |
| 1792 return NULL; | 1839 return NULL; |
| 1793 } | 1840 } |
| 1794 | 1841 |
| 1795 | 1842 |
| 1796 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1843 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
| 1844 LOperand* context = UseFixed(instr->context(), cp); |
| 1797 LOperand* value = UseFixed(instr->value(), a0); | 1845 LOperand* value = UseFixed(instr->value(), a0); |
| 1798 return MarkAsCall(new(zone()) LThrow(value), instr); | 1846 return MarkAsCall(new(zone()) LThrow(context, value), instr); |
| 1799 } | 1847 } |
| 1800 | 1848 |
| 1801 | 1849 |
| 1802 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { | 1850 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { |
| 1803 return NULL; | 1851 return NULL; |
| 1804 } | 1852 } |
| 1805 | 1853 |
| 1806 | 1854 |
| 1807 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { | 1855 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { |
| 1808 // All HForceRepresentation instructions should be eliminated in the | 1856 // All HForceRepresentation instructions should be eliminated in the |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1969 ASSERT(input_rep.IsSmiOrTagged()); | 2017 ASSERT(input_rep.IsSmiOrTagged()); |
| 1970 // Register allocator doesn't (yet) support allocation of double | 2018 // Register allocator doesn't (yet) support allocation of double |
| 1971 // temps. Reserve f22 explicitly. | 2019 // temps. Reserve f22 explicitly. |
| 1972 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, FixedTemp(f22)); | 2020 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, FixedTemp(f22)); |
| 1973 return AssignEnvironment(DefineAsRegister(result)); | 2021 return AssignEnvironment(DefineAsRegister(result)); |
| 1974 } | 2022 } |
| 1975 } | 2023 } |
| 1976 | 2024 |
| 1977 | 2025 |
| 1978 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 2026 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
| 2027 LOperand* context = info()->IsStub() |
| 2028 ? UseFixed(instr->context(), cp) |
| 2029 : NULL; |
| 1979 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); | 2030 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); |
| 1980 return new(zone()) LReturn(UseFixed(instr->value(), v0), | 2031 return new(zone()) LReturn(UseFixed(instr->value(), v0), context, |
| 1981 parameter_count); | 2032 parameter_count); |
| 1982 } | 2033 } |
| 1983 | 2034 |
| 1984 | 2035 |
| 1985 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 2036 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1986 Representation r = instr->representation(); | 2037 Representation r = instr->representation(); |
| 1987 if (r.IsSmi()) { | 2038 if (r.IsSmi()) { |
| 1988 return DefineAsRegister(new(zone()) LConstantS); | 2039 return DefineAsRegister(new(zone()) LConstantS); |
| 1989 } else if (r.IsInteger32()) { | 2040 } else if (r.IsInteger32()) { |
| 1990 return DefineAsRegister(new(zone()) LConstantI); | 2041 return DefineAsRegister(new(zone()) LConstantI); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2003 | 2054 |
| 2004 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { | 2055 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { |
| 2005 LLoadGlobalCell* result = new(zone()) LLoadGlobalCell; | 2056 LLoadGlobalCell* result = new(zone()) LLoadGlobalCell; |
| 2006 return instr->RequiresHoleCheck() | 2057 return instr->RequiresHoleCheck() |
| 2007 ? AssignEnvironment(DefineAsRegister(result)) | 2058 ? AssignEnvironment(DefineAsRegister(result)) |
| 2008 : DefineAsRegister(result); | 2059 : DefineAsRegister(result); |
| 2009 } | 2060 } |
| 2010 | 2061 |
| 2011 | 2062 |
| 2012 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { | 2063 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { |
| 2064 LOperand* context = UseFixed(instr->context(), cp); |
| 2013 LOperand* global_object = UseFixed(instr->global_object(), a0); | 2065 LOperand* global_object = UseFixed(instr->global_object(), a0); |
| 2014 LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(global_object); | 2066 LLoadGlobalGeneric* result = |
| 2067 new(zone()) LLoadGlobalGeneric(context, global_object); |
| 2015 return MarkAsCall(DefineFixed(result, v0), instr); | 2068 return MarkAsCall(DefineFixed(result, v0), instr); |
| 2016 } | 2069 } |
| 2017 | 2070 |
| 2018 | 2071 |
| 2019 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { | 2072 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { |
| 2020 LOperand* value = UseRegister(instr->value()); | 2073 LOperand* value = UseRegister(instr->value()); |
| 2021 // Use a temp to check the value in the cell in the case where we perform | 2074 // Use a temp to check the value in the cell in the case where we perform |
| 2022 // a hole check. | 2075 // a hole check. |
| 2023 return instr->RequiresHoleCheck() | 2076 return instr->RequiresHoleCheck() |
| 2024 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) | 2077 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) |
| 2025 : new(zone()) LStoreGlobalCell(value, NULL); | 2078 : new(zone()) LStoreGlobalCell(value, NULL); |
| 2026 } | 2079 } |
| 2027 | 2080 |
| 2028 | 2081 |
| 2029 LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) { | 2082 LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) { |
| 2083 LOperand* context = UseFixed(instr->context(), cp); |
| 2030 LOperand* global_object = UseFixed(instr->global_object(), a1); | 2084 LOperand* global_object = UseFixed(instr->global_object(), a1); |
| 2031 LOperand* value = UseFixed(instr->value(), a0); | 2085 LOperand* value = UseFixed(instr->value(), a0); |
| 2032 LStoreGlobalGeneric* result = | 2086 LStoreGlobalGeneric* result = |
| 2033 new(zone()) LStoreGlobalGeneric(global_object, value); | 2087 new(zone()) LStoreGlobalGeneric(context, global_object, value); |
| 2034 return MarkAsCall(result, instr); | 2088 return MarkAsCall(result, instr); |
| 2035 } | 2089 } |
| 2036 | 2090 |
| 2037 | 2091 |
| 2038 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { | 2092 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { |
| 2039 LOperand* context = UseRegisterAtStart(instr->value()); | 2093 LOperand* context = UseRegisterAtStart(instr->value()); |
| 2040 LInstruction* result = | 2094 LInstruction* result = |
| 2041 DefineAsRegister(new(zone()) LLoadContextSlot(context)); | 2095 DefineAsRegister(new(zone()) LLoadContextSlot(context)); |
| 2042 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; | 2096 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; |
| 2043 } | 2097 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2058 } | 2112 } |
| 2059 | 2113 |
| 2060 | 2114 |
| 2061 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 2115 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 2062 LOperand* obj = UseRegisterAtStart(instr->object()); | 2116 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 2063 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); | 2117 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); |
| 2064 } | 2118 } |
| 2065 | 2119 |
| 2066 | 2120 |
| 2067 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 2121 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 2122 LOperand* context = UseFixed(instr->context(), cp); |
| 2068 LOperand* object = UseFixed(instr->object(), a0); | 2123 LOperand* object = UseFixed(instr->object(), a0); |
| 2069 LInstruction* result = DefineFixed(new(zone()) LLoadNamedGeneric(object), v0); | 2124 LInstruction* result = |
| 2125 DefineFixed(new(zone()) LLoadNamedGeneric(context, object), v0); |
| 2070 return MarkAsCall(result, instr); | 2126 return MarkAsCall(result, instr); |
| 2071 } | 2127 } |
| 2072 | 2128 |
| 2073 | 2129 |
| 2074 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( | 2130 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
| 2075 HLoadFunctionPrototype* instr) { | 2131 HLoadFunctionPrototype* instr) { |
| 2076 return AssignEnvironment(DefineAsRegister( | 2132 return AssignEnvironment(DefineAsRegister( |
| 2077 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); | 2133 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); |
| 2078 } | 2134 } |
| 2079 | 2135 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2092 | 2148 |
| 2093 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2149 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2094 ASSERT(instr->key()->representation().IsSmiOrInteger32()); | 2150 ASSERT(instr->key()->representation().IsSmiOrInteger32()); |
| 2095 ElementsKind elements_kind = instr->elements_kind(); | 2151 ElementsKind elements_kind = instr->elements_kind(); |
| 2096 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2152 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2097 LLoadKeyed* result = NULL; | 2153 LLoadKeyed* result = NULL; |
| 2098 | 2154 |
| 2099 if (!instr->is_external()) { | 2155 if (!instr->is_external()) { |
| 2100 LOperand* obj = NULL; | 2156 LOperand* obj = NULL; |
| 2101 if (instr->representation().IsDouble()) { | 2157 if (instr->representation().IsDouble()) { |
| 2102 obj = UseTempRegister(instr->elements()); | 2158 obj = UseRegister(instr->elements()); |
| 2103 } else { | 2159 } else { |
| 2104 ASSERT(instr->representation().IsSmiOrTagged()); | 2160 ASSERT(instr->representation().IsSmiOrTagged()); |
| 2105 obj = UseRegisterAtStart(instr->elements()); | 2161 obj = UseRegisterAtStart(instr->elements()); |
| 2106 } | 2162 } |
| 2107 result = new(zone()) LLoadKeyed(obj, key); | 2163 result = new(zone()) LLoadKeyed(obj, key); |
| 2108 } else { | 2164 } else { |
| 2109 ASSERT( | 2165 ASSERT( |
| 2110 (instr->representation().IsInteger32() && | 2166 (instr->representation().IsInteger32() && |
| 2111 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && | 2167 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && |
| 2112 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || | 2168 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || |
| 2113 (instr->representation().IsDouble() && | 2169 (instr->representation().IsDouble() && |
| 2114 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || | 2170 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || |
| 2115 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); | 2171 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); |
| 2116 LOperand* external_pointer = UseRegister(instr->elements()); | 2172 LOperand* external_pointer = UseRegister(instr->elements()); |
| 2117 result = new(zone()) LLoadKeyed(external_pointer, key); | 2173 result = new(zone()) LLoadKeyed(external_pointer, key); |
| 2118 } | 2174 } |
| 2119 | 2175 |
| 2120 DefineAsRegister(result); | 2176 DefineAsRegister(result); |
| 2121 // An unsigned int array load might overflow and cause a deopt, make sure it | 2177 // An unsigned int array load might overflow and cause a deopt, make sure it |
| 2122 // has an environment. | 2178 // has an environment. |
| 2123 bool can_deoptimize = instr->RequiresHoleCheck() || | 2179 bool can_deoptimize = instr->RequiresHoleCheck() || |
| 2124 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS); | 2180 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS); |
| 2125 return can_deoptimize ? AssignEnvironment(result) : result; | 2181 return can_deoptimize ? AssignEnvironment(result) : result; |
| 2126 } | 2182 } |
| 2127 | 2183 |
| 2128 | 2184 |
| 2129 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 2185 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 2186 LOperand* context = UseFixed(instr->context(), cp); |
| 2130 LOperand* object = UseFixed(instr->object(), a1); | 2187 LOperand* object = UseFixed(instr->object(), a1); |
| 2131 LOperand* key = UseFixed(instr->key(), a0); | 2188 LOperand* key = UseFixed(instr->key(), a0); |
| 2132 | 2189 |
| 2133 LInstruction* result = | 2190 LInstruction* result = |
| 2134 DefineFixed(new(zone()) LLoadKeyedGeneric(object, key), v0); | 2191 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), v0); |
| 2135 return MarkAsCall(result, instr); | 2192 return MarkAsCall(result, instr); |
| 2136 } | 2193 } |
| 2137 | 2194 |
| 2138 | 2195 |
| 2139 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2196 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2140 if (!instr->is_external()) { | 2197 if (!instr->is_external()) { |
| 2141 ASSERT(instr->elements()->representation().IsTagged()); | 2198 ASSERT(instr->elements()->representation().IsTagged()); |
| 2142 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2199 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 2143 LOperand* object = NULL; | 2200 LOperand* object = NULL; |
| 2144 LOperand* val = NULL; | 2201 LOperand* val = NULL; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2174 ASSERT(instr->elements()->representation().IsExternal()); | 2231 ASSERT(instr->elements()->representation().IsExternal()); |
| 2175 LOperand* val = UseRegister(instr->value()); | 2232 LOperand* val = UseRegister(instr->value()); |
| 2176 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2233 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2177 LOperand* external_pointer = UseRegister(instr->elements()); | 2234 LOperand* external_pointer = UseRegister(instr->elements()); |
| 2178 | 2235 |
| 2179 return new(zone()) LStoreKeyed(external_pointer, key, val); | 2236 return new(zone()) LStoreKeyed(external_pointer, key, val); |
| 2180 } | 2237 } |
| 2181 | 2238 |
| 2182 | 2239 |
| 2183 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2240 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 2241 LOperand* context = UseFixed(instr->context(), cp); |
| 2184 LOperand* obj = UseFixed(instr->object(), a2); | 2242 LOperand* obj = UseFixed(instr->object(), a2); |
| 2185 LOperand* key = UseFixed(instr->key(), a1); | 2243 LOperand* key = UseFixed(instr->key(), a1); |
| 2186 LOperand* val = UseFixed(instr->value(), a0); | 2244 LOperand* val = UseFixed(instr->value(), a0); |
| 2187 | 2245 |
| 2188 ASSERT(instr->object()->representation().IsTagged()); | 2246 ASSERT(instr->object()->representation().IsTagged()); |
| 2189 ASSERT(instr->key()->representation().IsTagged()); | 2247 ASSERT(instr->key()->representation().IsTagged()); |
| 2190 ASSERT(instr->value()->representation().IsTagged()); | 2248 ASSERT(instr->value()->representation().IsTagged()); |
| 2191 | 2249 |
| 2192 return MarkAsCall(new(zone()) LStoreKeyedGeneric(obj, key, val), instr); | 2250 return MarkAsCall( |
| 2251 new(zone()) LStoreKeyedGeneric(context, obj, key, val), instr); |
| 2193 } | 2252 } |
| 2194 | 2253 |
| 2195 | 2254 |
| 2196 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2255 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
| 2197 HTransitionElementsKind* instr) { | 2256 HTransitionElementsKind* instr) { |
| 2198 LOperand* object = UseRegister(instr->object()); | 2257 LOperand* object = UseRegister(instr->object()); |
| 2199 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2258 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
| 2200 LOperand* new_map_reg = TempRegister(); | 2259 LOperand* new_map_reg = TempRegister(); |
| 2201 LTransitionElementsKind* result = | 2260 LTransitionElementsKind* result = |
| 2202 new(zone()) LTransitionElementsKind(object, new_map_reg); | 2261 new(zone()) LTransitionElementsKind(object, NULL, new_map_reg); |
| 2203 return result; | 2262 return result; |
| 2204 } else { | 2263 } else { |
| 2264 LOperand* context = UseFixed(instr->context(), cp); |
| 2205 LTransitionElementsKind* result = | 2265 LTransitionElementsKind* result = |
| 2206 new(zone()) LTransitionElementsKind(object, NULL); | 2266 new(zone()) LTransitionElementsKind(object, context, NULL); |
| 2207 return AssignPointerMap(result); | 2267 return AssignPointerMap(result); |
| 2208 } | 2268 } |
| 2209 } | 2269 } |
| 2210 | 2270 |
| 2211 | 2271 |
| 2212 LInstruction* LChunkBuilder::DoTrapAllocationMemento( | 2272 LInstruction* LChunkBuilder::DoTrapAllocationMemento( |
| 2213 HTrapAllocationMemento* instr) { | 2273 HTrapAllocationMemento* instr) { |
| 2214 LOperand* object = UseRegister(instr->object()); | 2274 LOperand* object = UseRegister(instr->object()); |
| 2215 LOperand* temp = TempRegister(); | 2275 LOperand* temp = TempRegister(); |
| 2216 LTrapAllocationMemento* result = | 2276 LTrapAllocationMemento* result = |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2255 instr->field_representation().IsHeapObject()) { | 2315 instr->field_representation().IsHeapObject()) { |
| 2256 if (!instr->value()->type().IsHeapObject()) { | 2316 if (!instr->value()->type().IsHeapObject()) { |
| 2257 return AssignEnvironment(result); | 2317 return AssignEnvironment(result); |
| 2258 } | 2318 } |
| 2259 } | 2319 } |
| 2260 return result; | 2320 return result; |
| 2261 } | 2321 } |
| 2262 | 2322 |
| 2263 | 2323 |
| 2264 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 2324 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 2325 LOperand* context = UseFixed(instr->context(), cp); |
| 2265 LOperand* obj = UseFixed(instr->object(), a1); | 2326 LOperand* obj = UseFixed(instr->object(), a1); |
| 2266 LOperand* val = UseFixed(instr->value(), a0); | 2327 LOperand* val = UseFixed(instr->value(), a0); |
| 2267 | 2328 |
| 2268 LInstruction* result = new(zone()) LStoreNamedGeneric(obj, val); | 2329 LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val); |
| 2269 return MarkAsCall(result, instr); | 2330 return MarkAsCall(result, instr); |
| 2270 } | 2331 } |
| 2271 | 2332 |
| 2272 | 2333 |
| 2273 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { | 2334 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { |
| 2335 LOperand* context = UseFixed(instr->context(), cp); |
| 2274 LOperand* left = UseRegisterAtStart(instr->left()); | 2336 LOperand* left = UseRegisterAtStart(instr->left()); |
| 2275 LOperand* right = UseRegisterAtStart(instr->right()); | 2337 LOperand* right = UseRegisterAtStart(instr->right()); |
| 2276 return MarkAsCall(DefineFixed(new(zone()) LStringAdd(left, right), v0), | 2338 return MarkAsCall( |
| 2277 instr); | 2339 DefineFixed(new(zone()) LStringAdd(context, left, right), v0), |
| 2340 instr); |
| 2278 } | 2341 } |
| 2279 | 2342 |
| 2280 | 2343 |
| 2281 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 2344 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 2282 LOperand* string = UseTempRegister(instr->string()); | 2345 LOperand* string = UseTempRegister(instr->string()); |
| 2283 LOperand* index = UseTempRegister(instr->index()); | 2346 LOperand* index = UseTempRegister(instr->index()); |
| 2284 LStringCharCodeAt* result = new(zone()) LStringCharCodeAt(string, index); | 2347 LOperand* context = UseAny(instr->context()); |
| 2348 LStringCharCodeAt* result = |
| 2349 new(zone()) LStringCharCodeAt(context, string, index); |
| 2285 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 2350 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 2286 } | 2351 } |
| 2287 | 2352 |
| 2288 | 2353 |
| 2289 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { | 2354 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { |
| 2290 LOperand* char_code = UseRegister(instr->value()); | 2355 LOperand* char_code = UseRegister(instr->value()); |
| 2291 LStringCharFromCode* result = new(zone()) LStringCharFromCode(char_code); | 2356 LOperand* context = UseAny(instr->context()); |
| 2357 LStringCharFromCode* result = |
| 2358 new(zone()) LStringCharFromCode(context, char_code); |
| 2292 return AssignPointerMap(DefineAsRegister(result)); | 2359 return AssignPointerMap(DefineAsRegister(result)); |
| 2293 } | 2360 } |
| 2294 | 2361 |
| 2295 | 2362 |
| 2296 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { | 2363 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { |
| 2297 info()->MarkAsDeferredCalling(); | 2364 info()->MarkAsDeferredCalling(); |
| 2365 LOperand* context = UseAny(instr->context()); |
| 2298 LOperand* size = instr->size()->IsConstant() | 2366 LOperand* size = instr->size()->IsConstant() |
| 2299 ? UseConstant(instr->size()) | 2367 ? UseConstant(instr->size()) |
| 2300 : UseTempRegister(instr->size()); | 2368 : UseTempRegister(instr->size()); |
| 2301 LOperand* temp1 = TempRegister(); | 2369 LOperand* temp1 = TempRegister(); |
| 2302 LOperand* temp2 = TempRegister(); | 2370 LOperand* temp2 = TempRegister(); |
| 2303 LAllocate* result = new(zone()) LAllocate(size, temp1, temp2); | 2371 LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2); |
| 2304 return AssignPointerMap(DefineAsRegister(result)); | 2372 return AssignPointerMap(DefineAsRegister(result)); |
| 2305 } | 2373 } |
| 2306 | 2374 |
| 2307 | 2375 |
| 2308 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 2376 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 2309 return MarkAsCall(DefineFixed(new(zone()) LRegExpLiteral, v0), instr); | 2377 LOperand* context = UseFixed(instr->context(), cp); |
| 2378 return MarkAsCall( |
| 2379 DefineFixed(new(zone()) LRegExpLiteral(context), v0), instr); |
| 2310 } | 2380 } |
| 2311 | 2381 |
| 2312 | 2382 |
| 2313 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 2383 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 2314 return MarkAsCall(DefineFixed(new(zone()) LFunctionLiteral, v0), instr); | 2384 LOperand* context = UseFixed(instr->context(), cp); |
| 2385 return MarkAsCall( |
| 2386 DefineFixed(new(zone()) LFunctionLiteral(context), v0), instr); |
| 2315 } | 2387 } |
| 2316 | 2388 |
| 2317 | 2389 |
| 2318 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 2390 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 2319 ASSERT(argument_count_ == 0); | 2391 ASSERT(argument_count_ == 0); |
| 2320 allocator_->MarkAsOsrEntry(); | 2392 allocator_->MarkAsOsrEntry(); |
| 2321 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 2393 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 2322 return AssignEnvironment(new(zone()) LOsrEntry); | 2394 return AssignEnvironment(new(zone()) LOsrEntry); |
| 2323 } | 2395 } |
| 2324 | 2396 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2351 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { | 2423 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { |
| 2352 Abort(kTooManySpillSlotsNeededForOSR); | 2424 Abort(kTooManySpillSlotsNeededForOSR); |
| 2353 spill_index = 0; | 2425 spill_index = 0; |
| 2354 } | 2426 } |
| 2355 } | 2427 } |
| 2356 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); | 2428 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); |
| 2357 } | 2429 } |
| 2358 | 2430 |
| 2359 | 2431 |
| 2360 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 2432 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| 2361 argument_count_ -= instr->argument_count(); | 2433 LOperand* context = UseFixed(instr->context(), cp); |
| 2362 return MarkAsCall(DefineFixed(new(zone()) LCallStub, v0), instr); | 2434 return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), v0), instr); |
| 2363 } | 2435 } |
| 2364 | 2436 |
| 2365 | 2437 |
| 2366 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 2438 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 2367 // There are no real uses of the arguments object. | 2439 // There are no real uses of the arguments object. |
| 2368 // arguments.length and element access are supported directly on | 2440 // arguments.length and element access are supported directly on |
| 2369 // stack arguments, and any real arguments object use causes a bailout. | 2441 // stack arguments, and any real arguments object use causes a bailout. |
| 2370 // So this value is never used. | 2442 // So this value is never used. |
| 2371 return NULL; | 2443 return NULL; |
| 2372 } | 2444 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2397 | 2469 |
| 2398 | 2470 |
| 2399 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { | 2471 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { |
| 2400 LOperand* object = UseFixed(instr->value(), a0); | 2472 LOperand* object = UseFixed(instr->value(), a0); |
| 2401 LToFastProperties* result = new(zone()) LToFastProperties(object); | 2473 LToFastProperties* result = new(zone()) LToFastProperties(object); |
| 2402 return MarkAsCall(DefineFixed(result, v0), instr); | 2474 return MarkAsCall(DefineFixed(result, v0), instr); |
| 2403 } | 2475 } |
| 2404 | 2476 |
| 2405 | 2477 |
| 2406 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 2478 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 2407 LTypeof* result = new(zone()) LTypeof(UseFixed(instr->value(), a0)); | 2479 LOperand* context = UseFixed(instr->context(), cp); |
| 2480 LTypeof* result = new(zone()) LTypeof(context, UseFixed(instr->value(), a0)); |
| 2408 return MarkAsCall(DefineFixed(result, v0), instr); | 2481 return MarkAsCall(DefineFixed(result, v0), instr); |
| 2409 } | 2482 } |
| 2410 | 2483 |
| 2411 | 2484 |
| 2412 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { | 2485 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { |
| 2413 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); | 2486 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); |
| 2414 } | 2487 } |
| 2415 | 2488 |
| 2416 | 2489 |
| 2417 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( | 2490 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2436 pending_deoptimization_ast_id_ = BailoutId::None(); | 2509 pending_deoptimization_ast_id_ = BailoutId::None(); |
| 2437 return result; | 2510 return result; |
| 2438 } | 2511 } |
| 2439 | 2512 |
| 2440 return NULL; | 2513 return NULL; |
| 2441 } | 2514 } |
| 2442 | 2515 |
| 2443 | 2516 |
| 2444 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2517 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2445 if (instr->is_function_entry()) { | 2518 if (instr->is_function_entry()) { |
| 2446 return MarkAsCall(new(zone()) LStackCheck, instr); | 2519 LOperand* context = UseFixed(instr->context(), cp); |
| 2520 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
| 2447 } else { | 2521 } else { |
| 2448 ASSERT(instr->is_backwards_branch()); | 2522 ASSERT(instr->is_backwards_branch()); |
| 2449 return AssignEnvironment(AssignPointerMap(new(zone()) LStackCheck)); | 2523 LOperand* context = UseAny(instr->context()); |
| 2524 return AssignEnvironment( |
| 2525 AssignPointerMap(new(zone()) LStackCheck(context))); |
| 2450 } | 2526 } |
| 2451 } | 2527 } |
| 2452 | 2528 |
| 2453 | 2529 |
| 2454 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 2530 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
| 2455 HEnvironment* outer = current_block_->last_environment(); | 2531 HEnvironment* outer = current_block_->last_environment(); |
| 2456 HConstant* undefined = graph()->GetConstantUndefined(); | 2532 HConstant* undefined = graph()->GetConstantUndefined(); |
| 2457 HEnvironment* inner = outer->CopyForInlining(instr->closure(), | 2533 HEnvironment* inner = outer->CopyForInlining(instr->closure(), |
| 2458 instr->arguments_count(), | 2534 instr->arguments_count(), |
| 2459 instr->function(), | 2535 instr->function(), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2472 | 2548 |
| 2473 | 2549 |
| 2474 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2550 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 2475 LInstruction* pop = NULL; | 2551 LInstruction* pop = NULL; |
| 2476 | 2552 |
| 2477 HEnvironment* env = current_block_->last_environment(); | 2553 HEnvironment* env = current_block_->last_environment(); |
| 2478 | 2554 |
| 2479 if (env->entry()->arguments_pushed()) { | 2555 if (env->entry()->arguments_pushed()) { |
| 2480 int argument_count = env->arguments_environment()->parameter_count(); | 2556 int argument_count = env->arguments_environment()->parameter_count(); |
| 2481 pop = new(zone()) LDrop(argument_count); | 2557 pop = new(zone()) LDrop(argument_count); |
| 2482 argument_count_ -= argument_count; | 2558 ASSERT(instr->argument_delta() == -argument_count); |
| 2483 } | 2559 } |
| 2484 | 2560 |
| 2485 HEnvironment* outer = current_block_->last_environment()-> | 2561 HEnvironment* outer = current_block_->last_environment()-> |
| 2486 DiscardInlined(false); | 2562 DiscardInlined(false); |
| 2487 current_block_->UpdateEnvironment(outer); | 2563 current_block_->UpdateEnvironment(outer); |
| 2488 | 2564 |
| 2489 return pop; | 2565 return pop; |
| 2490 } | 2566 } |
| 2491 | 2567 |
| 2492 | 2568 |
| 2493 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { | 2569 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { |
| 2570 LOperand* context = UseFixed(instr->context(), cp); |
| 2494 LOperand* object = UseFixed(instr->enumerable(), a0); | 2571 LOperand* object = UseFixed(instr->enumerable(), a0); |
| 2495 LForInPrepareMap* result = new(zone()) LForInPrepareMap(object); | 2572 LForInPrepareMap* result = new(zone()) LForInPrepareMap(context, object); |
| 2496 return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY); | 2573 return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 2497 } | 2574 } |
| 2498 | 2575 |
| 2499 | 2576 |
| 2500 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) { | 2577 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) { |
| 2501 LOperand* map = UseRegister(instr->map()); | 2578 LOperand* map = UseRegister(instr->map()); |
| 2502 return AssignEnvironment(DefineAsRegister(new(zone()) LForInCacheArray(map))); | 2579 return AssignEnvironment(DefineAsRegister(new(zone()) LForInCacheArray(map))); |
| 2503 } | 2580 } |
| 2504 | 2581 |
| 2505 | 2582 |
| 2506 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) { | 2583 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) { |
| 2507 LOperand* value = UseRegisterAtStart(instr->value()); | 2584 LOperand* value = UseRegisterAtStart(instr->value()); |
| 2508 LOperand* map = UseRegisterAtStart(instr->map()); | 2585 LOperand* map = UseRegisterAtStart(instr->map()); |
| 2509 return AssignEnvironment(new(zone()) LCheckMapValue(value, map)); | 2586 return AssignEnvironment(new(zone()) LCheckMapValue(value, map)); |
| 2510 } | 2587 } |
| 2511 | 2588 |
| 2512 | 2589 |
| 2513 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2590 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2514 LOperand* object = UseRegister(instr->object()); | 2591 LOperand* object = UseRegister(instr->object()); |
| 2515 LOperand* index = UseRegister(instr->index()); | 2592 LOperand* index = UseRegister(instr->index()); |
| 2516 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2593 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
| 2517 } | 2594 } |
| 2518 | 2595 |
| 2519 | 2596 |
| 2520 } } // namespace v8::internal | 2597 } } // namespace v8::internal |
| OLD | NEW |