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 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
788 return CallICBase::LoadFunction(state, | 788 return CallICBase::LoadFunction(state, |
789 Code::kNoExtraICState, | 789 Code::kNoExtraICState, |
790 object, | 790 object, |
791 Handle<String>::cast(key)); | 791 Handle<String>::cast(key)); |
792 } | 792 } |
793 | 793 |
794 if (object->IsUndefined() || object->IsNull()) { | 794 if (object->IsUndefined() || object->IsNull()) { |
795 return TypeError("non_object_property_call", object, key); | 795 return TypeError("non_object_property_call", object, key); |
796 } | 796 } |
797 | 797 |
798 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { | 798 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); |
799 ASSERT(state != GENERIC); | 799 ASSERT(!(use_ic && object->IsJSGlobalProxy())); |
800 | |
801 if (use_ic && state != MEGAMORPHIC) { | |
800 int argc = target()->arguments_count(); | 802 int argc = target()->arguments_count(); |
801 Handle<Map> map = | 803 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( |
802 isolate()->factory()->non_strict_arguments_elements_map(); | 804 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); |
803 if (object->IsJSObject() && | 805 if (object->IsJSObject()) { |
804 Handle<JSObject>::cast(object)->elements()->map() == *map) { | 806 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
805 Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments( | 807 if (receiver->elements()->map() == |
806 argc, Code::KEYED_CALL_IC); | 808 isolate()->heap()->non_strict_arguments_elements_map()) { |
807 set_target(*code); | 809 stub = isolate()->stub_cache()->ComputeCallArguments(argc); |
808 TRACE_IC("KeyedCallIC", key, state, target()); | 810 } |
809 } else if (!object->IsAccessCheckNeeded()) { | |
810 Handle<Code> code = isolate()->stub_cache()->ComputeCallMegamorphic( | |
811 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); | |
812 set_target(*code); | |
813 TRACE_IC("KeyedCallIC", key, state, target()); | |
814 } | 811 } |
812 ASSERT(!stub.is_null()); | |
813 set_target(*stub); | |
815 } | 814 } |
816 | 815 |
816 TRACE_IC("KeyedCallIC", key, state, target()); | |
Jakob Kummerow
2013/01/25 11:38:57
We should only TRACE_IC after setting a new target
Toon Verwaest
2013/01/25 11:46:54
Done.
| |
817 | |
817 Handle<Object> result = GetProperty(object, key); | 818 Handle<Object> result = GetProperty(object, key); |
818 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 819 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
819 | 820 |
820 // Make receiver an object if the callee requires it. Strict mode or builtin | 821 // Make receiver an object if the callee requires it. Strict mode or builtin |
821 // functions do not wrap the receiver, non-strict functions and objects | 822 // functions do not wrap the receiver, non-strict functions and objects |
822 // called as functions do. | 823 // called as functions do. |
823 ReceiverToObjectIfRequired(result, object); | 824 ReceiverToObjectIfRequired(result, object); |
824 if (result->IsJSFunction()) return *result; | 825 if (result->IsJSFunction()) return *result; |
825 | 826 |
826 result = TryCallAsFunction(result); | 827 result = TryCallAsFunction(result); |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1236 Handle<Object> key, | 1237 Handle<Object> key, |
1237 ICMissMode miss_mode) { | 1238 ICMissMode miss_mode) { |
1238 // Check for values that can be converted into a symbol directly or | 1239 // Check for values that can be converted into a symbol directly or |
1239 // is representable as a smi. | 1240 // is representable as a smi. |
1240 key = TryConvertKey(key, isolate()); | 1241 key = TryConvertKey(key, isolate()); |
1241 | 1242 |
1242 if (key->IsSymbol()) { | 1243 if (key->IsSymbol()) { |
1243 return LoadIC::Load(state, object, Handle<String>::cast(key)); | 1244 return LoadIC::Load(state, object, Handle<String>::cast(key)); |
1244 } | 1245 } |
1245 | 1246 |
1246 // Do not use ICs for objects that require access checks (including | |
1247 // the global object). | |
1248 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); | 1247 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); |
1248 ASSERT(!(use_ic && object->IsJSGlobalProxy())); | |
1249 | 1249 |
1250 if (use_ic) { | 1250 if (use_ic) { |
1251 Handle<Code> stub = generic_stub(); | 1251 Handle<Code> stub = generic_stub(); |
1252 if (miss_mode != MISS_FORCE_GENERIC) { | 1252 if (miss_mode != MISS_FORCE_GENERIC) { |
1253 if (object->IsString() && key->IsNumber()) { | 1253 if (object->IsString() && key->IsNumber()) { |
1254 if (state == UNINITIALIZED) { | 1254 if (state == UNINITIALIZED) { |
1255 stub = string_stub(); | 1255 stub = string_stub(); |
1256 } | 1256 } |
1257 } else if (object->IsJSObject()) { | 1257 } else if (object->IsJSObject()) { |
1258 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1258 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1259 if (receiver->elements()->map() == | 1259 if (receiver->elements()->map() == |
1260 isolate()->heap()->non_strict_arguments_elements_map()) { | 1260 isolate()->heap()->non_strict_arguments_elements_map()) { |
1261 stub = non_strict_arguments_stub(); | 1261 stub = non_strict_arguments_stub(); |
1262 } else if (receiver->HasIndexedInterceptor()) { | 1262 } else if (receiver->HasIndexedInterceptor()) { |
1263 stub = indexed_interceptor_stub(); | 1263 stub = indexed_interceptor_stub(); |
1264 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { | 1264 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { |
1265 stub = LoadElementStub(receiver); | 1265 stub = LoadElementStub(receiver); |
1266 } | 1266 } |
1267 } | 1267 } |
1268 } else { | 1268 } else { |
1269 TRACE_GENERIC_IC("KeyedLoadIC", "force generic"); | 1269 TRACE_GENERIC_IC("KeyedLoadIC", "force generic"); |
1270 } | 1270 } |
1271 if (!stub.is_null()) set_target(*stub); | 1271 ASSERT(!stub.is_null()); |
1272 set_target(*stub); | |
1272 } | 1273 } |
1273 | 1274 |
1274 TRACE_IC("KeyedLoadIC", key, state, target()); | 1275 TRACE_IC("KeyedLoadIC", key, state, target()); |
Jakob Kummerow
2013/01/25 11:38:57
Same here. (Due to the conditions, this code actua
Toon Verwaest
2013/01/25 11:46:54
Done.
| |
1275 | 1276 |
1276 // Get the property. | |
1277 return Runtime::GetObjectProperty(isolate(), object, key); | 1277 return Runtime::GetObjectProperty(isolate(), object, key); |
1278 } | 1278 } |
1279 | 1279 |
1280 | 1280 |
1281 Handle<Code> KeyedLoadIC::ComputeLoadMonomorphic(LookupResult* lookup, | 1281 Handle<Code> KeyedLoadIC::ComputeLoadMonomorphic(LookupResult* lookup, |
1282 Handle<JSObject> receiver, | 1282 Handle<JSObject> receiver, |
1283 Handle<String> name) { | 1283 Handle<String> name) { |
1284 // Bail out if we didn't find a result. | 1284 // Bail out if we didn't find a result. |
1285 if (!lookup->IsProperty()) return Handle<Code>::null(); | 1285 if (!lookup->IsProperty()) return Handle<Code>::null(); |
1286 | 1286 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1400 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); | 1400 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); |
1401 } | 1401 } |
1402 | 1402 |
1403 // Use specialized code for setting the length of arrays with fast | 1403 // Use specialized code for setting the length of arrays with fast |
1404 // properties. Slow properties might indicate redefinition of the length | 1404 // properties. Slow properties might indicate redefinition of the length |
1405 // property. | 1405 // property. |
1406 if (FLAG_use_ic && | 1406 if (FLAG_use_ic && |
1407 receiver->IsJSArray() && | 1407 receiver->IsJSArray() && |
1408 name->Equals(isolate()->heap()->length_symbol()) && | 1408 name->Equals(isolate()->heap()->length_symbol()) && |
1409 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && | 1409 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && |
1410 receiver->HasFastProperties() && | 1410 receiver->HasFastProperties()) { |
1411 kind() != Code::KEYED_STORE_IC) { | 1411 Handle<Code> stub = StoreArrayLengthStub(kind(), strict_mode).GetCode(); |
1412 Handle<Code> stub = (strict_mode == kStrictMode) | |
1413 ? isolate()->builtins()->StoreIC_ArrayLength_Strict() | |
1414 : isolate()->builtins()->StoreIC_ArrayLength(); | |
1415 set_target(*stub); | 1412 set_target(*stub); |
1416 TRACE_IC("StoreIC", name, state, *stub); | 1413 TRACE_IC("StoreIC", name, state, *stub); |
1417 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); | 1414 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); |
1418 } | 1415 } |
1419 | 1416 |
1420 if (receiver->IsJSGlobalProxy()) { | 1417 if (receiver->IsJSGlobalProxy()) { |
1421 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) { | 1418 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) { |
1422 // Generate a generic stub that goes to the runtime when we see a global | 1419 // Generate a generic stub that goes to the runtime when we see a global |
1423 // proxy as receiver. | 1420 // proxy as receiver. |
1424 Handle<Code> stub = (strict_mode == kStrictMode) | 1421 Handle<Code> stub = (strict_mode == kStrictMode) |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1721 StrictModeFlag strict_mode, | 1718 StrictModeFlag strict_mode, |
1722 Handle<Object> object, | 1719 Handle<Object> object, |
1723 Handle<Object> key, | 1720 Handle<Object> key, |
1724 Handle<Object> value, | 1721 Handle<Object> value, |
1725 ICMissMode miss_mode) { | 1722 ICMissMode miss_mode) { |
1726 // Check for values that can be converted into a symbol directly or | 1723 // Check for values that can be converted into a symbol directly or |
1727 // is representable as a smi. | 1724 // is representable as a smi. |
1728 key = TryConvertKey(key, isolate()); | 1725 key = TryConvertKey(key, isolate()); |
1729 | 1726 |
1730 if (key->IsSymbol()) { | 1727 if (key->IsSymbol()) { |
1731 Handle<String> name = Handle<String>::cast(key); | |
1732 return StoreIC::Store(state, | 1728 return StoreIC::Store(state, |
1733 strict_mode, | 1729 strict_mode, |
1734 object, | 1730 object, |
1735 name, | 1731 Handle<String>::cast(key), |
1736 value, | 1732 value, |
1737 JSReceiver::MAY_BE_STORE_FROM_KEYED); | 1733 JSReceiver::MAY_BE_STORE_FROM_KEYED); |
1738 } | 1734 } |
1739 | 1735 |
1740 // Do not use ICs for objects that require access checks (including | |
1741 // the global object), or are observed. | |
1742 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() && | 1736 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() && |
1743 !(FLAG_harmony_observation && object->IsJSObject() && | 1737 !(FLAG_harmony_observation && object->IsJSObject() && |
1744 JSObject::cast(*object)->map()->is_observed()); | 1738 JSObject::cast(*object)->map()->is_observed()); |
1745 ASSERT(!(use_ic && object->IsJSGlobalProxy())); | 1739 ASSERT(!(use_ic && object->IsJSGlobalProxy())); |
1746 | 1740 |
1747 if (use_ic) { | 1741 if (use_ic) { |
1748 Handle<Code> stub = (strict_mode == kStrictMode) | 1742 Handle<Code> stub = (strict_mode == kStrictMode) |
1749 ? generic_stub_strict() | 1743 ? generic_stub_strict() |
1750 : generic_stub(); | 1744 : generic_stub(); |
1751 if (object->IsJSObject()) { | 1745 if (miss_mode != MISS_FORCE_GENERIC) { |
1752 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1746 if (object->IsJSObject()) { |
1753 if (receiver->elements()->map() == | 1747 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1754 isolate()->heap()->non_strict_arguments_elements_map()) { | 1748 if (receiver->elements()->map() == |
1755 stub = non_strict_arguments_stub(); | 1749 isolate()->heap()->non_strict_arguments_elements_map()) { |
1756 } else if (miss_mode != MISS_FORCE_GENERIC) { | 1750 stub = non_strict_arguments_stub(); |
1757 if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { | 1751 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { |
1758 StubKind stub_kind = GetStubKind(receiver, key, value); | 1752 StubKind stub_kind = GetStubKind(receiver, key, value); |
1759 stub = StoreElementStub(receiver, stub_kind, strict_mode); | 1753 stub = StoreElementStub(receiver, stub_kind, strict_mode); |
1760 } | 1754 } |
1761 } else { | |
1762 TRACE_GENERIC_IC("KeyedStoreIC", "force generic"); | |
1763 } | 1755 } |
1756 } else { | |
1757 TRACE_GENERIC_IC("KeyedStoreIC", "force generic"); | |
1764 } | 1758 } |
1765 if (!stub.is_null()) set_target(*stub); | 1759 ASSERT(!stub.is_null()); |
1760 set_target(*stub); | |
1766 } | 1761 } |
1767 | 1762 |
1768 TRACE_IC("KeyedStoreIC", key, state, target()); | 1763 TRACE_IC("KeyedStoreIC", key, state, target()); |
Jakob Kummerow
2013/01/25 11:38:57
Again, please move this to right after set_target(
Toon Verwaest
2013/01/25 11:46:54
Done.
| |
1769 | 1764 |
1770 // Set the property. | |
1771 return Runtime::SetObjectProperty( | 1765 return Runtime::SetObjectProperty( |
1772 isolate(), object , key, value, NONE, strict_mode); | 1766 isolate(), object , key, value, NONE, strict_mode); |
1773 } | 1767 } |
1774 | 1768 |
1775 | 1769 |
1776 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, | 1770 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
1777 StrictModeFlag strict_mode, | 1771 StrictModeFlag strict_mode, |
1778 Handle<JSObject> receiver, | 1772 Handle<JSObject> receiver, |
1779 Handle<String> name) { | 1773 Handle<String> name) { |
1780 // If the property has a non-field type allowing map transitions | 1774 // If the property has a non-field type allowing map transitions |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1929 ASSERT(len->IsSmi()); | 1923 ASSERT(len->IsSmi()); |
1930 | 1924 |
1931 #ifdef DEBUG | 1925 #ifdef DEBUG |
1932 // The length property has to be a writable callback property. | 1926 // The length property has to be a writable callback property. |
1933 LookupResult debug_lookup(isolate); | 1927 LookupResult debug_lookup(isolate); |
1934 receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup); | 1928 receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup); |
1935 ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly()); | 1929 ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly()); |
1936 #endif | 1930 #endif |
1937 | 1931 |
1938 Object* result; | 1932 Object* result; |
1939 { MaybeObject* maybe_result = receiver->SetElementsLength(len); | 1933 MaybeObject* maybe_result = receiver->SetElementsLength(len); |
1940 if (!maybe_result->ToObject(&result)) return maybe_result; | 1934 if (!maybe_result->To(&result)) return maybe_result; |
1941 } | 1935 |
1942 return len; | 1936 return len; |
1943 } | 1937 } |
1944 | 1938 |
1945 | 1939 |
1946 // Extend storage is called in a store inline cache when | 1940 // Extend storage is called in a store inline cache when |
1947 // it is necessary to extend the properties array of a | 1941 // it is necessary to extend the properties array of a |
1948 // JSObject. | 1942 // JSObject. |
1949 RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { | 1943 RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { |
1950 NoHandleAllocation na; | 1944 NoHandleAllocation na; |
1951 ASSERT(args.length() == 3); | 1945 ASSERT(args.length() == 3); |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2558 #undef ADDR | 2552 #undef ADDR |
2559 }; | 2553 }; |
2560 | 2554 |
2561 | 2555 |
2562 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2556 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2563 return IC_utilities[id]; | 2557 return IC_utilities[id]; |
2564 } | 2558 } |
2565 | 2559 |
2566 | 2560 |
2567 } } // namespace v8::internal | 2561 } } // namespace v8::internal |
OLD | NEW |