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

Side by Side Diff: src/ic.cc

Issue 1094014: Merge the partial_snapshots branch back into bleeding_edge. For... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 9 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
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 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 if (!lookup.IsProperty()) { 429 if (!lookup.IsProperty()) {
430 // If the object does not have the requested property, check which 430 // If the object does not have the requested property, check which
431 // exception we need to throw. 431 // exception we need to throw.
432 if (IsContextual(object)) { 432 if (IsContextual(object)) {
433 return ReferenceError("not_defined", name); 433 return ReferenceError("not_defined", name);
434 } 434 }
435 return TypeError("undefined_method", object, name); 435 return TypeError("undefined_method", object, name);
436 } 436 }
437 437
438 // Lookup is valid: Update inline cache and stub cache. 438 // Lookup is valid: Update inline cache and stub cache.
439 if (FLAG_use_ic && lookup.IsLoaded()) { 439 if (FLAG_use_ic) {
440 UpdateCaches(&lookup, state, object, name); 440 UpdateCaches(&lookup, state, object, name);
441 } 441 }
442 442
443 // Get the property. 443 // Get the property.
444 PropertyAttributes attr; 444 PropertyAttributes attr;
445 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 445 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
446 if (result->IsFailure()) return result; 446 if (result->IsFailure()) return result;
447 if (lookup.type() == INTERCEPTOR) { 447 if (lookup.type() == INTERCEPTOR) {
448 // If the object does not have the requested property, check which 448 // If the object does not have the requested property, check which
449 // exception we need to throw. 449 // exception we need to throw.
(...skipping 27 matching lines...) Expand all
477 result = TryCallAsFunction(result); 477 result = TryCallAsFunction(result);
478 return result->IsJSFunction() ? 478 return result->IsJSFunction() ?
479 result : TypeError("property_not_function", object, name); 479 result : TypeError("property_not_function", object, name);
480 } 480 }
481 481
482 482
483 void CallIC::UpdateCaches(LookupResult* lookup, 483 void CallIC::UpdateCaches(LookupResult* lookup,
484 State state, 484 State state,
485 Handle<Object> object, 485 Handle<Object> object,
486 Handle<String> name) { 486 Handle<String> name) {
487 ASSERT(lookup->IsLoaded());
488 // Bail out if we didn't find a result. 487 // Bail out if we didn't find a result.
489 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 488 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
490 489
491 // Compute the number of arguments. 490 // Compute the number of arguments.
492 int argc = target()->arguments_count(); 491 int argc = target()->arguments_count();
493 InLoopFlag in_loop = target()->ic_in_loop(); 492 InLoopFlag in_loop = target()->ic_in_loop();
494 Object* code = NULL; 493 Object* code = NULL;
495 494
496 if (state == UNINITIALIZED) { 495 if (state == UNINITIALIZED) {
497 // This is the first time we execute this inline cache. 496 // This is the first time we execute this inline cache.
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 if (FLAG_strict || IsContextual(object)) { 639 if (FLAG_strict || IsContextual(object)) {
641 return ReferenceError("not_defined", name); 640 return ReferenceError("not_defined", name);
642 } 641 }
643 LOG(SuspectReadEvent(*name, *object)); 642 LOG(SuspectReadEvent(*name, *object));
644 } 643 }
645 644
646 bool can_be_inlined = 645 bool can_be_inlined =
647 FLAG_use_ic && 646 FLAG_use_ic &&
648 state == PREMONOMORPHIC && 647 state == PREMONOMORPHIC &&
649 lookup.IsProperty() && 648 lookup.IsProperty() &&
650 lookup.IsLoaded() &&
651 lookup.IsCacheable() && 649 lookup.IsCacheable() &&
652 lookup.holder() == *object && 650 lookup.holder() == *object &&
653 lookup.type() == FIELD && 651 lookup.type() == FIELD &&
654 !object->IsAccessCheckNeeded(); 652 !object->IsAccessCheckNeeded();
655 653
656 if (can_be_inlined) { 654 if (can_be_inlined) {
657 Map* map = lookup.holder()->map(); 655 Map* map = lookup.holder()->map();
658 // Property's index in the properties array. If negative we have 656 // Property's index in the properties array. If negative we have
659 // an inobject property. 657 // an inobject property.
660 int index = lookup.GetFieldIndex() - map->inobject_properties(); 658 int index = lookup.GetFieldIndex() - map->inobject_properties();
661 if (index < 0) { 659 if (index < 0) {
662 // Index is an offset from the end of the object. 660 // Index is an offset from the end of the object.
663 int offset = map->instance_size() + (index * kPointerSize); 661 int offset = map->instance_size() + (index * kPointerSize);
664 if (PatchInlinedLoad(address(), map, offset)) { 662 if (PatchInlinedLoad(address(), map, offset)) {
665 set_target(megamorphic_stub()); 663 set_target(megamorphic_stub());
666 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex()); 664 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
667 } 665 }
668 } 666 }
669 } 667 }
670 668
671 // Update inline cache and stub cache. 669 // Update inline cache and stub cache.
672 if (FLAG_use_ic && lookup.IsLoaded()) { 670 if (FLAG_use_ic) {
673 UpdateCaches(&lookup, state, object, name); 671 UpdateCaches(&lookup, state, object, name);
674 } 672 }
675 673
676 PropertyAttributes attr; 674 PropertyAttributes attr;
677 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { 675 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
678 // Get the property. 676 // Get the property.
679 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 677 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
680 if (result->IsFailure()) return result; 678 if (result->IsFailure()) return result;
681 // If the property is not present, check if we need to throw an 679 // If the property is not present, check if we need to throw an
682 // exception. 680 // exception.
683 if (attr == ABSENT && IsContextual(object)) { 681 if (attr == ABSENT && IsContextual(object)) {
684 return ReferenceError("not_defined", name); 682 return ReferenceError("not_defined", name);
685 } 683 }
686 return result; 684 return result;
687 } 685 }
688 686
689 // Get the property. 687 // Get the property.
690 return object->GetProperty(*object, &lookup, *name, &attr); 688 return object->GetProperty(*object, &lookup, *name, &attr);
691 } 689 }
692 690
693 691
694 void LoadIC::UpdateCaches(LookupResult* lookup, 692 void LoadIC::UpdateCaches(LookupResult* lookup,
695 State state, 693 State state,
696 Handle<Object> object, 694 Handle<Object> object,
697 Handle<String> name) { 695 Handle<String> name) {
698 ASSERT(lookup->IsLoaded());
699 // Bail out if we didn't find a result. 696 // Bail out if we didn't find a result.
700 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 697 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
701 698
702 // Loading properties from values is not common, so don't try to 699 // Loading properties from values is not common, so don't try to
703 // deal with non-JS objects here. 700 // deal with non-JS objects here.
704 if (!object->IsJSObject()) return; 701 if (!object->IsJSObject()) return;
705 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 702 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
706 703
707 // Compute the code stub for this load. 704 // Compute the code stub for this load.
708 Object* code = NULL; 705 Object* code = NULL;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 LookupResult lookup; 847 LookupResult lookup;
851 LookupForRead(*object, *name, &lookup); 848 LookupForRead(*object, *name, &lookup);
852 849
853 // If we did not find a property, check if we need to throw an exception. 850 // If we did not find a property, check if we need to throw an exception.
854 if (!lookup.IsProperty()) { 851 if (!lookup.IsProperty()) {
855 if (FLAG_strict || IsContextual(object)) { 852 if (FLAG_strict || IsContextual(object)) {
856 return ReferenceError("not_defined", name); 853 return ReferenceError("not_defined", name);
857 } 854 }
858 } 855 }
859 856
860 if (FLAG_use_ic && lookup.IsLoaded()) { 857 if (FLAG_use_ic) {
861 UpdateCaches(&lookup, state, object, name); 858 UpdateCaches(&lookup, state, object, name);
862 } 859 }
863 860
864 PropertyAttributes attr; 861 PropertyAttributes attr;
865 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { 862 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
866 // Get the property. 863 // Get the property.
867 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 864 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
868 if (result->IsFailure()) return result; 865 if (result->IsFailure()) return result;
869 // 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
870 // exception. 867 // exception.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 } 902 }
906 } 903 }
907 904
908 // Get the property. 905 // Get the property.
909 return Runtime::GetObjectProperty(object, key); 906 return Runtime::GetObjectProperty(object, key);
910 } 907 }
911 908
912 909
913 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, 910 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state,
914 Handle<Object> object, Handle<String> name) { 911 Handle<Object> object, Handle<String> name) {
915 ASSERT(lookup->IsLoaded());
916 // Bail out if we didn't find a result. 912 // Bail out if we didn't find a result.
917 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 913 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
918 914
919 if (!object->IsJSObject()) return; 915 if (!object->IsJSObject()) return;
920 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 916 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
921 917
922 // Compute the code stub for this load. 918 // Compute the code stub for this load.
923 Object* code = NULL; 919 Object* code = NULL;
924 920
925 if (state == UNINITIALIZED) { 921 if (state == UNINITIALIZED) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 982
987 983
988 static bool StoreICableLookup(LookupResult* lookup) { 984 static bool StoreICableLookup(LookupResult* lookup) {
989 // Bail out if we didn't find a result. 985 // Bail out if we didn't find a result.
990 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false; 986 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;
991 987
992 // If the property is read-only, we leave the IC in its current 988 // If the property is read-only, we leave the IC in its current
993 // state. 989 // state.
994 if (lookup->IsReadOnly()) return false; 990 if (lookup->IsReadOnly()) return false;
995 991
996 if (!lookup->IsLoaded()) return false;
997
998 return true; 992 return true;
999 } 993 }
1000 994
1001 995
1002 static bool LookupForWrite(JSObject* object, 996 static bool LookupForWrite(JSObject* object,
1003 String* name, 997 String* name,
1004 LookupResult* lookup) { 998 LookupResult* lookup) {
1005 object->LocalLookup(name, lookup); 999 object->LocalLookup(name, lookup);
1006 if (!StoreICableLookup(lookup)) { 1000 if (!StoreICableLookup(lookup)) {
1007 return false; 1001 return false;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 // Set the property. 1060 // Set the property.
1067 return receiver->SetProperty(*name, *value, NONE); 1061 return receiver->SetProperty(*name, *value, NONE);
1068 } 1062 }
1069 1063
1070 1064
1071 void StoreIC::UpdateCaches(LookupResult* lookup, 1065 void StoreIC::UpdateCaches(LookupResult* lookup,
1072 State state, 1066 State state,
1073 Handle<JSObject> receiver, 1067 Handle<JSObject> receiver,
1074 Handle<String> name, 1068 Handle<String> name,
1075 Handle<Object> value) { 1069 Handle<Object> value) {
1076 ASSERT(lookup->IsLoaded());
1077 // Skip JSGlobalProxy. 1070 // Skip JSGlobalProxy.
1078 ASSERT(!receiver->IsJSGlobalProxy()); 1071 ASSERT(!receiver->IsJSGlobalProxy());
1079 1072
1080 ASSERT(StoreICableLookup(lookup)); 1073 ASSERT(StoreICableLookup(lookup));
1081 1074
1082 // If the property has a non-field type allowing map transitions 1075 // If the property has a non-field type allowing map transitions
1083 // where there is extra room in the object, we leave the IC in its 1076 // where there is extra room in the object, we leave the IC in its
1084 // current state. 1077 // current state.
1085 PropertyType type = lookup->type(); 1078 PropertyType type = lookup->type();
1086 1079
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 Handle<Object> result = SetElement(receiver, index, value); 1167 Handle<Object> result = SetElement(receiver, index, value);
1175 if (result.is_null()) return Failure::Exception(); 1168 if (result.is_null()) return Failure::Exception();
1176 return *value; 1169 return *value;
1177 } 1170 }
1178 1171
1179 // Lookup the property locally in the receiver. 1172 // Lookup the property locally in the receiver.
1180 LookupResult lookup; 1173 LookupResult lookup;
1181 receiver->LocalLookup(*name, &lookup); 1174 receiver->LocalLookup(*name, &lookup);
1182 1175
1183 // Update inline cache and stub cache. 1176 // Update inline cache and stub cache.
1184 if (FLAG_use_ic && lookup.IsLoaded()) { 1177 if (FLAG_use_ic) {
1185 UpdateCaches(&lookup, state, receiver, name, value); 1178 UpdateCaches(&lookup, state, receiver, name, value);
1186 } 1179 }
1187 1180
1188 // Set the property. 1181 // Set the property.
1189 return receiver->SetProperty(*name, *value, NONE); 1182 return receiver->SetProperty(*name, *value, NONE);
1190 } 1183 }
1191 1184
1192 // Do not use ICs for objects that require access checks (including 1185 // Do not use ICs for objects that require access checks (including
1193 // the global object). 1186 // the global object).
1194 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 1187 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
(...skipping 13 matching lines...) Expand all
1208 // Set the property. 1201 // Set the property.
1209 return Runtime::SetObjectProperty(object, key, value, NONE); 1202 return Runtime::SetObjectProperty(object, key, value, NONE);
1210 } 1203 }
1211 1204
1212 1205
1213 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, 1206 void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
1214 State state, 1207 State state,
1215 Handle<JSObject> receiver, 1208 Handle<JSObject> receiver,
1216 Handle<String> name, 1209 Handle<String> name,
1217 Handle<Object> value) { 1210 Handle<Object> value) {
1218 ASSERT(lookup->IsLoaded());
1219
1220 // Skip JSGlobalProxy. 1211 // Skip JSGlobalProxy.
1221 if (receiver->IsJSGlobalProxy()) return; 1212 if (receiver->IsJSGlobalProxy()) return;
1222 1213
1223 // Bail out if we didn't find a result. 1214 // Bail out if we didn't find a result.
1224 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return; 1215 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return;
1225 1216
1226 // If the property is read-only, we leave the IC in its current 1217 // If the property is read-only, we leave the IC in its current
1227 // state. 1218 // state.
1228 if (lookup->IsReadOnly()) return; 1219 if (lookup->IsReadOnly()) return;
1229 1220
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 #undef ADDR 1512 #undef ADDR
1522 }; 1513 };
1523 1514
1524 1515
1525 Address IC::AddressFromUtilityId(IC::UtilityId id) { 1516 Address IC::AddressFromUtilityId(IC::UtilityId id) {
1526 return IC_utilities[id]; 1517 return IC_utilities[id];
1527 } 1518 }
1528 1519
1529 1520
1530 } } // namespace v8::internal 1521 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698