Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/ic.cc

Issue 11896091: Replace store array length builtin with codestub. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Only inform of updating IC after actually updating it. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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);
814 TRACE_IC("KeyedCallIC", key, state, target());
815 } 815 }
816 816
817 Handle<Object> result = GetProperty(object, key); 817 Handle<Object> result = GetProperty(object, key);
818 RETURN_IF_EMPTY_HANDLE(isolate(), result); 818 RETURN_IF_EMPTY_HANDLE(isolate(), result);
819 819
820 // Make receiver an object if the callee requires it. Strict mode or builtin 820 // 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 821 // functions do not wrap the receiver, non-strict functions and objects
822 // called as functions do. 822 // called as functions do.
823 ReceiverToObjectIfRequired(result, object); 823 ReceiverToObjectIfRequired(result, object);
824 if (result->IsJSFunction()) return *result; 824 if (result->IsJSFunction()) return *result;
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 Handle<Object> key, 1236 Handle<Object> key,
1237 ICMissMode miss_mode) { 1237 ICMissMode miss_mode) {
1238 // Check for values that can be converted into a symbol directly or 1238 // Check for values that can be converted into a symbol directly or
1239 // is representable as a smi. 1239 // is representable as a smi.
1240 key = TryConvertKey(key, isolate()); 1240 key = TryConvertKey(key, isolate());
1241 1241
1242 if (key->IsSymbol()) { 1242 if (key->IsSymbol()) {
1243 return LoadIC::Load(state, object, Handle<String>::cast(key)); 1243 return LoadIC::Load(state, object, Handle<String>::cast(key));
1244 } 1244 }
1245 1245
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(); 1246 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
1247 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
1249 1248
1250 if (use_ic) { 1249 if (use_ic) {
1251 Handle<Code> stub = generic_stub(); 1250 Handle<Code> stub = generic_stub();
1252 if (miss_mode != MISS_FORCE_GENERIC) { 1251 if (miss_mode != MISS_FORCE_GENERIC) {
1253 if (object->IsString() && key->IsNumber()) { 1252 if (object->IsString() && key->IsNumber()) {
1254 if (state == UNINITIALIZED) { 1253 if (state == UNINITIALIZED) {
1255 stub = string_stub(); 1254 stub = string_stub();
1256 } 1255 }
1257 } else if (object->IsJSObject()) { 1256 } else if (object->IsJSObject()) {
1258 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1257 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1259 if (receiver->elements()->map() == 1258 if (receiver->elements()->map() ==
1260 isolate()->heap()->non_strict_arguments_elements_map()) { 1259 isolate()->heap()->non_strict_arguments_elements_map()) {
1261 stub = non_strict_arguments_stub(); 1260 stub = non_strict_arguments_stub();
1262 } else if (receiver->HasIndexedInterceptor()) { 1261 } else if (receiver->HasIndexedInterceptor()) {
1263 stub = indexed_interceptor_stub(); 1262 stub = indexed_interceptor_stub();
1264 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { 1263 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1265 stub = LoadElementStub(receiver); 1264 stub = LoadElementStub(receiver);
1266 } 1265 }
1267 } 1266 }
1268 } else { 1267 } else {
1269 TRACE_GENERIC_IC("KeyedLoadIC", "force generic"); 1268 TRACE_GENERIC_IC("KeyedLoadIC", "force generic");
1270 } 1269 }
1271 if (!stub.is_null()) set_target(*stub); 1270 ASSERT(!stub.is_null());
1271 set_target(*stub);
1272 TRACE_IC("KeyedLoadIC", key, state, target());
1272 } 1273 }
1273 1274
1274 TRACE_IC("KeyedLoadIC", key, state, target());
1275 1275
1276 // Get the property.
1277 return Runtime::GetObjectProperty(isolate(), object, key); 1276 return Runtime::GetObjectProperty(isolate(), object, key);
1278 } 1277 }
1279 1278
1280 1279
1281 Handle<Code> KeyedLoadIC::ComputeLoadMonomorphic(LookupResult* lookup, 1280 Handle<Code> KeyedLoadIC::ComputeLoadMonomorphic(LookupResult* lookup,
1282 Handle<JSObject> receiver, 1281 Handle<JSObject> receiver,
1283 Handle<String> name) { 1282 Handle<String> name) {
1284 // Bail out if we didn't find a result. 1283 // Bail out if we didn't find a result.
1285 if (!lookup->IsProperty()) return Handle<Code>::null(); 1284 if (!lookup->IsProperty()) return Handle<Code>::null();
1286 1285
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); 1399 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
1401 } 1400 }
1402 1401
1403 // Use specialized code for setting the length of arrays with fast 1402 // Use specialized code for setting the length of arrays with fast
1404 // properties. Slow properties might indicate redefinition of the length 1403 // properties. Slow properties might indicate redefinition of the length
1405 // property. 1404 // property.
1406 if (FLAG_use_ic && 1405 if (FLAG_use_ic &&
1407 receiver->IsJSArray() && 1406 receiver->IsJSArray() &&
1408 name->Equals(isolate()->heap()->length_symbol()) && 1407 name->Equals(isolate()->heap()->length_symbol()) &&
1409 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && 1408 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
1410 receiver->HasFastProperties() && 1409 receiver->HasFastProperties()) {
1411 kind() != Code::KEYED_STORE_IC) { 1410 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); 1411 set_target(*stub);
1416 TRACE_IC("StoreIC", name, state, *stub); 1412 TRACE_IC("StoreIC", name, state, *stub);
1417 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); 1413 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
1418 } 1414 }
1419 1415
1420 if (receiver->IsJSGlobalProxy()) { 1416 if (receiver->IsJSGlobalProxy()) {
1421 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) { 1417 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) {
1422 // Generate a generic stub that goes to the runtime when we see a global 1418 // Generate a generic stub that goes to the runtime when we see a global
1423 // proxy as receiver. 1419 // proxy as receiver.
1424 Handle<Code> stub = (strict_mode == kStrictMode) 1420 Handle<Code> stub = (strict_mode == kStrictMode)
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 StrictModeFlag strict_mode, 1717 StrictModeFlag strict_mode,
1722 Handle<Object> object, 1718 Handle<Object> object,
1723 Handle<Object> key, 1719 Handle<Object> key,
1724 Handle<Object> value, 1720 Handle<Object> value,
1725 ICMissMode miss_mode) { 1721 ICMissMode miss_mode) {
1726 // Check for values that can be converted into a symbol directly or 1722 // Check for values that can be converted into a symbol directly or
1727 // is representable as a smi. 1723 // is representable as a smi.
1728 key = TryConvertKey(key, isolate()); 1724 key = TryConvertKey(key, isolate());
1729 1725
1730 if (key->IsSymbol()) { 1726 if (key->IsSymbol()) {
1731 Handle<String> name = Handle<String>::cast(key);
1732 return StoreIC::Store(state, 1727 return StoreIC::Store(state,
1733 strict_mode, 1728 strict_mode,
1734 object, 1729 object,
1735 name, 1730 Handle<String>::cast(key),
1736 value, 1731 value,
1737 JSReceiver::MAY_BE_STORE_FROM_KEYED); 1732 JSReceiver::MAY_BE_STORE_FROM_KEYED);
1738 } 1733 }
1739 1734
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() && 1735 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() &&
1743 !(FLAG_harmony_observation && object->IsJSObject() && 1736 !(FLAG_harmony_observation && object->IsJSObject() &&
1744 JSObject::cast(*object)->map()->is_observed()); 1737 JSObject::cast(*object)->map()->is_observed());
1745 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 1738 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
1746 1739
1747 if (use_ic) { 1740 if (use_ic) {
1748 Handle<Code> stub = (strict_mode == kStrictMode) 1741 Handle<Code> stub = (strict_mode == kStrictMode)
1749 ? generic_stub_strict() 1742 ? generic_stub_strict()
1750 : generic_stub(); 1743 : generic_stub();
1751 if (object->IsJSObject()) { 1744 if (miss_mode != MISS_FORCE_GENERIC) {
1752 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1745 if (object->IsJSObject()) {
1753 if (receiver->elements()->map() == 1746 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1754 isolate()->heap()->non_strict_arguments_elements_map()) { 1747 if (receiver->elements()->map() ==
1755 stub = non_strict_arguments_stub(); 1748 isolate()->heap()->non_strict_arguments_elements_map()) {
1756 } else if (miss_mode != MISS_FORCE_GENERIC) { 1749 stub = non_strict_arguments_stub();
1757 if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { 1750 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1758 StubKind stub_kind = GetStubKind(receiver, key, value); 1751 StubKind stub_kind = GetStubKind(receiver, key, value);
1759 stub = StoreElementStub(receiver, stub_kind, strict_mode); 1752 stub = StoreElementStub(receiver, stub_kind, strict_mode);
1760 } 1753 }
1761 } else {
1762 TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
1763 } 1754 }
1755 } else {
1756 TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
1764 } 1757 }
1765 if (!stub.is_null()) set_target(*stub); 1758 ASSERT(!stub.is_null());
1759 set_target(*stub);
1760 TRACE_IC("KeyedStoreIC", key, state, target());
1766 } 1761 }
1767 1762
1768 TRACE_IC("KeyedStoreIC", key, state, target());
1769
1770 // Set the property.
1771 return Runtime::SetObjectProperty( 1763 return Runtime::SetObjectProperty(
1772 isolate(), object , key, value, NONE, strict_mode); 1764 isolate(), object , key, value, NONE, strict_mode);
1773 } 1765 }
1774 1766
1775 1767
1776 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, 1768 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
1777 StrictModeFlag strict_mode, 1769 StrictModeFlag strict_mode,
1778 Handle<JSObject> receiver, 1770 Handle<JSObject> receiver,
1779 Handle<String> name) { 1771 Handle<String> name) {
1780 // If the property has a non-field type allowing map transitions 1772 // If the property has a non-field type allowing map transitions
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 ASSERT(len->IsSmi()); 1921 ASSERT(len->IsSmi());
1930 1922
1931 #ifdef DEBUG 1923 #ifdef DEBUG
1932 // The length property has to be a writable callback property. 1924 // The length property has to be a writable callback property.
1933 LookupResult debug_lookup(isolate); 1925 LookupResult debug_lookup(isolate);
1934 receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup); 1926 receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup);
1935 ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly()); 1927 ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly());
1936 #endif 1928 #endif
1937 1929
1938 Object* result; 1930 Object* result;
1939 { MaybeObject* maybe_result = receiver->SetElementsLength(len); 1931 MaybeObject* maybe_result = receiver->SetElementsLength(len);
1940 if (!maybe_result->ToObject(&result)) return maybe_result; 1932 if (!maybe_result->To(&result)) return maybe_result;
1941 } 1933
1942 return len; 1934 return len;
1943 } 1935 }
1944 1936
1945 1937
1946 // Extend storage is called in a store inline cache when 1938 // Extend storage is called in a store inline cache when
1947 // it is necessary to extend the properties array of a 1939 // it is necessary to extend the properties array of a
1948 // JSObject. 1940 // JSObject.
1949 RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { 1941 RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) {
1950 NoHandleAllocation na; 1942 NoHandleAllocation na;
1951 ASSERT(args.length() == 3); 1943 ASSERT(args.length() == 3);
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 #undef ADDR 2550 #undef ADDR
2559 }; 2551 };
2560 2552
2561 2553
2562 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2554 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2563 return IC_utilities[id]; 2555 return IC_utilities[id];
2564 } 2556 }
2565 2557
2566 2558
2567 } } // namespace v8::internal 2559 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698