| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 SINGLE, | 91 SINGLE, |
| 92 MULTIPLE | 92 MULTIPLE |
| 93 }; | 93 }; |
| 94 | 94 |
| 95 HValue* BuildArrayConstructor(ElementsKind kind, | 95 HValue* BuildArrayConstructor(ElementsKind kind, |
| 96 AllocationSiteOverrideMode override_mode, | 96 AllocationSiteOverrideMode override_mode, |
| 97 ArgumentClass argument_class); | 97 ArgumentClass argument_class); |
| 98 HValue* BuildInternalArrayConstructor(ElementsKind kind, | 98 HValue* BuildInternalArrayConstructor(ElementsKind kind, |
| 99 ArgumentClass argument_class); | 99 ArgumentClass argument_class); |
| 100 | 100 |
| 101 void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context, | 101 // BuildCheckAndInstallOptimizedCode emits code to install the optimized |
| 102 HValue* code_object); | 102 // function found in the optimized code map at map_index in js_function, if |
| 103 // the function at map_index matches the given native_context. Builder is |
| 104 // left in the "Then()" state after the install. |
| 105 void BuildCheckAndInstallOptimizedCode(HValue* js_function, |
| 106 HValue* native_context, |
| 107 IfBuilder* builder, |
| 108 HValue* optimized_map, |
| 109 HValue* map_index); |
| 103 void BuildInstallCode(HValue* js_function, HValue* shared_info); | 110 void BuildInstallCode(HValue* js_function, HValue* shared_info); |
| 111 |
| 112 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map, |
| 113 HValue* iterator, |
| 114 int field_offset); |
| 104 void BuildInstallFromOptimizedCodeMap(HValue* js_function, | 115 void BuildInstallFromOptimizedCodeMap(HValue* js_function, |
| 105 HValue* shared_info, | 116 HValue* shared_info, |
| 106 HValue* native_context); | 117 HValue* native_context); |
| 107 | 118 |
| 108 private: | 119 private: |
| 109 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); | 120 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); |
| 110 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, | 121 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, |
| 111 ElementsKind kind); | 122 ElementsKind kind); |
| 112 | 123 |
| 113 SmartArrayPointer<HParameter*> parameters_; | 124 SmartArrayPointer<HParameter*> parameters_; |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 casted_stub()->is_inobject()); | 601 casted_stub()->is_inobject()); |
| 591 } | 602 } |
| 592 | 603 |
| 593 | 604 |
| 594 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { | 605 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { |
| 595 return DoGenerateCode(isolate, this); | 606 return DoGenerateCode(isolate, this); |
| 596 } | 607 } |
| 597 | 608 |
| 598 | 609 |
| 599 template<> | 610 template<> |
| 600 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() { | 611 HValue* CodeStubGraphBuilder<StringLengthStub>::BuildCodeStub() { |
| 601 return BuildLoadNamedField(GetParameter(0), | 612 HValue* string = BuildLoadNamedField( |
| 602 casted_stub()->representation(), | 613 GetParameter(0), Representation::Tagged(), JSValue::kValueOffset, true); |
| 603 casted_stub()->offset(), | 614 return BuildLoadNamedField( |
| 604 casted_stub()->is_inobject()); | 615 string, Representation::Tagged(), String::kLengthOffset, true); |
| 605 } | 616 } |
| 606 | 617 |
| 607 | 618 |
| 608 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) { | 619 Handle<Code> StringLengthStub::GenerateCode(Isolate* isolate) { |
| 609 return DoGenerateCode(isolate, this); | 620 return DoGenerateCode(isolate, this); |
| 610 } | 621 } |
| 611 | 622 |
| 612 | 623 |
| 613 template <> | 624 template <> |
| 614 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() { | 625 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() { |
| 615 BuildUncheckedMonomorphicElementAccess( | 626 BuildUncheckedMonomorphicElementAccess( |
| 616 GetParameter(0), GetParameter(1), GetParameter(2), | 627 GetParameter(0), GetParameter(1), GetParameter(2), |
| 617 casted_stub()->is_js_array(), casted_stub()->elements_kind(), | 628 casted_stub()->is_js_array(), casted_stub()->elements_kind(), |
| 618 STORE, NEVER_RETURN_HOLE, casted_stub()->store_mode()); | 629 STORE, NEVER_RETURN_HOLE, casted_stub()->store_mode()); |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 | 1053 |
| 1043 | 1054 |
| 1044 template <> | 1055 template <> |
| 1045 HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() { | 1056 HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() { |
| 1046 StoreGlobalStub* stub = casted_stub(); | 1057 StoreGlobalStub* stub = casted_stub(); |
| 1047 Handle<Object> hole(isolate()->heap()->the_hole_value(), isolate()); | 1058 Handle<Object> hole(isolate()->heap()->the_hole_value(), isolate()); |
| 1048 Handle<Object> placeholer_value(Smi::FromInt(0), isolate()); | 1059 Handle<Object> placeholer_value(Smi::FromInt(0), isolate()); |
| 1049 Handle<PropertyCell> placeholder_cell = | 1060 Handle<PropertyCell> placeholder_cell = |
| 1050 isolate()->factory()->NewPropertyCell(placeholer_value); | 1061 isolate()->factory()->NewPropertyCell(placeholer_value); |
| 1051 | 1062 |
| 1052 HParameter* receiver = GetParameter(0); | |
| 1053 HParameter* value = GetParameter(2); | 1063 HParameter* value = GetParameter(2); |
| 1054 | 1064 |
| 1055 // Check that the map of the global has not changed: use a placeholder map | 1065 if (stub->check_global()) { |
| 1056 // that will be replaced later with the global object's map. | 1066 // Check that the map of the global has not changed: use a placeholder map |
| 1057 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); | 1067 // that will be replaced later with the global object's map. |
| 1058 Add<HCheckMaps>(receiver, placeholder_map, top_info()); | 1068 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); |
| 1069 HValue* global = Add<HConstant>( |
| 1070 StoreGlobalStub::global_placeholder(isolate())); |
| 1071 Add<HCheckMaps>(global, placeholder_map, top_info()); |
| 1072 } |
| 1059 | 1073 |
| 1060 HValue* cell = Add<HConstant>(placeholder_cell); | 1074 HValue* cell = Add<HConstant>(placeholder_cell); |
| 1061 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); | 1075 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); |
| 1062 HValue* cell_contents = Add<HLoadNamedField>( | 1076 HValue* cell_contents = Add<HLoadNamedField>( |
| 1063 cell, static_cast<HValue*>(NULL), access); | 1077 cell, static_cast<HValue*>(NULL), access); |
| 1064 | 1078 |
| 1065 if (stub->is_constant()) { | 1079 if (stub->is_constant()) { |
| 1066 IfBuilder builder(this); | 1080 IfBuilder builder(this); |
| 1067 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); | 1081 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); |
| 1068 builder.Then(); | 1082 builder.Then(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 | 1132 |
| 1119 return value; | 1133 return value; |
| 1120 } | 1134 } |
| 1121 | 1135 |
| 1122 | 1136 |
| 1123 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode(Isolate* isolate) { | 1137 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode(Isolate* isolate) { |
| 1124 return DoGenerateCode(isolate, this); | 1138 return DoGenerateCode(isolate, this); |
| 1125 } | 1139 } |
| 1126 | 1140 |
| 1127 | 1141 |
| 1128 void CodeStubGraphBuilderBase::BuildInstallOptimizedCode( | 1142 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode( |
| 1129 HValue* js_function, | 1143 HValue* js_function, |
| 1130 HValue* native_context, | 1144 HValue* native_context, |
| 1131 HValue* code_object) { | 1145 IfBuilder* builder, |
| 1146 HValue* optimized_map, |
| 1147 HValue* map_index) { |
| 1148 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); |
| 1149 HValue* context_slot = LoadFromOptimizedCodeMap( |
| 1150 optimized_map, map_index, SharedFunctionInfo::kContextOffset); |
| 1151 HValue* osr_ast_slot = LoadFromOptimizedCodeMap( |
| 1152 optimized_map, map_index, SharedFunctionInfo::kOsrAstIdOffset); |
| 1153 builder->If<HCompareObjectEqAndBranch>(native_context, |
| 1154 context_slot); |
| 1155 builder->AndIf<HCompareObjectEqAndBranch>(osr_ast_slot, osr_ast_id_none); |
| 1156 builder->Then(); |
| 1157 HValue* code_object = LoadFromOptimizedCodeMap(optimized_map, |
| 1158 map_index, SharedFunctionInfo::kCachedCodeOffset); |
| 1159 // and the literals |
| 1160 HValue* literals = LoadFromOptimizedCodeMap(optimized_map, |
| 1161 map_index, SharedFunctionInfo::kLiteralsOffset); |
| 1162 |
| 1132 Counters* counters = isolate()->counters(); | 1163 Counters* counters = isolate()->counters(); |
| 1133 AddIncrementCounter(counters->fast_new_closure_install_optimized()); | 1164 AddIncrementCounter(counters->fast_new_closure_install_optimized()); |
| 1134 | 1165 |
| 1135 // TODO(fschneider): Idea: store proper code pointers in the optimized code | 1166 // TODO(fschneider): Idea: store proper code pointers in the optimized code |
| 1136 // map and either unmangle them on marking or do nothing as the whole map is | 1167 // map and either unmangle them on marking or do nothing as the whole map is |
| 1137 // discarded on major GC anyway. | 1168 // discarded on major GC anyway. |
| 1138 Add<HStoreCodeEntry>(js_function, code_object); | 1169 Add<HStoreCodeEntry>(js_function, code_object); |
| 1170 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), |
| 1171 literals); |
| 1139 | 1172 |
| 1140 // Now link a function into a list of optimized functions. | 1173 // Now link a function into a list of optimized functions. |
| 1141 HValue* optimized_functions_list = Add<HLoadNamedField>( | 1174 HValue* optimized_functions_list = Add<HLoadNamedField>( |
| 1142 native_context, static_cast<HValue*>(NULL), | 1175 native_context, static_cast<HValue*>(NULL), |
| 1143 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST)); | 1176 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST)); |
| 1144 Add<HStoreNamedField>(js_function, | 1177 Add<HStoreNamedField>(js_function, |
| 1145 HObjectAccess::ForNextFunctionLinkPointer(), | 1178 HObjectAccess::ForNextFunctionLinkPointer(), |
| 1146 optimized_functions_list); | 1179 optimized_functions_list); |
| 1147 | 1180 |
| 1148 // This store is the only one that should have a write barrier. | 1181 // This store is the only one that should have a write barrier. |
| 1149 Add<HStoreNamedField>(native_context, | 1182 Add<HStoreNamedField>(native_context, |
| 1150 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST), | 1183 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST), |
| 1151 js_function); | 1184 js_function); |
| 1185 |
| 1186 // The builder continues in the "then" after this function. |
| 1152 } | 1187 } |
| 1153 | 1188 |
| 1154 | 1189 |
| 1155 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function, | 1190 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function, |
| 1156 HValue* shared_info) { | 1191 HValue* shared_info) { |
| 1157 Add<HStoreNamedField>(js_function, | 1192 Add<HStoreNamedField>(js_function, |
| 1158 HObjectAccess::ForNextFunctionLinkPointer(), | 1193 HObjectAccess::ForNextFunctionLinkPointer(), |
| 1159 graph()->GetConstantUndefined()); | 1194 graph()->GetConstantUndefined()); |
| 1160 HValue* code_object = Add<HLoadNamedField>( | 1195 HValue* code_object = Add<HLoadNamedField>( |
| 1161 shared_info, static_cast<HValue*>(NULL), HObjectAccess::ForCodeOffset()); | 1196 shared_info, static_cast<HValue*>(NULL), HObjectAccess::ForCodeOffset()); |
| 1162 Add<HStoreCodeEntry>(js_function, code_object); | 1197 Add<HStoreCodeEntry>(js_function, code_object); |
| 1163 } | 1198 } |
| 1164 | 1199 |
| 1165 | 1200 |
| 1201 HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap( |
| 1202 HValue* optimized_map, |
| 1203 HValue* iterator, |
| 1204 int field_offset) { |
| 1205 // By making sure to express these loads in the form [<hvalue> + constant] |
| 1206 // the keyed load can be hoisted. |
| 1207 ASSERT(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength); |
| 1208 HValue* field_slot = iterator; |
| 1209 if (field_offset > 0) { |
| 1210 HValue* field_offset_value = Add<HConstant>(field_offset); |
| 1211 field_slot = AddUncasted<HAdd>(iterator, field_offset_value); |
| 1212 } |
| 1213 HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot, |
| 1214 static_cast<HValue*>(NULL), FAST_ELEMENTS); |
| 1215 return field_entry; |
| 1216 } |
| 1217 |
| 1218 |
| 1166 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap( | 1219 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap( |
| 1167 HValue* js_function, | 1220 HValue* js_function, |
| 1168 HValue* shared_info, | 1221 HValue* shared_info, |
| 1169 HValue* native_context) { | 1222 HValue* native_context) { |
| 1170 Counters* counters = isolate()->counters(); | 1223 Counters* counters = isolate()->counters(); |
| 1171 IfBuilder is_optimized(this); | 1224 IfBuilder is_optimized(this); |
| 1172 HInstruction* optimized_map = Add<HLoadNamedField>( | 1225 HInstruction* optimized_map = Add<HLoadNamedField>( |
| 1173 shared_info, static_cast<HValue*>(NULL), | 1226 shared_info, static_cast<HValue*>(NULL), |
| 1174 HObjectAccess::ForOptimizedCodeMap()); | 1227 HObjectAccess::ForOptimizedCodeMap()); |
| 1175 HValue* null_constant = Add<HConstant>(0); | 1228 HValue* null_constant = Add<HConstant>(0); |
| 1176 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant); | 1229 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant); |
| 1177 is_optimized.Then(); | 1230 is_optimized.Then(); |
| 1178 { | 1231 { |
| 1179 BuildInstallCode(js_function, shared_info); | 1232 BuildInstallCode(js_function, shared_info); |
| 1180 } | 1233 } |
| 1181 is_optimized.Else(); | 1234 is_optimized.Else(); |
| 1182 { | 1235 { |
| 1183 AddIncrementCounter(counters->fast_new_closure_try_optimized()); | 1236 AddIncrementCounter(counters->fast_new_closure_try_optimized()); |
| 1184 // optimized_map points to fixed array of 3-element entries | 1237 // optimized_map points to fixed array of 3-element entries |
| 1185 // (native context, optimized code, literals). | 1238 // (native context, optimized code, literals). |
| 1186 // Map must never be empty, so check the first elements. | 1239 // Map must never be empty, so check the first elements. |
| 1187 Label install_optimized; | 1240 HValue* first_entry_index = |
| 1188 HValue* first_context_slot = Add<HLoadNamedField>( | 1241 Add<HConstant>(SharedFunctionInfo::kEntriesStart); |
| 1189 optimized_map, static_cast<HValue*>(NULL), | |
| 1190 HObjectAccess::ForFirstContextSlot()); | |
| 1191 HValue* first_osr_ast_slot = Add<HLoadNamedField>( | |
| 1192 optimized_map, static_cast<HValue*>(NULL), | |
| 1193 HObjectAccess::ForFirstOsrAstIdSlot()); | |
| 1194 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); | |
| 1195 IfBuilder already_in(this); | 1242 IfBuilder already_in(this); |
| 1196 already_in.If<HCompareObjectEqAndBranch>(native_context, | 1243 BuildCheckAndInstallOptimizedCode(js_function, native_context, &already_in, |
| 1197 first_context_slot); | 1244 optimized_map, first_entry_index); |
| 1198 already_in.AndIf<HCompareObjectEqAndBranch>(first_osr_ast_slot, | |
| 1199 osr_ast_id_none); | |
| 1200 already_in.Then(); | |
| 1201 { | |
| 1202 HValue* code_object = Add<HLoadNamedField>( | |
| 1203 optimized_map, static_cast<HValue*>(NULL), | |
| 1204 HObjectAccess::ForFirstCodeSlot()); | |
| 1205 BuildInstallOptimizedCode(js_function, native_context, code_object); | |
| 1206 } | |
| 1207 already_in.Else(); | 1245 already_in.Else(); |
| 1208 { | 1246 { |
| 1247 // Iterate through the rest of map backwards. Do not double check first |
| 1248 // entry. After the loop, if no matching optimized code was found, |
| 1249 // install unoptimized code. |
| 1250 // for(i = map.length() - SharedFunctionInfo::kEntryLength; |
| 1251 // i > SharedFunctionInfo::kEntriesStart; |
| 1252 // i -= SharedFunctionInfo::kEntryLength) { .. } |
| 1209 HValue* shared_function_entry_length = | 1253 HValue* shared_function_entry_length = |
| 1210 Add<HConstant>(SharedFunctionInfo::kEntryLength); | 1254 Add<HConstant>(SharedFunctionInfo::kEntryLength); |
| 1211 LoopBuilder loop_builder(this, | 1255 LoopBuilder loop_builder(this, |
| 1212 context(), | 1256 context(), |
| 1213 LoopBuilder::kPostDecrement, | 1257 LoopBuilder::kPostDecrement, |
| 1214 shared_function_entry_length); | 1258 shared_function_entry_length); |
| 1215 HValue* array_length = Add<HLoadNamedField>( | 1259 HValue* array_length = Add<HLoadNamedField>( |
| 1216 optimized_map, static_cast<HValue*>(NULL), | 1260 optimized_map, static_cast<HValue*>(NULL), |
| 1217 HObjectAccess::ForFixedArrayLength()); | 1261 HObjectAccess::ForFixedArrayLength()); |
| 1218 HValue* slot_iterator = loop_builder.BeginBody(array_length, | 1262 HValue* start_pos = AddUncasted<HSub>(array_length, |
| 1219 graph()->GetConstant0(), | 1263 shared_function_entry_length); |
| 1220 Token::GT); | 1264 HValue* slot_iterator = loop_builder.BeginBody(start_pos, |
| 1265 first_entry_index, |
| 1266 Token::GT); |
| 1221 { | 1267 { |
| 1222 // Iterate through the rest of map backwards. | 1268 IfBuilder done_check(this); |
| 1223 // Do not double check first entry. | 1269 BuildCheckAndInstallOptimizedCode(js_function, native_context, |
| 1224 HValue* second_entry_index = | 1270 &done_check, |
| 1225 Add<HConstant>(SharedFunctionInfo::kSecondEntryIndex); | 1271 optimized_map, |
| 1226 IfBuilder restore_check(this); | 1272 slot_iterator); |
| 1227 restore_check.If<HCompareNumericAndBranch>( | 1273 // Fall out of the loop |
| 1228 slot_iterator, second_entry_index, Token::EQ); | 1274 loop_builder.Break(); |
| 1229 restore_check.Then(); | |
| 1230 { | |
| 1231 // Store the unoptimized code | |
| 1232 BuildInstallCode(js_function, shared_info); | |
| 1233 loop_builder.Break(); | |
| 1234 } | |
| 1235 restore_check.Else(); | |
| 1236 { | |
| 1237 STATIC_ASSERT(SharedFunctionInfo::kContextOffset == 0); | |
| 1238 STATIC_ASSERT(SharedFunctionInfo::kEntryLength - | |
| 1239 SharedFunctionInfo::kOsrAstIdOffset == 1); | |
| 1240 HValue* native_context_slot = AddUncasted<HSub>( | |
| 1241 slot_iterator, shared_function_entry_length); | |
| 1242 HValue* osr_ast_id_slot = AddUncasted<HSub>( | |
| 1243 slot_iterator, graph()->GetConstant1()); | |
| 1244 HInstruction* native_context_entry = Add<HLoadKeyed>(optimized_map, | |
| 1245 native_context_slot, static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
| 1246 HInstruction* osr_ast_id_entry = Add<HLoadKeyed>(optimized_map, | |
| 1247 osr_ast_id_slot, static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
| 1248 IfBuilder done_check(this); | |
| 1249 done_check.If<HCompareObjectEqAndBranch>(native_context, | |
| 1250 native_context_entry); | |
| 1251 done_check.AndIf<HCompareObjectEqAndBranch>(osr_ast_id_entry, | |
| 1252 osr_ast_id_none); | |
| 1253 done_check.Then(); | |
| 1254 { | |
| 1255 // Hit: fetch the optimized code. | |
| 1256 HValue* code_slot = AddUncasted<HAdd>( | |
| 1257 native_context_slot, graph()->GetConstant1()); | |
| 1258 HValue* code_object = Add<HLoadKeyed>(optimized_map, | |
| 1259 code_slot, static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
| 1260 BuildInstallOptimizedCode(js_function, native_context, code_object); | |
| 1261 | |
| 1262 // Fall out of the loop | |
| 1263 loop_builder.Break(); | |
| 1264 } | |
| 1265 done_check.Else(); | |
| 1266 done_check.End(); | |
| 1267 } | |
| 1268 restore_check.End(); | |
| 1269 } | 1275 } |
| 1270 loop_builder.EndBody(); | 1276 loop_builder.EndBody(); |
| 1277 |
| 1278 // If slot_iterator equals first entry index, then we failed to find and |
| 1279 // install optimized code |
| 1280 IfBuilder no_optimized_code_check(this); |
| 1281 no_optimized_code_check.If<HCompareNumericAndBranch>( |
| 1282 slot_iterator, first_entry_index, Token::EQ); |
| 1283 no_optimized_code_check.Then(); |
| 1284 { |
| 1285 // Store the unoptimized code |
| 1286 BuildInstallCode(js_function, shared_info); |
| 1287 } |
| 1271 } | 1288 } |
| 1272 already_in.End(); | |
| 1273 } | 1289 } |
| 1274 is_optimized.End(); | |
| 1275 } | 1290 } |
| 1276 | 1291 |
| 1277 | 1292 |
| 1278 template<> | 1293 template<> |
| 1279 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() { | 1294 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() { |
| 1280 Counters* counters = isolate()->counters(); | 1295 Counters* counters = isolate()->counters(); |
| 1281 Factory* factory = isolate()->factory(); | 1296 Factory* factory = isolate()->factory(); |
| 1282 HInstruction* empty_fixed_array = | 1297 HInstruction* empty_fixed_array = |
| 1283 Add<HConstant>(factory->empty_fixed_array()); | 1298 Add<HConstant>(factory->empty_fixed_array()); |
| 1284 HValue* shared_info = GetParameter(0); | 1299 HValue* shared_info = GetParameter(0); |
| 1285 | 1300 |
| 1286 AddIncrementCounter(counters->fast_new_closure_total()); | 1301 AddIncrementCounter(counters->fast_new_closure_total()); |
| 1287 | 1302 |
| 1288 // Create a new closure from the given function info in new space | 1303 // Create a new closure from the given function info in new space |
| 1289 HValue* size = Add<HConstant>(JSFunction::kSize); | 1304 HValue* size = Add<HConstant>(JSFunction::kSize); |
| 1290 HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(), | 1305 HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(), |
| 1291 NOT_TENURED, JS_FUNCTION_TYPE); | 1306 NOT_TENURED, JS_FUNCTION_TYPE); |
| 1292 | 1307 |
| 1293 int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(), | 1308 int map_index = Context::FunctionMapIndex(casted_stub()->strict_mode(), |
| 1294 casted_stub()->is_generator()); | 1309 casted_stub()->is_generator()); |
| 1295 | 1310 |
| 1296 // Compute the function map in the current native context and set that | 1311 // Compute the function map in the current native context and set that |
| 1297 // as the map of the allocated object. | 1312 // as the map of the allocated object. |
| 1298 HInstruction* native_context = BuildGetNativeContext(); | 1313 HInstruction* native_context = BuildGetNativeContext(); |
| 1299 HInstruction* map_slot_value = Add<HLoadNamedField>( | 1314 HInstruction* map_slot_value = Add<HLoadNamedField>( |
| 1300 native_context, static_cast<HValue*>(NULL), | 1315 native_context, static_cast<HValue*>(NULL), |
| 1301 HObjectAccess::ForContextSlot(map_index)); | 1316 HObjectAccess::ForContextSlot(map_index)); |
| 1302 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); | 1317 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); |
| 1303 | 1318 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1415 return BuildRegExpConstructResult(length, index, input); | 1430 return BuildRegExpConstructResult(length, index, input); |
| 1416 } | 1431 } |
| 1417 | 1432 |
| 1418 | 1433 |
| 1419 Handle<Code> RegExpConstructResultStub::GenerateCode(Isolate* isolate) { | 1434 Handle<Code> RegExpConstructResultStub::GenerateCode(Isolate* isolate) { |
| 1420 return DoGenerateCode(isolate, this); | 1435 return DoGenerateCode(isolate, this); |
| 1421 } | 1436 } |
| 1422 | 1437 |
| 1423 | 1438 |
| 1424 } } // namespace v8::internal | 1439 } } // namespace v8::internal |
| OLD | NEW |