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 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 return false; | 984 return false; |
985 } | 985 } |
986 | 986 |
987 MapHandleList receiver_maps; | 987 MapHandleList receiver_maps; |
988 CodeHandleList handlers; | 988 CodeHandleList handlers; |
989 | 989 |
990 int number_of_valid_maps; | 990 int number_of_valid_maps; |
991 int handler_to_overwrite = -1; | 991 int handler_to_overwrite = -1; |
992 Handle<Map> new_receiver_map(receiver->map()); | 992 Handle<Map> new_receiver_map(receiver->map()); |
993 { | 993 { |
994 AssertNoAllocation no_gc; | 994 DisallowHeapAllocation no_gc; |
995 target()->FindAllMaps(&receiver_maps); | 995 target()->FindAllMaps(&receiver_maps); |
996 int number_of_maps = receiver_maps.length(); | 996 int number_of_maps = receiver_maps.length(); |
997 number_of_valid_maps = number_of_maps; | 997 number_of_valid_maps = number_of_maps; |
998 | 998 |
999 for (int i = 0; i < number_of_maps; i++) { | 999 for (int i = 0; i < number_of_maps; i++) { |
1000 Handle<Map> map = receiver_maps.at(i); | 1000 Handle<Map> map = receiver_maps.at(i); |
1001 // Filter out deprecated maps to ensure its instances get migrated. | 1001 // Filter out deprecated maps to ensure its instances get migrated. |
1002 if (map->is_deprecated()) { | 1002 if (map->is_deprecated()) { |
1003 number_of_valid_maps--; | 1003 number_of_valid_maps--; |
1004 // If the receiver map is already in the polymorphic IC, this indicates | 1004 // If the receiver map is already in the polymorphic IC, this indicates |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedMonomorphicIC( | 1052 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedMonomorphicIC( |
1053 receiver, handler, name); | 1053 receiver, handler, name); |
1054 set_target(*ic); | 1054 set_target(*ic); |
1055 } | 1055 } |
1056 | 1056 |
1057 | 1057 |
1058 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 1058 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
1059 MapHandleList receiver_maps; | 1059 MapHandleList receiver_maps; |
1060 CodeHandleList handlers; | 1060 CodeHandleList handlers; |
1061 { | 1061 { |
1062 AssertNoAllocation no_gc; | 1062 DisallowHeapAllocation no_gc; |
1063 target()->FindAllMaps(&receiver_maps); | 1063 target()->FindAllMaps(&receiver_maps); |
1064 target()->FindAllCode(&handlers, receiver_maps.length()); | 1064 target()->FindAllCode(&handlers, receiver_maps.length()); |
1065 } | 1065 } |
1066 for (int i = 0; i < receiver_maps.length(); i++) { | 1066 for (int i = 0; i < receiver_maps.length(); i++) { |
1067 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); | 1067 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); |
1068 } | 1068 } |
1069 } | 1069 } |
1070 | 1070 |
1071 | 1071 |
1072 bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) { | 1072 bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) { |
1073 AssertNoAllocation no_allocation; | 1073 DisallowHeapAllocation no_allocation; |
1074 | 1074 |
1075 Map* current_map = target()->FindFirstMap(); | 1075 Map* current_map = target()->FindFirstMap(); |
1076 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); | 1076 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); |
1077 bool more_general_transition = | 1077 bool more_general_transition = |
1078 IsMoreGeneralElementsKindTransition( | 1078 IsMoreGeneralElementsKindTransition( |
1079 current_map->elements_kind(), receiver_elements_kind); | 1079 current_map->elements_kind(), receiver_elements_kind); |
1080 Map* transitioned_map = more_general_transition | 1080 Map* transitioned_map = more_general_transition |
1081 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) | 1081 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) |
1082 : NULL; | 1082 : NULL; |
1083 | 1083 |
(...skipping 13 matching lines...) Expand all Loading... |
1097 case PREMONOMORPHIC: | 1097 case PREMONOMORPHIC: |
1098 case MONOMORPHIC_PROTOTYPE_FAILURE: | 1098 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1099 UpdateMonomorphicIC(receiver, code, name); | 1099 UpdateMonomorphicIC(receiver, code, name); |
1100 break; | 1100 break; |
1101 case MONOMORPHIC: | 1101 case MONOMORPHIC: |
1102 // Only move to megamorphic if the target changes. | 1102 // Only move to megamorphic if the target changes. |
1103 if (target() != *code) { | 1103 if (target() != *code) { |
1104 if (target()->is_load_stub()) { | 1104 if (target()->is_load_stub()) { |
1105 bool is_same_handler = false; | 1105 bool is_same_handler = false; |
1106 { | 1106 { |
1107 AssertNoAllocation no_allocation; | 1107 DisallowHeapAllocation no_allocation; |
1108 Code* old_handler = target()->FindFirstCode(); | 1108 Code* old_handler = target()->FindFirstCode(); |
1109 is_same_handler = old_handler == *code; | 1109 is_same_handler = old_handler == *code; |
1110 } | 1110 } |
1111 if (is_same_handler | 1111 if (is_same_handler |
1112 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { | 1112 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { |
1113 UpdateMonomorphicIC(receiver, code, name); | 1113 UpdateMonomorphicIC(receiver, code, name); |
1114 break; | 1114 break; |
1115 } | 1115 } |
1116 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { | 1116 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { |
1117 break; | 1117 break; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 ASSERT(stub->is_inline_cache_stub()); | 1162 ASSERT(stub->is_inline_cache_stub()); |
1163 switch (stub->ic_state()) { | 1163 switch (stub->ic_state()) { |
1164 case MONOMORPHIC: { | 1164 case MONOMORPHIC: { |
1165 Map* map = stub->FindFirstMap(); | 1165 Map* map = stub->FindFirstMap(); |
1166 if (map != NULL) { | 1166 if (map != NULL) { |
1167 result->Add(Handle<Map>(map)); | 1167 result->Add(Handle<Map>(map)); |
1168 } | 1168 } |
1169 break; | 1169 break; |
1170 } | 1170 } |
1171 case POLYMORPHIC: { | 1171 case POLYMORPHIC: { |
1172 AssertNoAllocation no_allocation; | 1172 DisallowHeapAllocation no_allocation; |
1173 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 1173 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
1174 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { | 1174 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { |
1175 RelocInfo* info = it.rinfo(); | 1175 RelocInfo* info = it.rinfo(); |
1176 Handle<Object> object(info->target_object(), stub->GetIsolate()); | 1176 Handle<Object> object(info->target_object(), stub->GetIsolate()); |
1177 if (object->IsString()) break; | 1177 if (object->IsString()) break; |
1178 ASSERT(object->IsMap()); | 1178 ASSERT(object->IsMap()); |
1179 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); | 1179 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); |
1180 } | 1180 } |
1181 break; | 1181 break; |
1182 } | 1182 } |
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2217 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2217 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
2218 return ic.Store(state, | 2218 return ic.Store(state, |
2219 Code::GetStrictMode(extra_ic_state), | 2219 Code::GetStrictMode(extra_ic_state), |
2220 args.at<Object>(0), | 2220 args.at<Object>(0), |
2221 args.at<String>(1), | 2221 args.at<String>(1), |
2222 args.at<Object>(2)); | 2222 args.at<Object>(2)); |
2223 } | 2223 } |
2224 | 2224 |
2225 | 2225 |
2226 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { | 2226 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { |
2227 NoHandleAllocation nha(isolate); | 2227 RequireNewHandleScope rnhs(isolate); |
2228 | 2228 |
2229 ASSERT(args.length() == 2); | 2229 ASSERT(args.length() == 2); |
2230 JSArray* receiver = JSArray::cast(args[0]); | 2230 JSArray* receiver = JSArray::cast(args[0]); |
2231 Object* len = args[1]; | 2231 Object* len = args[1]; |
2232 | 2232 |
2233 // The generated code should filter out non-Smis before we get here. | 2233 // The generated code should filter out non-Smis before we get here. |
2234 ASSERT(len->IsSmi()); | 2234 ASSERT(len->IsSmi()); |
2235 | 2235 |
2236 #ifdef DEBUG | 2236 #ifdef DEBUG |
2237 // The length property has to be a writable callback property. | 2237 // The length property has to be a writable callback property. |
2238 LookupResult debug_lookup(isolate); | 2238 LookupResult debug_lookup(isolate); |
2239 receiver->LocalLookup(isolate->heap()->length_string(), &debug_lookup); | 2239 receiver->LocalLookup(isolate->heap()->length_string(), &debug_lookup); |
2240 ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly()); | 2240 ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly()); |
2241 #endif | 2241 #endif |
2242 | 2242 |
2243 Object* result; | 2243 Object* result; |
2244 MaybeObject* maybe_result = receiver->SetElementsLength(len); | 2244 MaybeObject* maybe_result = receiver->SetElementsLength(len); |
2245 if (!maybe_result->To(&result)) return maybe_result; | 2245 if (!maybe_result->To(&result)) return maybe_result; |
2246 | 2246 |
2247 return len; | 2247 return len; |
2248 } | 2248 } |
2249 | 2249 |
2250 | 2250 |
2251 // Extend storage is called in a store inline cache when | 2251 // Extend storage is called in a store inline cache when |
2252 // it is necessary to extend the properties array of a | 2252 // it is necessary to extend the properties array of a |
2253 // JSObject. | 2253 // JSObject. |
2254 RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { | 2254 RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { |
2255 NoHandleAllocation na(isolate); | 2255 DisallowHandleAllocation no_handles; |
2256 ASSERT(args.length() == 3); | 2256 ASSERT(args.length() == 3); |
2257 | 2257 |
2258 // Convert the parameters | 2258 // Convert the parameters |
2259 JSObject* object = JSObject::cast(args[0]); | 2259 JSObject* object = JSObject::cast(args[0]); |
2260 Map* transition = Map::cast(args[1]); | 2260 Map* transition = Map::cast(args[1]); |
2261 Object* value = args[2]; | 2261 Object* value = args[2]; |
2262 | 2262 |
2263 // Check the object has run out out property space. | 2263 // Check the object has run out out property space. |
2264 ASSERT(object->HasFastProperties()); | 2264 ASSERT(object->HasFastProperties()); |
2265 ASSERT(object->map()->unused_property_fields() == 0); | 2265 ASSERT(object->map()->unused_property_fields() == 0); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2322 return ic.Store(state, | 2322 return ic.Store(state, |
2323 Code::GetStrictMode(extra_ic_state), | 2323 Code::GetStrictMode(extra_ic_state), |
2324 args.at<Object>(0), | 2324 args.at<Object>(0), |
2325 args.at<Object>(1), | 2325 args.at<Object>(1), |
2326 args.at<Object>(2), | 2326 args.at<Object>(2), |
2327 MISS); | 2327 MISS); |
2328 } | 2328 } |
2329 | 2329 |
2330 | 2330 |
2331 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { | 2331 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { |
2332 NoHandleAllocation na(isolate); | 2332 RequireNewHandleScope rnhs(isolate); |
2333 ASSERT(args.length() == 3); | 2333 ASSERT(args.length() == 3); |
2334 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); | 2334 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
2335 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2335 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
2336 Handle<Object> object = args.at<Object>(0); | 2336 Handle<Object> object = args.at<Object>(0); |
2337 Handle<Object> key = args.at<Object>(1); | 2337 Handle<Object> key = args.at<Object>(1); |
2338 Handle<Object> value = args.at<Object>(2); | 2338 Handle<Object> value = args.at<Object>(2); |
2339 StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state); | 2339 StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state); |
2340 return Runtime::SetObjectProperty(isolate, | 2340 return Runtime::SetObjectProperty(isolate, |
2341 object, | 2341 object, |
2342 key, | 2342 key, |
2343 value, | 2343 value, |
2344 NONE, | 2344 NONE, |
2345 strict_mode); | 2345 strict_mode); |
2346 } | 2346 } |
2347 | 2347 |
2348 | 2348 |
2349 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { | 2349 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { |
2350 NoHandleAllocation na(isolate); | 2350 RequireNewHandleScope rnhs(isolate); |
2351 ASSERT(args.length() == 3); | 2351 ASSERT(args.length() == 3); |
2352 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); | 2352 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
2353 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2353 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
2354 Handle<Object> object = args.at<Object>(0); | 2354 Handle<Object> object = args.at<Object>(0); |
2355 Handle<Object> key = args.at<Object>(1); | 2355 Handle<Object> key = args.at<Object>(1); |
2356 Handle<Object> value = args.at<Object>(2); | 2356 Handle<Object> value = args.at<Object>(2); |
2357 StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state); | 2357 StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state); |
2358 return Runtime::SetObjectProperty(isolate, | 2358 return Runtime::SetObjectProperty(isolate, |
2359 object, | 2359 object, |
2360 key, | 2360 key, |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2873 | 2873 |
2874 // Activate inlined smi code. | 2874 // Activate inlined smi code. |
2875 if (previous_state == UNINITIALIZED) { | 2875 if (previous_state == UNINITIALIZED) { |
2876 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); | 2876 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); |
2877 } | 2877 } |
2878 } | 2878 } |
2879 | 2879 |
2880 | 2880 |
2881 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc. | 2881 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc. |
2882 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { | 2882 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { |
2883 NoHandleAllocation na(isolate); | 2883 RequireNewHandleScope rnhs(isolate); |
2884 ASSERT(args.length() == 3); | 2884 ASSERT(args.length() == 3); |
2885 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); | 2885 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); |
2886 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); | 2886 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); |
2887 return ic.target(); | 2887 return ic.target(); |
2888 } | 2888 } |
2889 | 2889 |
2890 | 2890 |
2891 void CompareNilIC::Clear(Address address, Code* target) { | 2891 void CompareNilIC::Clear(Address address, Code* target) { |
2892 if (target->ic_state() == UNINITIALIZED) return; | 2892 if (target->ic_state() == UNINITIALIZED) return; |
2893 Code::ExtraICState state = target->extended_extra_ic_state(); | 2893 Code::ExtraICState state = target->extended_extra_ic_state(); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2992 #undef ADDR | 2992 #undef ADDR |
2993 }; | 2993 }; |
2994 | 2994 |
2995 | 2995 |
2996 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2996 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2997 return IC_utilities[id]; | 2997 return IC_utilities[id]; |
2998 } | 2998 } |
2999 | 2999 |
3000 | 3000 |
3001 } } // namespace v8::internal | 3001 } } // namespace v8::internal |
OLD | NEW |