| 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 SealHandleScope shs(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 SealHandleScope shs(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 SealHandleScope shs(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 SealHandleScope shs(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 |