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 |