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: Created 7 years, 11 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);
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
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
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
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
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
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
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