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

Side by Side Diff: src/ic.cc

Issue 647015: Remove the LookupResult IsValid method because it is confusing.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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/ia32/stub-cache-ia32.cc ('k') | src/objects.cc » ('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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 static void LookupForRead(Object* object, 323 static void LookupForRead(Object* object,
324 String* name, 324 String* name,
325 LookupResult* lookup) { 325 LookupResult* lookup) {
326 AssertNoAllocation no_gc; // pointers must stay valid 326 AssertNoAllocation no_gc; // pointers must stay valid
327 327
328 // Skip all the objects with named interceptors, but 328 // Skip all the objects with named interceptors, but
329 // without actual getter. 329 // without actual getter.
330 while (true) { 330 while (true) {
331 object->Lookup(name, lookup); 331 object->Lookup(name, lookup);
332 // Besides normal conditions (property not found or it's not 332 // Besides normal conditions (property not found or it's not
333 // an interceptor), bail out of lookup is not cacheable: we won't 333 // an interceptor), bail out if lookup is not cacheable: we won't
334 // be able to IC it anyway and regular lookup should work fine. 334 // be able to IC it anyway and regular lookup should work fine.
335 if (lookup->IsNotFound() || lookup->type() != INTERCEPTOR || 335 if (!lookup->IsFound()
336 !lookup->IsCacheable()) { 336 || (lookup->type() != INTERCEPTOR)
337 || !lookup->IsCacheable()) {
337 return; 338 return;
338 } 339 }
339 340
340 JSObject* holder = lookup->holder(); 341 JSObject* holder = lookup->holder();
341 if (HasInterceptorGetter(holder)) { 342 if (HasInterceptorGetter(holder)) {
342 return; 343 return;
343 } 344 }
344 345
345 holder->LocalLookupRealNamedProperty(name, lookup); 346 holder->LocalLookupRealNamedProperty(name, lookup);
346 if (lookup->IsValid()) { 347 if (lookup->IsProperty()) {
347 ASSERT(lookup->type() != INTERCEPTOR); 348 ASSERT(lookup->type() != INTERCEPTOR);
348 return; 349 return;
349 } 350 }
350 351
351 Object* proto = holder->GetPrototype(); 352 Object* proto = holder->GetPrototype();
352 if (proto->IsNull()) { 353 if (proto->IsNull()) {
353 lookup->NotFound(); 354 lookup->NotFound();
354 return; 355 return;
355 } 356 }
356 357
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 result = TryCallAsFunction(result); 416 result = TryCallAsFunction(result);
416 if (result->IsJSFunction()) return result; 417 if (result->IsJSFunction()) return result;
417 418
418 // Otherwise, it will fail in the lookup step. 419 // Otherwise, it will fail in the lookup step.
419 } 420 }
420 421
421 // Lookup the property in the object. 422 // Lookup the property in the object.
422 LookupResult lookup; 423 LookupResult lookup;
423 LookupForRead(*object, *name, &lookup); 424 LookupForRead(*object, *name, &lookup);
424 425
425 if (!lookup.IsValid()) { 426 if (!lookup.IsProperty()) {
426 // If the object does not have the requested property, check which 427 // If the object does not have the requested property, check which
427 // exception we need to throw. 428 // exception we need to throw.
428 if (IsContextual(object)) { 429 if (IsContextual(object)) {
429 return ReferenceError("not_defined", name); 430 return ReferenceError("not_defined", name);
430 } 431 }
431 return TypeError("undefined_method", object, name); 432 return TypeError("undefined_method", object, name);
432 } 433 }
433 434
434 // Lookup is valid: Update inline cache and stub cache. 435 // Lookup is valid: Update inline cache and stub cache.
435 if (FLAG_use_ic && lookup.IsLoaded()) { 436 if (FLAG_use_ic && lookup.IsLoaded()) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 result : TypeError("property_not_function", object, name); 487 result : TypeError("property_not_function", object, name);
487 } 488 }
488 489
489 490
490 void CallIC::UpdateCaches(LookupResult* lookup, 491 void CallIC::UpdateCaches(LookupResult* lookup,
491 State state, 492 State state,
492 Handle<Object> object, 493 Handle<Object> object,
493 Handle<String> name) { 494 Handle<String> name) {
494 ASSERT(lookup->IsLoaded()); 495 ASSERT(lookup->IsLoaded());
495 // Bail out if we didn't find a result. 496 // Bail out if we didn't find a result.
496 if (!lookup->IsValid() || !lookup->IsCacheable()) return; 497 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
497 498
498 // Compute the number of arguments. 499 // Compute the number of arguments.
499 int argc = target()->arguments_count(); 500 int argc = target()->arguments_count();
500 InLoopFlag in_loop = target()->ic_in_loop(); 501 InLoopFlag in_loop = target()->ic_in_loop();
501 Object* code = NULL; 502 Object* code = NULL;
502 503
503 if (state == UNINITIALIZED) { 504 if (state == UNINITIALIZED) {
504 // This is the first time we execute this inline cache. 505 // This is the first time we execute this inline cache.
505 // Set the target to the pre monomorphic stub to delay 506 // Set the target to the pre monomorphic stub to delay
506 // setting the monomorphic state. 507 // setting the monomorphic state.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 636
636 // Check if the name is trivially convertible to an index and get 637 // Check if the name is trivially convertible to an index and get
637 // the element if so. 638 // the element if so.
638 uint32_t index; 639 uint32_t index;
639 if (name->AsArrayIndex(&index)) return object->GetElement(index); 640 if (name->AsArrayIndex(&index)) return object->GetElement(index);
640 641
641 // Named lookup in the object. 642 // Named lookup in the object.
642 LookupResult lookup; 643 LookupResult lookup;
643 LookupForRead(*object, *name, &lookup); 644 LookupForRead(*object, *name, &lookup);
644 645
645 // If lookup is invalid, check if we need to throw an exception. 646 // If we did not find a property, check if we need to throw an exception.
646 if (!lookup.IsValid()) { 647 if (!lookup.IsProperty()) {
647 if (FLAG_strict || IsContextual(object)) { 648 if (FLAG_strict || IsContextual(object)) {
648 return ReferenceError("not_defined", name); 649 return ReferenceError("not_defined", name);
649 } 650 }
650 LOG(SuspectReadEvent(*name, *object)); 651 LOG(SuspectReadEvent(*name, *object));
651 } 652 }
652 653
653 bool can_be_inlined = 654 bool can_be_inlined =
654 FLAG_use_ic && 655 FLAG_use_ic &&
655 state == PREMONOMORPHIC && 656 state == PREMONOMORPHIC &&
656 lookup.IsValid() && 657 lookup.IsProperty() &&
657 lookup.IsLoaded() && 658 lookup.IsLoaded() &&
658 lookup.IsCacheable() && 659 lookup.IsCacheable() &&
659 lookup.holder() == *object && 660 lookup.holder() == *object &&
660 lookup.type() == FIELD && 661 lookup.type() == FIELD &&
661 !object->IsAccessCheckNeeded(); 662 !object->IsAccessCheckNeeded();
662 663
663 if (can_be_inlined) { 664 if (can_be_inlined) {
664 Map* map = lookup.holder()->map(); 665 Map* map = lookup.holder()->map();
665 // Property's index in the properties array. If negative we have 666 // Property's index in the properties array. If negative we have
666 // an inobject property. 667 // an inobject property.
667 int index = lookup.GetFieldIndex() - map->inobject_properties(); 668 int index = lookup.GetFieldIndex() - map->inobject_properties();
668 if (index < 0) { 669 if (index < 0) {
669 // Index is an offset from the end of the object. 670 // Index is an offset from the end of the object.
670 int offset = map->instance_size() + (index * kPointerSize); 671 int offset = map->instance_size() + (index * kPointerSize);
671 if (PatchInlinedLoad(address(), map, offset)) { 672 if (PatchInlinedLoad(address(), map, offset)) {
672 set_target(megamorphic_stub()); 673 set_target(megamorphic_stub());
673 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex()); 674 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
674 } 675 }
675 } 676 }
676 } 677 }
677 678
678 // Update inline cache and stub cache. 679 // Update inline cache and stub cache.
679 if (FLAG_use_ic && lookup.IsLoaded()) { 680 if (FLAG_use_ic && lookup.IsLoaded()) {
680 UpdateCaches(&lookup, state, object, name); 681 UpdateCaches(&lookup, state, object, name);
681 } 682 }
682 683
683 PropertyAttributes attr; 684 PropertyAttributes attr;
684 if (lookup.IsValid() && lookup.type() == INTERCEPTOR) { 685 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
685 // Get the property. 686 // Get the property.
686 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 687 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
687 if (result->IsFailure()) return result; 688 if (result->IsFailure()) return result;
688 // If the property is not present, check if we need to throw an 689 // If the property is not present, check if we need to throw an
689 // exception. 690 // exception.
690 if (attr == ABSENT && IsContextual(object)) { 691 if (attr == ABSENT && IsContextual(object)) {
691 return ReferenceError("not_defined", name); 692 return ReferenceError("not_defined", name);
692 } 693 }
693 return result; 694 return result;
694 } 695 }
695 696
696 // Get the property. 697 // Get the property.
697 return object->GetProperty(*object, &lookup, *name, &attr); 698 return object->GetProperty(*object, &lookup, *name, &attr);
698 } 699 }
699 700
700 701
701 void LoadIC::UpdateCaches(LookupResult* lookup, 702 void LoadIC::UpdateCaches(LookupResult* lookup,
702 State state, 703 State state,
703 Handle<Object> object, 704 Handle<Object> object,
704 Handle<String> name) { 705 Handle<String> name) {
705 ASSERT(lookup->IsLoaded()); 706 ASSERT(lookup->IsLoaded());
706 // Bail out if we didn't find a result. 707 // Bail out if we didn't find a result.
707 if (!lookup->IsValid() || !lookup->IsCacheable()) return; 708 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
708 709
709 // Loading properties from values is not common, so don't try to 710 // Loading properties from values is not common, so don't try to
710 // deal with non-JS objects here. 711 // deal with non-JS objects here.
711 if (!object->IsJSObject()) return; 712 if (!object->IsJSObject()) return;
712 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 713 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
713 714
714 // Compute the code stub for this load. 715 // Compute the code stub for this load.
715 Object* code = NULL; 716 Object* code = NULL;
716 if (state == UNINITIALIZED) { 717 if (state == UNINITIALIZED) {
717 // This is the first time we execute this inline cache. 718 // This is the first time we execute this inline cache.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 HandleScope scope; 851 HandleScope scope;
851 // Rewrite to the generic keyed load stub. 852 // Rewrite to the generic keyed load stub.
852 if (FLAG_use_ic) set_target(generic_stub()); 853 if (FLAG_use_ic) set_target(generic_stub());
853 return Runtime::GetElementOrCharAt(object, index); 854 return Runtime::GetElementOrCharAt(object, index);
854 } 855 }
855 856
856 // Named lookup. 857 // Named lookup.
857 LookupResult lookup; 858 LookupResult lookup;
858 LookupForRead(*object, *name, &lookup); 859 LookupForRead(*object, *name, &lookup);
859 860
860 // If lookup is invalid, check if we need to throw an exception. 861 // If we did not find a property, check if we need to throw an exception.
861 if (!lookup.IsValid()) { 862 if (!lookup.IsProperty()) {
862 if (FLAG_strict || IsContextual(object)) { 863 if (FLAG_strict || IsContextual(object)) {
863 return ReferenceError("not_defined", name); 864 return ReferenceError("not_defined", name);
864 } 865 }
865 } 866 }
866 867
867 if (FLAG_use_ic && lookup.IsLoaded()) { 868 if (FLAG_use_ic && lookup.IsLoaded()) {
868 UpdateCaches(&lookup, state, object, name); 869 UpdateCaches(&lookup, state, object, name);
869 } 870 }
870 871
871 PropertyAttributes attr; 872 PropertyAttributes attr;
872 if (lookup.IsValid() && lookup.type() == INTERCEPTOR) { 873 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
873 // Get the property. 874 // Get the property.
874 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 875 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
875 if (result->IsFailure()) return result; 876 if (result->IsFailure()) return result;
876 // If the property is not present, check if we need to throw an 877 // If the property is not present, check if we need to throw an
877 // exception. 878 // exception.
878 if (attr == ABSENT && IsContextual(object)) { 879 if (attr == ABSENT && IsContextual(object)) {
879 return ReferenceError("not_defined", name); 880 return ReferenceError("not_defined", name);
880 } 881 }
881 return result; 882 return result;
882 } 883 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 915
915 // Get the property. 916 // Get the property.
916 return Runtime::GetObjectProperty(object, key); 917 return Runtime::GetObjectProperty(object, key);
917 } 918 }
918 919
919 920
920 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, 921 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state,
921 Handle<Object> object, Handle<String> name) { 922 Handle<Object> object, Handle<String> name) {
922 ASSERT(lookup->IsLoaded()); 923 ASSERT(lookup->IsLoaded());
923 // Bail out if we didn't find a result. 924 // Bail out if we didn't find a result.
924 if (!lookup->IsValid() || !lookup->IsCacheable()) return; 925 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
925 926
926 if (!object->IsJSObject()) return; 927 if (!object->IsJSObject()) return;
927 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 928 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
928 929
929 // Compute the code stub for this load. 930 // Compute the code stub for this load.
930 Object* code = NULL; 931 Object* code = NULL;
931 932
932 if (state == UNINITIALIZED) { 933 if (state == UNINITIALIZED) {
933 // This is the first time we execute this inline cache. 934 // This is the first time we execute this inline cache.
934 // Set the target to the pre monomorphic stub to delay 935 // Set the target to the pre monomorphic stub to delay
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 } 988 }
988 989
989 #ifdef DEBUG 990 #ifdef DEBUG
990 TraceIC("KeyedLoadIC", name, state, target()); 991 TraceIC("KeyedLoadIC", name, state, target());
991 #endif 992 #endif
992 } 993 }
993 994
994 995
995 static bool StoreICableLookup(LookupResult* lookup) { 996 static bool StoreICableLookup(LookupResult* lookup) {
996 // Bail out if we didn't find a result. 997 // Bail out if we didn't find a result.
997 if (!lookup->IsValid() || !lookup->IsCacheable()) return false; 998 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;
998 999
999 // If the property is read-only, we leave the IC in its current 1000 // If the property is read-only, we leave the IC in its current
1000 // state. 1001 // state.
1001 if (lookup->IsReadOnly()) return false; 1002 if (lookup->IsReadOnly()) return false;
1002 1003
1003 if (!lookup->IsLoaded()) return false; 1004 if (!lookup->IsLoaded()) return false;
1004 1005
1005 return true; 1006 return true;
1006 } 1007 }
1007 1008
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 State state, 1208 State state,
1208 Handle<JSObject> receiver, 1209 Handle<JSObject> receiver,
1209 Handle<String> name, 1210 Handle<String> name,
1210 Handle<Object> value) { 1211 Handle<Object> value) {
1211 ASSERT(lookup->IsLoaded()); 1212 ASSERT(lookup->IsLoaded());
1212 1213
1213 // Skip JSGlobalProxy. 1214 // Skip JSGlobalProxy.
1214 if (receiver->IsJSGlobalProxy()) return; 1215 if (receiver->IsJSGlobalProxy()) return;
1215 1216
1216 // Bail out if we didn't find a result. 1217 // Bail out if we didn't find a result.
1217 if (!lookup->IsValid() || !lookup->IsCacheable()) return; 1218 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return;
1218 1219
1219 // If the property is read-only, we leave the IC in its current 1220 // If the property is read-only, we leave the IC in its current
1220 // state. 1221 // state.
1221 if (lookup->IsReadOnly()) return; 1222 if (lookup->IsReadOnly()) return;
1222 1223
1223 // If the property has a non-field type allowing map transitions 1224 // If the property has a non-field type allowing map transitions
1224 // where there is extra room in the object, we leave the IC in its 1225 // where there is extra room in the object, we leave the IC in its
1225 // current state. 1226 // current state.
1226 PropertyType type = lookup->type(); 1227 PropertyType type = lookup->type();
1227 1228
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 #undef ADDR 1396 #undef ADDR
1396 }; 1397 };
1397 1398
1398 1399
1399 Address IC::AddressFromUtilityId(IC::UtilityId id) { 1400 Address IC::AddressFromUtilityId(IC::UtilityId id) {
1400 return IC_utilities[id]; 1401 return IC_utilities[id];
1401 } 1402 }
1402 1403
1403 1404
1404 } } // namespace v8::internal 1405 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698