| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 return CallICBase::LoadFunction(state, | 786 return CallICBase::LoadFunction(state, |
| 787 Code::kNoExtraICState, | 787 Code::kNoExtraICState, |
| 788 object, | 788 object, |
| 789 Handle<String>::cast(key)); | 789 Handle<String>::cast(key)); |
| 790 } | 790 } |
| 791 | 791 |
| 792 if (object->IsUndefined() || object->IsNull()) { | 792 if (object->IsUndefined() || object->IsNull()) { |
| 793 return TypeError("non_object_property_call", object, key); | 793 return TypeError("non_object_property_call", object, key); |
| 794 } | 794 } |
| 795 | 795 |
| 796 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { | 796 if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) { |
| 797 int argc = target()->arguments_count(); | 797 int argc = target()->arguments_count(); |
| 798 InLoopFlag in_loop = target()->ic_in_loop(); | 798 InLoopFlag in_loop = target()->ic_in_loop(); |
| 799 Heap* heap = Handle<HeapObject>::cast(object)->GetHeap(); | 799 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( |
| 800 Map* map = heap->non_strict_arguments_elements_map(); | 800 argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState); |
| 801 if (object->IsJSObject() && | 801 Object* code; |
| 802 Handle<JSObject>::cast(object)->elements()->map() == map) { | 802 if (maybe_code->ToObject(&code)) { |
| 803 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( | 803 set_target(Code::cast(code)); |
| 804 argc, in_loop, Code::KEYED_CALL_IC); | |
| 805 Object* code; | |
| 806 if (maybe_code->ToObject(&code)) { | |
| 807 set_target(Code::cast(code)); | |
| 808 #ifdef DEBUG | 804 #ifdef DEBUG |
| 809 TraceIC( | 805 TraceIC( |
| 810 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); | 806 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); |
| 811 #endif | 807 #endif |
| 812 } | |
| 813 } else if (FLAG_use_ic && state != MEGAMORPHIC && | |
| 814 !object->IsAccessCheckNeeded()) { | |
| 815 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( | |
| 816 argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState); | |
| 817 Object* code; | |
| 818 if (maybe_code->ToObject(&code)) { | |
| 819 set_target(Code::cast(code)); | |
| 820 #ifdef DEBUG | |
| 821 TraceIC( | |
| 822 "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); | |
| 823 #endif | |
| 824 } | |
| 825 } | 808 } |
| 826 } | 809 } |
| 827 | 810 |
| 828 HandleScope scope(isolate()); | 811 HandleScope scope(isolate()); |
| 829 Handle<Object> result = GetProperty(object, key); | 812 Handle<Object> result = GetProperty(object, key); |
| 830 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 813 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 831 | 814 |
| 832 // Make receiver an object if the callee requires it. Strict mode or builtin | 815 // Make receiver an object if the callee requires it. Strict mode or builtin |
| 833 // functions do not wrap the receiver, non-strict functions and objects | 816 // functions do not wrap the receiver, non-strict functions and objects |
| 834 // called as functions do. | 817 // called as functions do. |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 | 1230 |
| 1248 if (use_ic) { | 1231 if (use_ic) { |
| 1249 Code* stub = generic_stub(); | 1232 Code* stub = generic_stub(); |
| 1250 if (!force_generic_stub) { | 1233 if (!force_generic_stub) { |
| 1251 if (object->IsString() && key->IsNumber()) { | 1234 if (object->IsString() && key->IsNumber()) { |
| 1252 if (state == UNINITIALIZED) { | 1235 if (state == UNINITIALIZED) { |
| 1253 stub = string_stub(); | 1236 stub = string_stub(); |
| 1254 } | 1237 } |
| 1255 } else if (object->IsJSObject()) { | 1238 } else if (object->IsJSObject()) { |
| 1256 JSObject* receiver = JSObject::cast(*object); | 1239 JSObject* receiver = JSObject::cast(*object); |
| 1257 Heap* heap = Handle<JSObject>::cast(object)->GetHeap(); | 1240 if (receiver->HasIndexedInterceptor()) { |
| 1258 Map* elements_map = Handle<JSObject>::cast(object)->elements()->map(); | |
| 1259 if (elements_map == heap->non_strict_arguments_elements_map()) { | |
| 1260 stub = non_strict_arguments_stub(); | |
| 1261 } else if (receiver->HasIndexedInterceptor()) { | |
| 1262 stub = indexed_interceptor_stub(); | 1241 stub = indexed_interceptor_stub(); |
| 1263 } else if (key->IsSmi() && (target() != non_strict_arguments_stub())) { | 1242 } else if (key->IsSmi()) { |
| 1264 MaybeObject* maybe_stub = ComputeStub(receiver, | 1243 MaybeObject* maybe_stub = ComputeStub(receiver, |
| 1265 false, | 1244 false, |
| 1266 kNonStrictMode, | 1245 kNonStrictMode, |
| 1267 stub); | 1246 stub); |
| 1268 stub = maybe_stub->IsFailure() ? | 1247 stub = maybe_stub->IsFailure() ? |
| 1269 NULL : Code::cast(maybe_stub->ToObjectUnchecked()); | 1248 NULL : Code::cast(maybe_stub->ToObjectUnchecked()); |
| 1270 } | 1249 } |
| 1271 } | 1250 } |
| 1272 } | 1251 } |
| 1273 if (stub != NULL) set_target(stub); | 1252 if (stub != NULL) set_target(stub); |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1823 | 1802 |
| 1824 // Do not use ICs for objects that require access checks (including | 1803 // Do not use ICs for objects that require access checks (including |
| 1825 // the global object). | 1804 // the global object). |
| 1826 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); | 1805 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); |
| 1827 ASSERT(!(use_ic && object->IsJSGlobalProxy())); | 1806 ASSERT(!(use_ic && object->IsJSGlobalProxy())); |
| 1828 | 1807 |
| 1829 if (use_ic) { | 1808 if (use_ic) { |
| 1830 Code* stub = (strict_mode == kStrictMode) | 1809 Code* stub = (strict_mode == kStrictMode) |
| 1831 ? generic_stub_strict() | 1810 ? generic_stub_strict() |
| 1832 : generic_stub(); | 1811 : generic_stub(); |
| 1833 if (object->IsJSObject()) { | 1812 if (!force_generic) { |
| 1834 JSObject* receiver = JSObject::cast(*object); | 1813 if (object->IsJSObject() && key->IsSmi()) { |
| 1835 Heap* heap = Handle<JSObject>::cast(object)->GetHeap(); | 1814 JSObject* receiver = JSObject::cast(*object); |
| 1836 Map* elements_map = Handle<JSObject>::cast(object)->elements()->map(); | 1815 MaybeObject* maybe_stub = ComputeStub(receiver, |
| 1837 if (elements_map == heap->non_strict_arguments_elements_map()) { | 1816 true, |
| 1838 stub = non_strict_arguments_stub(); | 1817 strict_mode, |
| 1839 } else if (!force_generic) { | 1818 stub); |
| 1840 if (key->IsSmi() && (target() != non_strict_arguments_stub())) { | 1819 stub = maybe_stub->IsFailure() ? |
| 1841 MaybeObject* maybe_stub = ComputeStub(receiver, | 1820 NULL : Code::cast(maybe_stub->ToObjectUnchecked()); |
| 1842 true, | |
| 1843 strict_mode, | |
| 1844 stub); | |
| 1845 stub = maybe_stub->IsFailure() ? | |
| 1846 NULL : Code::cast(maybe_stub->ToObjectUnchecked()); | |
| 1847 } | |
| 1848 } | 1821 } |
| 1849 } | 1822 } |
| 1850 if (stub != NULL) set_target(stub); | 1823 if (stub != NULL) set_target(stub); |
| 1851 } | 1824 } |
| 1852 | 1825 |
| 1853 #ifdef DEBUG | 1826 #ifdef DEBUG |
| 1854 TraceIC("KeyedStoreIC", key, state, target()); | 1827 TraceIC("KeyedStoreIC", key, state, target()); |
| 1855 #endif | 1828 #endif |
| 1856 | 1829 |
| 1857 // Set the property. | 1830 // Set the property. |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2543 #undef ADDR | 2516 #undef ADDR |
| 2544 }; | 2517 }; |
| 2545 | 2518 |
| 2546 | 2519 |
| 2547 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2520 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2548 return IC_utilities[id]; | 2521 return IC_utilities[id]; |
| 2549 } | 2522 } |
| 2550 | 2523 |
| 2551 | 2524 |
| 2552 } } // namespace v8::internal | 2525 } } // namespace v8::internal |
| OLD | NEW |