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

Side by Side Diff: src/ic.cc

Issue 2868108: Revert r5174. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 4 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/ia32/stub-cache-ia32.cc ('k') | src/stub-cache.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 494
495 // Try to find a suitable function delegate for the object at hand. 495 // Try to find a suitable function delegate for the object at hand.
496 result = TryCallAsFunction(result); 496 result = TryCallAsFunction(result);
497 if (result->IsJSFunction()) return result; 497 if (result->IsJSFunction()) return result;
498 498
499 // Otherwise, it will fail in the lookup step. 499 // Otherwise, it will fail in the lookup step.
500 } 500 }
501 501
502 // Lookup the property in the object. 502 // Lookup the property in the object.
503 LookupResult lookup; 503 LookupResult lookup;
504 { 504 LookupForRead(*object, *name, &lookup);
505 AssertNoGC nogc; // GC could invalidate the pointers held in lookup.
506 505
507 LookupForRead(*object, *name, &lookup); 506 if (!lookup.IsProperty()) {
507 // If the object does not have the requested property, check which
508 // exception we need to throw.
509 if (IsContextual(object)) {
510 return ReferenceError("not_defined", name);
511 }
512 return TypeError("undefined_method", object, name);
513 }
508 514
509 if (!lookup.IsProperty()) { 515 // Lookup is valid: Update inline cache and stub cache.
510 // If the object does not have the requested property, check which 516 if (FLAG_use_ic) {
511 // exception we need to throw. 517 UpdateCaches(&lookup, state, object, name);
512 if (IsContextual(object)) {
513 return ReferenceError("not_defined", name);
514 }
515 return TypeError("undefined_method", object, name);
516 }
517
518 // Lookup is valid: Update inline cache and stub cache.
519 if (FLAG_use_ic) {
520 UpdateCaches(&lookup, state, object, name);
521 }
522 } 518 }
523 519
524 // Get the property. 520 // Get the property.
525 PropertyAttributes attr; 521 PropertyAttributes attr;
526 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 522 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
527 if (result->IsFailure()) return result; 523 if (result->IsFailure()) return result;
528 if (lookup.type() == INTERCEPTOR) { 524 if (lookup.type() == INTERCEPTOR) {
529 // If the object does not have the requested property, check which 525 // If the object does not have the requested property, check which
530 // exception we need to throw. 526 // exception we need to throw.
531 if (attr == ABSENT) { 527 if (attr == ABSENT) {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 } 780 }
785 } 781 }
786 782
787 // Check if the name is trivially convertible to an index and get 783 // Check if the name is trivially convertible to an index and get
788 // the element if so. 784 // the element if so.
789 uint32_t index; 785 uint32_t index;
790 if (name->AsArrayIndex(&index)) return object->GetElement(index); 786 if (name->AsArrayIndex(&index)) return object->GetElement(index);
791 787
792 // Named lookup in the object. 788 // Named lookup in the object.
793 LookupResult lookup; 789 LookupResult lookup;
794 { 790 LookupForRead(*object, *name, &lookup);
795 AssertNoGC nogc; // GC could invalidate the pointers held in lookup.
796 791
797 LookupForRead(*object, *name, &lookup); 792 // If we did not find a property, check if we need to throw an exception.
793 if (!lookup.IsProperty()) {
794 if (FLAG_strict || IsContextual(object)) {
795 return ReferenceError("not_defined", name);
796 }
797 LOG(SuspectReadEvent(*name, *object));
798 }
798 799
799 // If we did not find a property, check if we need to throw an exception. 800 bool can_be_inlined =
800 if (!lookup.IsProperty()) { 801 FLAG_use_ic &&
801 if (FLAG_strict || IsContextual(object)) { 802 state == PREMONOMORPHIC &&
802 return ReferenceError("not_defined", name); 803 lookup.IsProperty() &&
803 } 804 lookup.IsCacheable() &&
804 LOG(SuspectReadEvent(*name, *object)); 805 lookup.holder() == *object &&
805 } 806 lookup.type() == FIELD &&
807 !object->IsAccessCheckNeeded();
806 808
807 bool can_be_inlined = 809 if (can_be_inlined) {
808 FLAG_use_ic && 810 Map* map = lookup.holder()->map();
809 state == PREMONOMORPHIC && 811 // Property's index in the properties array. If negative we have
810 lookup.IsProperty() && 812 // an inobject property.
811 lookup.IsCacheable() && 813 int index = lookup.GetFieldIndex() - map->inobject_properties();
812 lookup.holder() == *object && 814 if (index < 0) {
813 lookup.type() == FIELD && 815 // Index is an offset from the end of the object.
814 !object->IsAccessCheckNeeded(); 816 int offset = map->instance_size() + (index * kPointerSize);
815 817 if (PatchInlinedLoad(address(), map, offset)) {
816 if (can_be_inlined) { 818 set_target(megamorphic_stub());
817 Map* map = lookup.holder()->map(); 819 #ifdef DEBUG
818 // Property's index in the properties array. If negative we have 820 if (FLAG_trace_ic) {
819 // an inobject property. 821 PrintF("[LoadIC : inline patch %s]\n", *name->ToCString());
820 int index = lookup.GetFieldIndex() - map->inobject_properties();
821 if (index < 0) {
822 // Index is an offset from the end of the object.
823 int offset = map->instance_size() + (index * kPointerSize);
824 if (PatchInlinedLoad(address(), map, offset)) {
825 set_target(megamorphic_stub());
826 #ifdef DEBUG
827 if (FLAG_trace_ic) {
828 PrintF("[LoadIC : inline patch %s]\n", *name->ToCString());
829 }
830 #endif
831 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
832 #ifdef DEBUG
833 } else {
834 if (FLAG_trace_ic) {
835 PrintF("[LoadIC : no inline patch %s (patching failed)]\n",
836 *name->ToCString());
837 }
838 } 822 }
823 #endif
824 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
825 #ifdef DEBUG
839 } else { 826 } else {
840 if (FLAG_trace_ic) { 827 if (FLAG_trace_ic) {
841 PrintF("[LoadIC : no inline patch %s (not inobject)]\n", 828 PrintF("[LoadIC : no inline patch %s (patching failed)]\n",
842 *name->ToCString()); 829 *name->ToCString());
843 } 830 }
844 } 831 }
845 } else { 832 } else {
846 if (FLAG_use_ic && state == PREMONOMORPHIC) { 833 if (FLAG_trace_ic) {
847 if (FLAG_trace_ic) { 834 PrintF("[LoadIC : no inline patch %s (not inobject)]\n",
848 PrintF("[LoadIC : no inline patch %s (not inlinable)]\n", 835 *name->ToCString());
849 *name->ToCString());
850 #endif
851 }
852 } 836 }
853 } 837 }
838 } else {
839 if (FLAG_use_ic && state == PREMONOMORPHIC) {
840 if (FLAG_trace_ic) {
841 PrintF("[LoadIC : no inline patch %s (not inlinable)]\n",
842 *name->ToCString());
843 #endif
844 }
845 }
846 }
854 847
855 // Update inline cache and stub cache. 848 // Update inline cache and stub cache.
856 if (FLAG_use_ic) { 849 if (FLAG_use_ic) {
857 UpdateCaches(&lookup, state, object, name); 850 UpdateCaches(&lookup, state, object, name);
858 }
859 } 851 }
860 852
861 PropertyAttributes attr; 853 PropertyAttributes attr;
862 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { 854 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
863 // Get the property. 855 // Get the property.
864 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 856 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
865 if (result->IsFailure()) return result; 857 if (result->IsFailure()) return result;
866 // If the property is not present, check if we need to throw an 858 // If the property is not present, check if we need to throw an
867 // exception. 859 // exception.
868 if (attr == ABSENT && IsContextual(object)) { 860 if (attr == ABSENT && IsContextual(object)) {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 uint32_t index = 0; 1030 uint32_t index = 0;
1039 if (name->AsArrayIndex(&index)) { 1031 if (name->AsArrayIndex(&index)) {
1040 HandleScope scope; 1032 HandleScope scope;
1041 // Rewrite to the generic keyed load stub. 1033 // Rewrite to the generic keyed load stub.
1042 if (FLAG_use_ic) set_target(generic_stub()); 1034 if (FLAG_use_ic) set_target(generic_stub());
1043 return Runtime::GetElementOrCharAt(object, index); 1035 return Runtime::GetElementOrCharAt(object, index);
1044 } 1036 }
1045 1037
1046 // Named lookup. 1038 // Named lookup.
1047 LookupResult lookup; 1039 LookupResult lookup;
1048 { 1040 LookupForRead(*object, *name, &lookup);
1049 AssertNoGC nogc; // GC could invalidate the pointers held in lookup.
1050 1041
1051 LookupForRead(*object, *name, &lookup); 1042 // If we did not find a property, check if we need to throw an exception.
1052 1043 if (!lookup.IsProperty()) {
1053 // If we did not find a property, check if we need to throw an exception. 1044 if (FLAG_strict || IsContextual(object)) {
1054 if (!lookup.IsProperty()) { 1045 return ReferenceError("not_defined", name);
1055 if (FLAG_strict || IsContextual(object)) {
1056 return ReferenceError("not_defined", name);
1057 }
1058 }
1059
1060 if (FLAG_use_ic) {
1061 UpdateCaches(&lookup, state, object, name);
1062 } 1046 }
1063 } 1047 }
1064 1048
1049 if (FLAG_use_ic) {
1050 UpdateCaches(&lookup, state, object, name);
1051 }
1052
1065 PropertyAttributes attr; 1053 PropertyAttributes attr;
1066 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { 1054 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
1067 // Get the property. 1055 // Get the property.
1068 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 1056 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
1069 if (result->IsFailure()) return result; 1057 if (result->IsFailure()) return result;
1070 // If the property is not present, check if we need to throw an 1058 // If the property is not present, check if we need to throw an
1071 // exception. 1059 // exception.
1072 if (attr == ABSENT && IsContextual(object)) { 1060 if (attr == ABSENT && IsContextual(object)) {
1073 return ReferenceError("not_defined", name); 1061 return ReferenceError("not_defined", name);
1074 } 1062 }
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 #ifdef DEBUG 1238 #ifdef DEBUG
1251 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); 1239 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
1252 #endif 1240 #endif
1253 Code* target = Builtins::builtin(Builtins::StoreIC_ArrayLength); 1241 Code* target = Builtins::builtin(Builtins::StoreIC_ArrayLength);
1254 set_target(target); 1242 set_target(target);
1255 return receiver->SetProperty(*name, *value, NONE); 1243 return receiver->SetProperty(*name, *value, NONE);
1256 } 1244 }
1257 1245
1258 // Lookup the property locally in the receiver. 1246 // Lookup the property locally in the receiver.
1259 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { 1247 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1260 AssertNoGC nogc; // GC could invalidate the pointers held in lookup.
1261
1262 LookupResult lookup; 1248 LookupResult lookup;
1263 1249
1264 if (LookupForWrite(*receiver, *name, &lookup)) { 1250 if (LookupForWrite(*receiver, *name, &lookup)) {
1265 bool can_be_inlined = 1251 bool can_be_inlined =
1266 state == UNINITIALIZED && 1252 state == UNINITIALIZED &&
1267 lookup.IsProperty() && 1253 lookup.IsProperty() &&
1268 lookup.holder() == *receiver && 1254 lookup.holder() == *receiver &&
1269 lookup.type() == FIELD && 1255 lookup.type() == FIELD &&
1270 !receiver->IsAccessCheckNeeded(); 1256 !receiver->IsAccessCheckNeeded();
1271 1257
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 1411
1426 // Check if the given name is an array index. 1412 // Check if the given name is an array index.
1427 uint32_t index; 1413 uint32_t index;
1428 if (name->AsArrayIndex(&index)) { 1414 if (name->AsArrayIndex(&index)) {
1429 HandleScope scope; 1415 HandleScope scope;
1430 Handle<Object> result = SetElement(receiver, index, value); 1416 Handle<Object> result = SetElement(receiver, index, value);
1431 if (result.is_null()) return Failure::Exception(); 1417 if (result.is_null()) return Failure::Exception();
1432 return *value; 1418 return *value;
1433 } 1419 }
1434 1420
1435 { 1421 // Lookup the property locally in the receiver.
1436 AssertNoGC nogc; // GC could invalidate the pointers held in lookup. 1422 LookupResult lookup;
1423 receiver->LocalLookup(*name, &lookup);
1437 1424
1438 // Lookup the property locally in the receiver. 1425 // Update inline cache and stub cache.
1439 LookupResult lookup; 1426 if (FLAG_use_ic) {
1440 receiver->LocalLookup(*name, &lookup); 1427 UpdateCaches(&lookup, state, receiver, name, value);
1441
1442 // Update inline cache and stub cache.
1443 if (FLAG_use_ic) {
1444 UpdateCaches(&lookup, state, receiver, name, value);
1445 }
1446 } 1428 }
1447 1429
1448 // Set the property. 1430 // Set the property.
1449 return receiver->SetProperty(*name, *value, NONE); 1431 return receiver->SetProperty(*name, *value, NONE);
1450 } 1432 }
1451 1433
1452 // Do not use ICs for objects that require access checks (including 1434 // Do not use ICs for objects that require access checks (including
1453 // the global object). 1435 // the global object).
1454 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 1436 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
1455 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 1437 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 #undef ADDR 1818 #undef ADDR
1837 }; 1819 };
1838 1820
1839 1821
1840 Address IC::AddressFromUtilityId(IC::UtilityId id) { 1822 Address IC::AddressFromUtilityId(IC::UtilityId id) {
1841 return IC_utilities[id]; 1823 return IC_utilities[id];
1842 } 1824 }
1843 1825
1844 1826
1845 } } // namespace v8::internal 1827 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698