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

Side by Side Diff: src/ic.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
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/ic.h ('k') | src/jump-target.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) { 436 if (FLAG_use_ic) {
(...skipping 12 matching lines...) Expand all
448 return ReferenceError("not_defined", name); 449 return ReferenceError("not_defined", name);
449 } 450 }
450 return TypeError("undefined_method", object, name); 451 return TypeError("undefined_method", object, name);
451 } 452 }
452 } 453 }
453 454
454 ASSERT(result != Heap::the_hole_value()); 455 ASSERT(result != Heap::the_hole_value());
455 456
456 if (result->IsJSFunction()) { 457 if (result->IsJSFunction()) {
457 // Check if there is an optimized (builtin) version of the function. 458 // Check if there is an optimized (builtin) version of the function.
458 // Ignored this will degrade performance for Array.prototype.{push,pop}. 459 // Ignored this will degrade performance for some Array functions.
459 // Please note we only return the optimized function iff 460 // Please note we only return the optimized function iff
460 // the JSObject has FastElements. 461 // the JSObject has FastElements.
461 if (object->IsJSObject() && JSObject::cast(*object)->HasFastElements()) { 462 if (object->IsJSObject() && JSObject::cast(*object)->HasFastElements()) {
462 Object* opt = Top::LookupSpecialFunction(JSObject::cast(*object), 463 Object* opt = Top::LookupSpecialFunction(JSObject::cast(*object),
463 lookup.holder(), 464 lookup.holder(),
464 JSFunction::cast(result)); 465 JSFunction::cast(result));
465 if (opt->IsJSFunction()) return opt; 466 if (opt->IsJSFunction()) return opt;
466 } 467 }
467 468
468 #ifdef ENABLE_DEBUGGER_SUPPORT 469 #ifdef ENABLE_DEBUGGER_SUPPORT
(...skipping 16 matching lines...) Expand all
485 return result->IsJSFunction() ? 486 return result->IsJSFunction() ?
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 // Bail out if we didn't find a result. 495 // Bail out if we didn't find a result.
495 if (!lookup->IsValid() || !lookup->IsCacheable()) return; 496 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
496 497
497 // Compute the number of arguments. 498 // Compute the number of arguments.
498 int argc = target()->arguments_count(); 499 int argc = target()->arguments_count();
499 InLoopFlag in_loop = target()->ic_in_loop(); 500 InLoopFlag in_loop = target()->ic_in_loop();
500 Object* code = NULL; 501 Object* code = NULL;
501 502
502 if (state == UNINITIALIZED) { 503 if (state == UNINITIALIZED) {
503 // This is the first time we execute this inline cache. 504 // This is the first time we execute this inline cache.
504 // Set the target to the pre monomorphic stub to delay 505 // Set the target to the pre monomorphic stub to delay
505 // setting the monomorphic state. 506 // setting the monomorphic state.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 635
635 // Check if the name is trivially convertible to an index and get 636 // Check if the name is trivially convertible to an index and get
636 // the element if so. 637 // the element if so.
637 uint32_t index; 638 uint32_t index;
638 if (name->AsArrayIndex(&index)) return object->GetElement(index); 639 if (name->AsArrayIndex(&index)) return object->GetElement(index);
639 640
640 // Named lookup in the object. 641 // Named lookup in the object.
641 LookupResult lookup; 642 LookupResult lookup;
642 LookupForRead(*object, *name, &lookup); 643 LookupForRead(*object, *name, &lookup);
643 644
644 // If lookup is invalid, check if we need to throw an exception. 645 // If we did not find a property, check if we need to throw an exception.
645 if (!lookup.IsValid()) { 646 if (!lookup.IsProperty()) {
646 if (FLAG_strict || IsContextual(object)) { 647 if (FLAG_strict || IsContextual(object)) {
647 return ReferenceError("not_defined", name); 648 return ReferenceError("not_defined", name);
648 } 649 }
649 LOG(SuspectReadEvent(*name, *object)); 650 LOG(SuspectReadEvent(*name, *object));
650 } 651 }
651 652
652 bool can_be_inlined = 653 bool can_be_inlined =
653 FLAG_use_ic && 654 FLAG_use_ic &&
654 state == PREMONOMORPHIC && 655 state == PREMONOMORPHIC &&
655 lookup.IsValid() && 656 lookup.IsProperty() &&
656 lookup.IsCacheable() && 657 lookup.IsCacheable() &&
657 lookup.holder() == *object && 658 lookup.holder() == *object &&
658 lookup.type() == FIELD && 659 lookup.type() == FIELD &&
659 !object->IsAccessCheckNeeded(); 660 !object->IsAccessCheckNeeded();
660 661
661 if (can_be_inlined) { 662 if (can_be_inlined) {
662 Map* map = lookup.holder()->map(); 663 Map* map = lookup.holder()->map();
663 // Property's index in the properties array. If negative we have 664 // Property's index in the properties array. If negative we have
664 // an inobject property. 665 // an inobject property.
665 int index = lookup.GetFieldIndex() - map->inobject_properties(); 666 int index = lookup.GetFieldIndex() - map->inobject_properties();
666 if (index < 0) { 667 if (index < 0) {
667 // Index is an offset from the end of the object. 668 // Index is an offset from the end of the object.
668 int offset = map->instance_size() + (index * kPointerSize); 669 int offset = map->instance_size() + (index * kPointerSize);
669 if (PatchInlinedLoad(address(), map, offset)) { 670 if (PatchInlinedLoad(address(), map, offset)) {
670 set_target(megamorphic_stub()); 671 set_target(megamorphic_stub());
671 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex()); 672 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
672 } 673 }
673 } 674 }
674 } 675 }
675 676
676 // Update inline cache and stub cache. 677 // Update inline cache and stub cache.
677 if (FLAG_use_ic) { 678 if (FLAG_use_ic) {
678 UpdateCaches(&lookup, state, object, name); 679 UpdateCaches(&lookup, state, object, name);
679 } 680 }
680 681
681 PropertyAttributes attr; 682 PropertyAttributes attr;
682 if (lookup.IsValid() && lookup.type() == INTERCEPTOR) { 683 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
683 // Get the property. 684 // Get the property.
684 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 685 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
685 if (result->IsFailure()) return result; 686 if (result->IsFailure()) return result;
686 // If the property is not present, check if we need to throw an 687 // If the property is not present, check if we need to throw an
687 // exception. 688 // exception.
688 if (attr == ABSENT && IsContextual(object)) { 689 if (attr == ABSENT && IsContextual(object)) {
689 return ReferenceError("not_defined", name); 690 return ReferenceError("not_defined", name);
690 } 691 }
691 return result; 692 return result;
692 } 693 }
693 694
694 // Get the property. 695 // Get the property.
695 return object->GetProperty(*object, &lookup, *name, &attr); 696 return object->GetProperty(*object, &lookup, *name, &attr);
696 } 697 }
697 698
698 699
699 void LoadIC::UpdateCaches(LookupResult* lookup, 700 void LoadIC::UpdateCaches(LookupResult* lookup,
700 State state, 701 State state,
701 Handle<Object> object, 702 Handle<Object> object,
702 Handle<String> name) { 703 Handle<String> name) {
703 // Bail out if we didn't find a result. 704 // Bail out if we didn't find a result.
704 if (!lookup->IsValid() || !lookup->IsCacheable()) return; 705 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
705 706
706 // Loading properties from values is not common, so don't try to 707 // Loading properties from values is not common, so don't try to
707 // deal with non-JS objects here. 708 // deal with non-JS objects here.
708 if (!object->IsJSObject()) return; 709 if (!object->IsJSObject()) return;
709 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 710 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
710 711
711 // Compute the code stub for this load. 712 // Compute the code stub for this load.
712 Object* code = NULL; 713 Object* code = NULL;
713 if (state == UNINITIALIZED) { 714 if (state == UNINITIALIZED) {
714 // This is the first time we execute this inline cache. 715 // This is the first time we execute this inline cache.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 HandleScope scope; 848 HandleScope scope;
848 // Rewrite to the generic keyed load stub. 849 // Rewrite to the generic keyed load stub.
849 if (FLAG_use_ic) set_target(generic_stub()); 850 if (FLAG_use_ic) set_target(generic_stub());
850 return Runtime::GetElementOrCharAt(object, index); 851 return Runtime::GetElementOrCharAt(object, index);
851 } 852 }
852 853
853 // Named lookup. 854 // Named lookup.
854 LookupResult lookup; 855 LookupResult lookup;
855 LookupForRead(*object, *name, &lookup); 856 LookupForRead(*object, *name, &lookup);
856 857
857 // If lookup is invalid, check if we need to throw an exception. 858 // If we did not find a property, check if we need to throw an exception.
858 if (!lookup.IsValid()) { 859 if (!lookup.IsProperty()) {
859 if (FLAG_strict || IsContextual(object)) { 860 if (FLAG_strict || IsContextual(object)) {
860 return ReferenceError("not_defined", name); 861 return ReferenceError("not_defined", name);
861 } 862 }
862 } 863 }
863 864
864 if (FLAG_use_ic) { 865 if (FLAG_use_ic) {
865 UpdateCaches(&lookup, state, object, name); 866 UpdateCaches(&lookup, state, object, name);
866 } 867 }
867 868
868 PropertyAttributes attr; 869 PropertyAttributes attr;
869 if (lookup.IsValid() && lookup.type() == INTERCEPTOR) { 870 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
870 // Get the property. 871 // Get the property.
871 Object* result = object->GetProperty(*object, &lookup, *name, &attr); 872 Object* result = object->GetProperty(*object, &lookup, *name, &attr);
872 if (result->IsFailure()) return result; 873 if (result->IsFailure()) return result;
873 // If the property is not present, check if we need to throw an 874 // If the property is not present, check if we need to throw an
874 // exception. 875 // exception.
875 if (attr == ABSENT && IsContextual(object)) { 876 if (attr == ABSENT && IsContextual(object)) {
876 return ReferenceError("not_defined", name); 877 return ReferenceError("not_defined", name);
877 } 878 }
878 return result; 879 return result;
879 } 880 }
880 881
881 return object->GetProperty(*object, &lookup, *name, &attr); 882 return object->GetProperty(*object, &lookup, *name, &attr);
882 } 883 }
883 884
884 // Do not use ICs for objects that require access checks (including 885 // Do not use ICs for objects that require access checks (including
885 // the global object). 886 // the global object).
886 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 887 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
887 888
888 if (use_ic) { 889 if (use_ic) {
889 Code* stub = generic_stub(); 890 Code* stub = generic_stub();
890 if (object->IsString() && key->IsNumber()) { 891 if (object->IsString() && key->IsNumber()) {
891 stub = string_stub(); 892 stub = string_stub();
892 } else if (object->IsJSObject()) { 893 } else if (object->IsJSObject()) {
893 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 894 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
894 if (receiver->HasExternalArrayElements()) { 895 if (receiver->HasExternalArrayElements()) {
895 stub = external_array_stub(receiver->GetElementsKind()); 896 stub = external_array_stub(receiver->GetElementsKind());
897 } else if (receiver->HasIndexedInterceptor()) {
898 stub = indexed_interceptor_stub();
896 } 899 }
897 } 900 }
898 set_target(stub); 901 set_target(stub);
899 // For JSObjects that are not value wrappers and that do not have 902 // For JSObjects that are not value wrappers and that do not have
900 // indexed interceptors, we initialize the inlined fast case (if 903 // indexed interceptors, we initialize the inlined fast case (if
901 // present) by patching the inlined map check. 904 // present) by patching the inlined map check.
902 if (object->IsJSObject() && 905 if (object->IsJSObject() &&
903 !object->IsJSValue() && 906 !object->IsJSValue() &&
904 !JSObject::cast(*object)->HasIndexedInterceptor()) { 907 !JSObject::cast(*object)->HasIndexedInterceptor()) {
905 Map* map = JSObject::cast(*object)->map(); 908 Map* map = JSObject::cast(*object)->map();
906 PatchInlinedLoad(address(), map); 909 PatchInlinedLoad(address(), map);
907 } 910 }
908 } 911 }
909 912
910 // Get the property. 913 // Get the property.
911 return Runtime::GetObjectProperty(object, key); 914 return Runtime::GetObjectProperty(object, key);
912 } 915 }
913 916
914 917
915 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, 918 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state,
916 Handle<Object> object, Handle<String> name) { 919 Handle<Object> object, Handle<String> name) {
917 // Bail out if we didn't find a result. 920 // Bail out if we didn't find a result.
918 if (!lookup->IsValid() || !lookup->IsCacheable()) return; 921 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
919 922
920 if (!object->IsJSObject()) return; 923 if (!object->IsJSObject()) return;
921 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 924 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
922 925
923 // Compute the code stub for this load. 926 // Compute the code stub for this load.
924 Object* code = NULL; 927 Object* code = NULL;
925 928
926 if (state == UNINITIALIZED) { 929 if (state == UNINITIALIZED) {
927 // This is the first time we execute this inline cache. 930 // This is the first time we execute this inline cache.
928 // Set the target to the pre monomorphic stub to delay 931 // Set the target to the pre monomorphic stub to delay
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 } 984 }
982 985
983 #ifdef DEBUG 986 #ifdef DEBUG
984 TraceIC("KeyedLoadIC", name, state, target()); 987 TraceIC("KeyedLoadIC", name, state, target());
985 #endif 988 #endif
986 } 989 }
987 990
988 991
989 static bool StoreICableLookup(LookupResult* lookup) { 992 static bool StoreICableLookup(LookupResult* lookup) {
990 // Bail out if we didn't find a result. 993 // Bail out if we didn't find a result.
991 if (!lookup->IsValid() || !lookup->IsCacheable()) return false; 994 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;
992 995
993 // If the property is read-only, we leave the IC in its current 996 // If the property is read-only, we leave the IC in its current
994 // state. 997 // state.
995 if (lookup->IsReadOnly()) return false; 998 if (lookup->IsReadOnly()) return false;
996 999
997 return true; 1000 return true;
998 } 1001 }
999 1002
1000 1003
1001 static bool LookupForWrite(JSObject* object, 1004 static bool LookupForWrite(JSObject* object,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 1036
1034 // Check if the given name is an array index. 1037 // Check if the given name is an array index.
1035 uint32_t index; 1038 uint32_t index;
1036 if (name->AsArrayIndex(&index)) { 1039 if (name->AsArrayIndex(&index)) {
1037 HandleScope scope; 1040 HandleScope scope;
1038 Handle<Object> result = SetElement(receiver, index, value); 1041 Handle<Object> result = SetElement(receiver, index, value);
1039 if (result.is_null()) return Failure::Exception(); 1042 if (result.is_null()) return Failure::Exception();
1040 return *value; 1043 return *value;
1041 } 1044 }
1042 1045
1046
1047 // Use specialized code for setting the length of arrays.
1048 if (receiver->IsJSArray()
1049 && name->Equals(Heap::length_symbol())
1050 && receiver->AllowsSetElementsLength()) {
1051 #ifdef DEBUG
1052 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
1053 #endif
1054 Code* target = Builtins::builtin(Builtins::StoreIC_ArrayLength);
1055 set_target(target);
1056 StubCache::Set(*name, HeapObject::cast(*object)->map(), target);
1057 return receiver->SetProperty(*name, *value, NONE);
1058 }
1059
1043 // Lookup the property locally in the receiver. 1060 // Lookup the property locally in the receiver.
1044 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { 1061 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1045 LookupResult lookup; 1062 LookupResult lookup;
1046 if (LookupForWrite(*receiver, *name, &lookup)) { 1063 if (LookupForWrite(*receiver, *name, &lookup)) {
1047 UpdateCaches(&lookup, state, receiver, name, value); 1064 UpdateCaches(&lookup, state, receiver, name, value);
1048 } 1065 }
1049 } 1066 }
1050 1067
1051 // Set the property. 1068 // Set the property.
1052 return receiver->SetProperty(*name, *value, NONE); 1069 return receiver->SetProperty(*name, *value, NONE);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 1213
1197 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, 1214 void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
1198 State state, 1215 State state,
1199 Handle<JSObject> receiver, 1216 Handle<JSObject> receiver,
1200 Handle<String> name, 1217 Handle<String> name,
1201 Handle<Object> value) { 1218 Handle<Object> value) {
1202 // Skip JSGlobalProxy. 1219 // Skip JSGlobalProxy.
1203 if (receiver->IsJSGlobalProxy()) return; 1220 if (receiver->IsJSGlobalProxy()) return;
1204 1221
1205 // Bail out if we didn't find a result. 1222 // Bail out if we didn't find a result.
1206 if (!lookup->IsValid() || !lookup->IsCacheable()) return; 1223 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return;
1207 1224
1208 // If the property is read-only, we leave the IC in its current 1225 // If the property is read-only, we leave the IC in its current
1209 // state. 1226 // state.
1210 if (lookup->IsReadOnly()) return; 1227 if (lookup->IsReadOnly()) return;
1211 1228
1212 // If the property has a non-field type allowing map transitions 1229 // If the property has a non-field type allowing map transitions
1213 // where there is extra room in the object, we leave the IC in its 1230 // where there is extra room in the object, we leave the IC in its
1214 // current state. 1231 // current state.
1215 PropertyType type = lookup->type(); 1232 PropertyType type = lookup->type();
1216 1233
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 // Used from ic_<arch>.cc. 1321 // Used from ic_<arch>.cc.
1305 Object* LoadIC_Miss(Arguments args) { 1322 Object* LoadIC_Miss(Arguments args) {
1306 NoHandleAllocation na; 1323 NoHandleAllocation na;
1307 ASSERT(args.length() == 2); 1324 ASSERT(args.length() == 2);
1308 LoadIC ic; 1325 LoadIC ic;
1309 IC::State state = IC::StateFrom(ic.target(), args[0]); 1326 IC::State state = IC::StateFrom(ic.target(), args[0]);
1310 return ic.Load(state, args.at<Object>(0), args.at<String>(1)); 1327 return ic.Load(state, args.at<Object>(0), args.at<String>(1));
1311 } 1328 }
1312 1329
1313 1330
1314 void LoadIC::GenerateInitialize(MacroAssembler* masm) {
1315 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
1316 }
1317
1318
1319 void LoadIC::GeneratePreMonomorphic(MacroAssembler* masm) {
1320 Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
1321 }
1322
1323
1324 // Used from ic_<arch>.cc 1331 // Used from ic_<arch>.cc
1325 Object* KeyedLoadIC_Miss(Arguments args) { 1332 Object* KeyedLoadIC_Miss(Arguments args) {
1326 NoHandleAllocation na; 1333 NoHandleAllocation na;
1327 ASSERT(args.length() == 2); 1334 ASSERT(args.length() == 2);
1328 KeyedLoadIC ic; 1335 KeyedLoadIC ic;
1329 IC::State state = IC::StateFrom(ic.target(), args[0]); 1336 IC::State state = IC::StateFrom(ic.target(), args[0]);
1330 return ic.Load(state, args.at<Object>(0), args.at<Object>(1)); 1337 return ic.Load(state, args.at<Object>(0), args.at<Object>(1));
1331 } 1338 }
1332 1339
1333 1340
1334 void KeyedLoadIC::GenerateInitialize(MacroAssembler* masm) {
1335 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
1336 }
1337
1338
1339 void KeyedLoadIC::GeneratePreMonomorphic(MacroAssembler* masm) {
1340 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
1341 }
1342
1343
1344 // Used from ic_<arch>.cc. 1341 // Used from ic_<arch>.cc.
1345 Object* StoreIC_Miss(Arguments args) { 1342 Object* StoreIC_Miss(Arguments args) {
1346 NoHandleAllocation na; 1343 NoHandleAllocation na;
1347 ASSERT(args.length() == 3); 1344 ASSERT(args.length() == 3);
1348 StoreIC ic; 1345 StoreIC ic;
1349 IC::State state = IC::StateFrom(ic.target(), args[0]); 1346 IC::State state = IC::StateFrom(ic.target(), args[0]);
1350 return ic.Store(state, args.at<Object>(0), args.at<String>(1), 1347 return ic.Store(state, args.at<Object>(0), args.at<String>(1),
1351 args.at<Object>(2)); 1348 args.at<Object>(2));
1352 } 1349 }
1353 1350
1354 1351
1352 Object* StoreIC_ArrayLength(Arguments args) {
1353 NoHandleAllocation nha;
1354
1355 ASSERT(args.length() == 2);
1356 JSObject* receiver = JSObject::cast(args[0]);
1357 Object* len = args[1];
1358
1359 return receiver->SetElementsLength(len);
1360 }
1361
1362
1355 // Extend storage is called in a store inline cache when 1363 // Extend storage is called in a store inline cache when
1356 // it is necessary to extend the properties array of a 1364 // it is necessary to extend the properties array of a
1357 // JSObject. 1365 // JSObject.
1358 Object* SharedStoreIC_ExtendStorage(Arguments args) { 1366 Object* SharedStoreIC_ExtendStorage(Arguments args) {
1359 NoHandleAllocation na; 1367 NoHandleAllocation na;
1360 ASSERT(args.length() == 3); 1368 ASSERT(args.length() == 3);
1361 1369
1362 // Convert the parameters 1370 // Convert the parameters
1363 JSObject* object = JSObject::cast(args[0]); 1371 JSObject* object = JSObject::cast(args[0]);
1364 Map* transition = Map::cast(args[1]); 1372 Map* transition = Map::cast(args[1]);
(...skipping 25 matching lines...) Expand all
1390 Object* KeyedStoreIC_Miss(Arguments args) { 1398 Object* KeyedStoreIC_Miss(Arguments args) {
1391 NoHandleAllocation na; 1399 NoHandleAllocation na;
1392 ASSERT(args.length() == 3); 1400 ASSERT(args.length() == 3);
1393 KeyedStoreIC ic; 1401 KeyedStoreIC ic;
1394 IC::State state = IC::StateFrom(ic.target(), args[0]); 1402 IC::State state = IC::StateFrom(ic.target(), args[0]);
1395 return ic.Store(state, args.at<Object>(0), args.at<Object>(1), 1403 return ic.Store(state, args.at<Object>(0), args.at<Object>(1),
1396 args.at<Object>(2)); 1404 args.at<Object>(2));
1397 } 1405 }
1398 1406
1399 1407
1400 void KeyedStoreIC::GenerateInitialize(MacroAssembler* masm) {
1401 Generate(masm, ExternalReference(IC_Utility(kKeyedStoreIC_Miss)));
1402 }
1403
1404
1405 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1406 Generate(masm, ExternalReference(IC_Utility(kKeyedStoreIC_Miss)));
1407 }
1408
1409
1410 static Address IC_utilities[] = { 1408 static Address IC_utilities[] = {
1411 #define ADDR(name) FUNCTION_ADDR(name), 1409 #define ADDR(name) FUNCTION_ADDR(name),
1412 IC_UTIL_LIST(ADDR) 1410 IC_UTIL_LIST(ADDR)
1413 NULL 1411 NULL
1414 #undef ADDR 1412 #undef ADDR
1415 }; 1413 };
1416 1414
1417 1415
1418 Address IC::AddressFromUtilityId(IC::UtilityId id) { 1416 Address IC::AddressFromUtilityId(IC::UtilityId id) {
1419 return IC_utilities[id]; 1417 return IC_utilities[id];
1420 } 1418 }
1421 1419
1422 1420
1423 } } // namespace v8::internal 1421 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/jump-target.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698