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