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

Side by Side Diff: src/ic.cc

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