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

Side by Side Diff: src/ic.cc

Issue 8357010: Handlify the stub cache lookup and patching for CallIC and KeyedCallIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Do not assume functions are compiled when specializing. Created 9 years, 2 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/objects.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 } else { 93 } else {
94 PrintF("<unknown>"); 94 PrintF("<unknown>");
95 } 95 }
96 PrintF(" (%c->%c)", 96 PrintF(" (%c->%c)",
97 TransitionMarkFromState(old_state), 97 TransitionMarkFromState(old_state),
98 TransitionMarkFromState(new_state)); 98 TransitionMarkFromState(new_state));
99 name->Print(); 99 name->Print();
100 PrintF("]\n"); 100 PrintF("]\n");
101 } 101 }
102 } 102 }
103 #endif 103 #endif // DEBUG
104
105
106 #define TRACE_IC(type, name, old_state, new_target) \
107 ASSERT((TraceIC(type, name, old_state, new_target), true))
104 108
105 109
106 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { 110 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
107 ASSERT(isolate == Isolate::Current()); 111 ASSERT(isolate == Isolate::Current());
108 // To improve the performance of the (much used) IC code, we unfold 112 // To improve the performance of the (much used) IC code, we unfold
109 // a few levels of the stack frame iteration code. This yields a 113 // a few levels of the stack frame iteration code. This yields a
110 // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag. 114 // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag.
111 const Address entry = 115 const Address entry =
112 Isolate::c_entry_fp(isolate->thread_local_top()); 116 Isolate::c_entry_fp(isolate->thread_local_top());
113 Address* pc_address = 117 Address* pc_address =
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 } 575 }
572 } 576 }
573 break; 577 break;
574 default: 578 default:
575 return false; 579 return false;
576 } 580 }
577 return false; 581 return false;
578 } 582 }
579 583
580 584
581 MaybeObject* CallICBase::ComputeMonomorphicStub( 585 Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
582 LookupResult* lookup, 586 State state,
583 State state, 587 Code::ExtraICState extra_state,
584 Code::ExtraICState extra_ic_state, 588 Handle<Object> object,
585 Handle<Object> object, 589 Handle<String> name) {
586 Handle<String> name) {
587 int argc = target()->arguments_count(); 590 int argc = target()->arguments_count();
588 MaybeObject* maybe_code = NULL; 591 Handle<JSObject> holder(lookup->holder());
589 switch (lookup->type()) { 592 switch (lookup->type()) {
590 case FIELD: { 593 case FIELD: {
591 int index = lookup->GetFieldIndex(); 594 int index = lookup->GetFieldIndex();
592 maybe_code = isolate()->stub_cache()->ComputeCallField(argc, 595 return isolate()->stub_cache()->ComputeCallField(
593 kind_, 596 argc, kind_, extra_state, name, object, holder, index);
594 extra_ic_state,
595 *name,
596 *object,
597 lookup->holder(),
598 index);
599 break;
600 } 597 }
601 case CONSTANT_FUNCTION: { 598 case CONSTANT_FUNCTION: {
602 // Get the constant function and compute the code stub for this 599 // Get the constant function and compute the code stub for this
603 // call; used for rewriting to monomorphic state and making sure 600 // call; used for rewriting to monomorphic state and making sure
604 // that the code stub is in the stub cache. 601 // that the code stub is in the stub cache.
605 JSFunction* function = lookup->GetConstantFunction(); 602 Handle<JSFunction> function(lookup->GetConstantFunction());
606 maybe_code = 603 return isolate()->stub_cache()->ComputeCallConstant(
607 isolate()->stub_cache()->ComputeCallConstant(argc, 604 argc, kind_, extra_state, name, object, holder, function);
608 kind_,
609 extra_ic_state,
610 *name,
611 *object,
612 lookup->holder(),
613 function);
614 break;
615 } 605 }
616 case NORMAL: { 606 case NORMAL: {
617 if (!object->IsJSObject()) return NULL; 607 // If we return a null handle, the IC will not be patched.
608 if (!object->IsJSObject()) return Handle<Code>::null();
618 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 609 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
619 610
620 if (lookup->holder()->IsGlobalObject()) { 611 if (holder->IsGlobalObject()) {
621 GlobalObject* global = GlobalObject::cast(lookup->holder()); 612 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
622 JSGlobalPropertyCell* cell = 613 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
623 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 614 if (!cell->value()->IsJSFunction()) return Handle<Code>::null();
624 if (!cell->value()->IsJSFunction()) return NULL; 615 Handle<JSFunction> function(JSFunction::cast(cell->value()));
625 JSFunction* function = JSFunction::cast(cell->value()); 616 return isolate()->stub_cache()->ComputeCallGlobal(
626 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, 617 argc, kind_, extra_state, name, receiver, global, cell, function);
627 kind_,
628 extra_ic_state,
629 *name,
630 *receiver,
631 global,
632 cell,
633 function);
634 } else { 618 } else {
635 // There is only one shared stub for calling normalized 619 // There is only one shared stub for calling normalized
636 // properties. It does not traverse the prototype chain, so the 620 // properties. It does not traverse the prototype chain, so the
637 // property must be found in the receiver for the stub to be 621 // property must be found in the receiver for the stub to be
638 // applicable. 622 // applicable.
639 if (lookup->holder() != *receiver) return NULL; 623 if (!holder.is_identical_to(receiver)) return Handle<Code>::null();
640 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, 624 return isolate()->stub_cache()->ComputeCallNormal(
641 kind_, 625 argc, kind_, extra_state);
642 extra_ic_state,
643 *name,
644 *receiver);
645 } 626 }
646 break; 627 break;
647 } 628 }
648 case INTERCEPTOR: { 629 case INTERCEPTOR:
649 ASSERT(HasInterceptorGetter(lookup->holder())); 630 ASSERT(HasInterceptorGetter(*holder));
650 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor( 631 return isolate()->stub_cache()->ComputeCallInterceptor(
651 argc, 632 argc, kind_, extra_state, name, object, holder);
652 kind_,
653 extra_ic_state,
654 *name,
655 *object,
656 lookup->holder());
657 break;
658 }
659 default: 633 default:
660 maybe_code = NULL; 634 return Handle<Code>::null();
661 break;
662 } 635 }
663 return maybe_code;
664 } 636 }
665 637
666 638
667 void CallICBase::UpdateCaches(LookupResult* lookup, 639 void CallICBase::UpdateCaches(LookupResult* lookup,
668 State state, 640 State state,
669 Code::ExtraICState extra_ic_state, 641 Code::ExtraICState extra_ic_state,
670 Handle<Object> object, 642 Handle<Object> object,
671 Handle<String> name) { 643 Handle<String> name) {
672 // Bail out if we didn't find a result. 644 // Bail out if we didn't find a result.
673 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 645 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
674 646
675 if (lookup->holder() != *object && 647 if (lookup->holder() != *object &&
676 HasNormalObjectsInPrototypeChain( 648 HasNormalObjectsInPrototypeChain(
677 isolate(), lookup, object->GetPrototype())) { 649 isolate(), lookup, object->GetPrototype())) {
678 // Suppress optimization for prototype chains with slow properties objects 650 // Suppress optimization for prototype chains with slow properties objects
679 // in the middle. 651 // in the middle.
680 return; 652 return;
681 } 653 }
682 654
683 // Compute the number of arguments. 655 // Compute the number of arguments.
684 int argc = target()->arguments_count(); 656 int argc = target()->arguments_count();
685 MaybeObject* maybe_code = NULL;
686 bool had_proto_failure = false; 657 bool had_proto_failure = false;
658 Handle<Code> code;
687 if (state == UNINITIALIZED) { 659 if (state == UNINITIALIZED) {
688 // This is the first time we execute this inline cache. 660 // This is the first time we execute this inline cache.
689 // Set the target to the pre monomorphic stub to delay 661 // Set the target to the pre monomorphic stub to delay
690 // setting the monomorphic state. 662 // setting the monomorphic state.
691 maybe_code = 663 code = isolate()->stub_cache()->ComputeCallPreMonomorphic(
692 isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, 664 argc, kind_, extra_ic_state);
693 kind_,
694 extra_ic_state);
695 } else if (state == MONOMORPHIC) { 665 } else if (state == MONOMORPHIC) {
696 if (kind_ == Code::CALL_IC && 666 if (kind_ == Code::CALL_IC &&
697 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { 667 TryUpdateExtraICState(lookup, object, &extra_ic_state)) {
698 maybe_code = ComputeMonomorphicStub(lookup, 668 code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
699 state, 669 object, name);
700 extra_ic_state,
701 object,
702 name);
703 } else if (kind_ == Code::CALL_IC && 670 } else if (kind_ == Code::CALL_IC &&
704 TryRemoveInvalidPrototypeDependentStub(target(), 671 TryRemoveInvalidPrototypeDependentStub(target(),
705 *object, 672 *object,
706 *name)) { 673 *name)) {
707 had_proto_failure = true; 674 had_proto_failure = true;
708 maybe_code = ComputeMonomorphicStub(lookup, 675 code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
709 state, 676 object, name);
710 extra_ic_state,
711 object,
712 name);
713 } else { 677 } else {
714 maybe_code = 678 code = isolate()->stub_cache()->ComputeCallMegamorphic(
715 isolate()->stub_cache()->ComputeCallMegamorphic(argc, 679 argc, kind_, extra_ic_state);
716 kind_,
717 extra_ic_state);
718 } 680 }
719 } else { 681 } else {
720 maybe_code = ComputeMonomorphicStub(lookup, 682 code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
721 state, 683 object, name);
722 extra_ic_state,
723 object,
724 name);
725 } 684 }
726 685
727 // If we're unable to compute the stub (not enough memory left), we 686 // If there's no appropriate stub we simply avoid updating the caches.
728 // simply avoid updating the caches. 687 if (code.is_null()) return;
729 Object* code;
730 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
731 688
732 // Patch the call site depending on the state of the cache. 689 // Patch the call site depending on the state of the cache.
733 if (state == UNINITIALIZED || 690 if (state == UNINITIALIZED ||
734 state == PREMONOMORPHIC || 691 state == PREMONOMORPHIC ||
735 state == MONOMORPHIC || 692 state == MONOMORPHIC ||
736 state == MONOMORPHIC_PROTOTYPE_FAILURE) { 693 state == MONOMORPHIC_PROTOTYPE_FAILURE) {
737 set_target(Code::cast(code)); 694 set_target(*code);
738 } else if (state == MEGAMORPHIC) { 695 } else if (state == MEGAMORPHIC) {
739 // Cache code holding map should be consistent with 696 // Cache code holding map should be consistent with
740 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. 697 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
741 Map* map = JSObject::cast(object->IsJSObject() ? *object : 698 Handle<JSObject> cache_object = object->IsJSObject()
742 object->GetPrototype())->map(); 699 ? Handle<JSObject>::cast(object)
743 700 : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
744 // Update the stub cache. 701 // Update the stub cache.
745 isolate()->stub_cache()->Set(*name, map, Code::cast(code)); 702 isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
746 } 703 }
747 704
748 USE(had_proto_failure);
749 #ifdef DEBUG
750 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; 705 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
751 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", 706 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
752 name, state, target()); 707 name, state, target());
753 #endif
754 } 708 }
755 709
756 710
757 MaybeObject* KeyedCallIC::LoadFunction(State state, 711 MaybeObject* KeyedCallIC::LoadFunction(State state,
758 Handle<Object> object, 712 Handle<Object> object,
759 Handle<Object> key) { 713 Handle<Object> key) {
760 if (key->IsSymbol()) { 714 if (key->IsSymbol()) {
761 return CallICBase::LoadFunction(state, 715 return CallICBase::LoadFunction(state,
762 Code::kNoExtraICState, 716 Code::kNoExtraICState,
763 object, 717 object,
764 Handle<String>::cast(key)); 718 Handle<String>::cast(key));
765 } 719 }
766 720
767 if (object->IsUndefined() || object->IsNull()) { 721 if (object->IsUndefined() || object->IsNull()) {
768 return TypeError("non_object_property_call", object, key); 722 return TypeError("non_object_property_call", object, key);
769 } 723 }
770 724
771 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { 725 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
772 int argc = target()->arguments_count(); 726 int argc = target()->arguments_count();
773 Handle<Map> map = 727 Handle<Map> map =
774 isolate()->factory()->non_strict_arguments_elements_map(); 728 isolate()->factory()->non_strict_arguments_elements_map();
775 if (object->IsJSObject() && 729 if (object->IsJSObject() &&
776 Handle<JSObject>::cast(object)->elements()->map() == *map) { 730 Handle<JSObject>::cast(object)->elements()->map() == *map) {
777 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( 731 Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments(
778 argc, Code::KEYED_CALL_IC); 732 argc, Code::KEYED_CALL_IC);
779 Code* code = NULL; 733 set_target(*code);
780 if (maybe_code->To(&code)) { 734 TRACE_IC("KeyedCallIC", key, state, target());
781 set_target(code);
782 #ifdef DEBUG
783 TraceIC("KeyedCallIC", key, state, target());
784 #endif
785 }
786 } else if (!object->IsAccessCheckNeeded()) { 735 } else if (!object->IsAccessCheckNeeded()) {
787 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( 736 Handle<Code> code = isolate()->stub_cache()->ComputeCallMegamorphic(
788 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 737 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
789 Code* code; 738 set_target(*code);
790 if (maybe_code->To(&code)) { 739 TRACE_IC("KeyedCallIC", key, state, target());
791 set_target(code);
792 #ifdef DEBUG
793 TraceIC("KeyedCallIC", key, state, target());
794 #endif
795 }
796 } 740 }
797 } 741 }
798 742
799 Handle<Object> result = GetProperty(object, key); 743 Handle<Object> result = GetProperty(object, key);
800 RETURN_IF_EMPTY_HANDLE(isolate(), result); 744 RETURN_IF_EMPTY_HANDLE(isolate(), result);
801 745
802 // Make receiver an object if the callee requires it. Strict mode or builtin 746 // Make receiver an object if the callee requires it. Strict mode or builtin
803 // functions do not wrap the receiver, non-strict functions and objects 747 // functions do not wrap the receiver, non-strict functions and objects
804 // called as functions do. 748 // called as functions do.
805 ReceiverToObjectIfRequired(result, object); 749 ReceiverToObjectIfRequired(result, object);
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 state == MONOMORPHIC_PROTOTYPE_FAILURE) { 960 state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1017 set_target(*code); 961 set_target(*code);
1018 } else if (state == MONOMORPHIC) { 962 } else if (state == MONOMORPHIC) {
1019 set_target(*megamorphic_stub()); 963 set_target(*megamorphic_stub());
1020 } else if (state == MEGAMORPHIC) { 964 } else if (state == MEGAMORPHIC) {
1021 // Cache code holding map should be consistent with 965 // Cache code holding map should be consistent with
1022 // GenerateMonomorphicCacheProbe. 966 // GenerateMonomorphicCacheProbe.
1023 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 967 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1024 } 968 }
1025 969
1026 #ifdef DEBUG 970 TRACE_IC("LoadIC", name, state, target());
1027 TraceIC("LoadIC", name, state, target());
1028 #endif
1029 } 971 }
1030 972
1031 973
1032 MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck( 974 MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck(
1033 bool is_js_array, 975 bool is_js_array,
1034 ElementsKind elements_kind) { 976 ElementsKind elements_kind) {
1035 return KeyedLoadElementStub(elements_kind).TryGetCode(); 977 return KeyedLoadElementStub(elements_kind).TryGetCode();
1036 } 978 }
1037 979
1038 980
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 1031
1090 // Use specialized code for getting the length of strings. 1032 // Use specialized code for getting the length of strings.
1091 if (object->IsString() && 1033 if (object->IsString() &&
1092 name->Equals(isolate()->heap()->length_symbol())) { 1034 name->Equals(isolate()->heap()->length_symbol())) {
1093 Handle<String> string = Handle<String>::cast(object); 1035 Handle<String> string = Handle<String>::cast(object);
1094 Handle<Code> code = 1036 Handle<Code> code =
1095 isolate()->stub_cache()->ComputeKeyedLoadStringLength(name, 1037 isolate()->stub_cache()->ComputeKeyedLoadStringLength(name,
1096 string); 1038 string);
1097 ASSERT(!code.is_null()); 1039 ASSERT(!code.is_null());
1098 set_target(*code); 1040 set_target(*code);
1099 #ifdef DEBUG 1041 TRACE_IC("KeyedLoadIC", name, state, target());
1100 TraceIC("KeyedLoadIC", name, state, target());
1101 #endif // DEBUG
1102 return Smi::FromInt(string->length()); 1042 return Smi::FromInt(string->length());
1103 } 1043 }
1104 1044
1105 // Use specialized code for getting the length of arrays. 1045 // Use specialized code for getting the length of arrays.
1106 if (object->IsJSArray() && 1046 if (object->IsJSArray() &&
1107 name->Equals(isolate()->heap()->length_symbol())) { 1047 name->Equals(isolate()->heap()->length_symbol())) {
1108 Handle<JSArray> array = Handle<JSArray>::cast(object); 1048 Handle<JSArray> array = Handle<JSArray>::cast(object);
1109 Handle<Code> code = 1049 Handle<Code> code =
1110 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array); 1050 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array);
1111 ASSERT(!code.is_null()); 1051 ASSERT(!code.is_null());
1112 set_target(*code); 1052 set_target(*code);
1113 #ifdef DEBUG 1053 TRACE_IC("KeyedLoadIC", name, state, target());
1114 TraceIC("KeyedLoadIC", name, state, target());
1115 #endif // DEBUG
1116 return array->length(); 1054 return array->length();
1117 } 1055 }
1118 1056
1119 // Use specialized code for getting prototype of functions. 1057 // Use specialized code for getting prototype of functions.
1120 if (object->IsJSFunction() && 1058 if (object->IsJSFunction() &&
1121 name->Equals(isolate()->heap()->prototype_symbol()) && 1059 name->Equals(isolate()->heap()->prototype_symbol()) &&
1122 Handle<JSFunction>::cast(object)->should_have_prototype()) { 1060 Handle<JSFunction>::cast(object)->should_have_prototype()) {
1123 Handle<JSFunction> function = Handle<JSFunction>::cast(object); 1061 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
1124 Handle<Code> code = 1062 Handle<Code> code =
1125 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype( 1063 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype(
1126 name, function); 1064 name, function);
1127 ASSERT(!code.is_null()); 1065 ASSERT(!code.is_null());
1128 set_target(*code); 1066 set_target(*code);
1129 #ifdef DEBUG 1067 TRACE_IC("KeyedLoadIC", name, state, target());
1130 TraceIC("KeyedLoadIC", name, state, target());
1131 #endif // DEBUG
1132 return Accessors::FunctionGetPrototype(*object, 0); 1068 return Accessors::FunctionGetPrototype(*object, 0);
1133 } 1069 }
1134 } 1070 }
1135 1071
1136 // Check if the name is trivially convertible to an index and get 1072 // Check if the name is trivially convertible to an index and get
1137 // the element or char if so. 1073 // the element or char if so.
1138 uint32_t index = 0; 1074 uint32_t index = 0;
1139 if (name->AsArrayIndex(&index)) { 1075 if (name->AsArrayIndex(&index)) {
1140 // Rewrite to the generic keyed load stub. 1076 // Rewrite to the generic keyed load stub.
1141 if (FLAG_use_ic) set_target(*generic_stub()); 1077 if (FLAG_use_ic) set_target(*generic_stub());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 } else if (receiver->HasIndexedInterceptor()) { 1127 } else if (receiver->HasIndexedInterceptor()) {
1192 stub = indexed_interceptor_stub(); 1128 stub = indexed_interceptor_stub();
1193 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { 1129 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1194 stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub); 1130 stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub);
1195 } 1131 }
1196 } 1132 }
1197 } 1133 }
1198 if (!stub.is_null()) set_target(*stub); 1134 if (!stub.is_null()) set_target(*stub);
1199 } 1135 }
1200 1136
1201 #ifdef DEBUG 1137 TRACE_IC("KeyedLoadIC", key, state, target());
1202 TraceIC("KeyedLoadIC", key, state, target());
1203 #endif // DEBUG
1204 1138
1205 // Get the property. 1139 // Get the property.
1206 return Runtime::GetObjectProperty(isolate(), object, key); 1140 return Runtime::GetObjectProperty(isolate(), object, key);
1207 } 1141 }
1208 1142
1209 1143
1210 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, 1144 void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
1211 State state, 1145 State state,
1212 Handle<Object> object, 1146 Handle<Object> object,
1213 Handle<String> name) { 1147 Handle<String> name) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 1200
1267 // Patch the call site depending on the state of the cache. Make 1201 // Patch the call site depending on the state of the cache. Make
1268 // sure to always rewrite from monomorphic to megamorphic. 1202 // sure to always rewrite from monomorphic to megamorphic.
1269 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); 1203 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1270 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { 1204 if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1271 set_target(*code); 1205 set_target(*code);
1272 } else if (state == MONOMORPHIC) { 1206 } else if (state == MONOMORPHIC) {
1273 set_target(*megamorphic_stub()); 1207 set_target(*megamorphic_stub());
1274 } 1208 }
1275 1209
1276 #ifdef DEBUG 1210 TRACE_IC("KeyedLoadIC", name, state, target());
1277 TraceIC("KeyedLoadIC", name, state, target());
1278 #endif
1279 } 1211 }
1280 1212
1281 1213
1282 static bool StoreICableLookup(LookupResult* lookup) { 1214 static bool StoreICableLookup(LookupResult* lookup) {
1283 // Bail out if we didn't find a result. 1215 // Bail out if we didn't find a result.
1284 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false; 1216 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;
1285 1217
1286 // If the property is read-only, we leave the IC in its current 1218 // If the property is read-only, we leave the IC in its current
1287 // state. 1219 // state.
1288 if (lookup->IsReadOnly()) return false; 1220 if (lookup->IsReadOnly()) return false;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 1315
1384 if (receiver->IsJSGlobalProxy()) { 1316 if (receiver->IsJSGlobalProxy()) {
1385 // TODO(ulan): find out why we patch this site even with --no-use-ic 1317 // TODO(ulan): find out why we patch this site even with --no-use-ic
1386 // Generate a generic stub that goes to the runtime when we see a global 1318 // Generate a generic stub that goes to the runtime when we see a global
1387 // proxy as receiver. 1319 // proxy as receiver.
1388 Handle<Code> stub = (strict_mode == kStrictMode) 1320 Handle<Code> stub = (strict_mode == kStrictMode)
1389 ? global_proxy_stub_strict() 1321 ? global_proxy_stub_strict()
1390 : global_proxy_stub(); 1322 : global_proxy_stub();
1391 if (target() != *stub) { 1323 if (target() != *stub) {
1392 set_target(*stub); 1324 set_target(*stub);
1393 #ifdef DEBUG 1325 TRACE_IC("StoreIC", name, state, target());
1394 TraceIC("StoreIC", name, state, target());
1395 #endif
1396 } 1326 }
1397 } 1327 }
1398 1328
1399 // Set the property. 1329 // Set the property.
1400 return receiver->SetProperty(*name, *value, NONE, strict_mode); 1330 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1401 } 1331 }
1402 1332
1403 1333
1404 void StoreIC::UpdateCaches(LookupResult* lookup, 1334 void StoreIC::UpdateCaches(LookupResult* lookup,
1405 State state, 1335 State state,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 if (target() != *code) { 1409 if (target() != *code) {
1480 set_target((strict_mode == kStrictMode) 1410 set_target((strict_mode == kStrictMode)
1481 ? megamorphic_stub_strict() 1411 ? megamorphic_stub_strict()
1482 : megamorphic_stub()); 1412 : megamorphic_stub());
1483 } 1413 }
1484 } else if (state == MEGAMORPHIC) { 1414 } else if (state == MEGAMORPHIC) {
1485 // Update the stub cache. 1415 // Update the stub cache.
1486 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 1416 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1487 } 1417 }
1488 1418
1489 #ifdef DEBUG 1419 TRACE_IC("StoreIC", name, state, target());
1490 TraceIC("StoreIC", name, state, target());
1491 #endif
1492 } 1420 }
1493 1421
1494 1422
1495 static bool AddOneReceiverMapIfMissing(MapList* receiver_maps, 1423 static bool AddOneReceiverMapIfMissing(MapList* receiver_maps,
1496 Map* new_receiver_map) { 1424 Map* new_receiver_map) {
1497 for (int current = 0; current < receiver_maps->length(); ++current) { 1425 for (int current = 0; current < receiver_maps->length(); ++current) {
1498 if (receiver_maps->at(current) == new_receiver_map) { 1426 if (receiver_maps->at(current) == new_receiver_map) {
1499 return false; 1427 return false;
1500 } 1428 }
1501 } 1429 }
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 strict_mode, 1718 strict_mode,
1791 stub); 1719 stub);
1792 stub = maybe_stub->IsFailure() ? 1720 stub = maybe_stub->IsFailure() ?
1793 NULL : Code::cast(maybe_stub->ToObjectUnchecked()); 1721 NULL : Code::cast(maybe_stub->ToObjectUnchecked());
1794 } 1722 }
1795 } 1723 }
1796 } 1724 }
1797 if (stub != NULL) set_target(stub); 1725 if (stub != NULL) set_target(stub);
1798 } 1726 }
1799 1727
1800 #ifdef DEBUG 1728 TRACE_IC("KeyedStoreIC", key, state, target());
1801 TraceIC("KeyedStoreIC", key, state, target());
1802 #endif
1803 1729
1804 // Set the property. 1730 // Set the property.
1805 return Runtime::SetObjectProperty( 1731 return Runtime::SetObjectProperty(
1806 isolate(), object , key, value, NONE, strict_mode); 1732 isolate(), object , key, value, NONE, strict_mode);
1807 } 1733 }
1808 1734
1809 1735
1810 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, 1736 void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
1811 State state, 1737 State state,
1812 StrictModeFlag strict_mode, 1738 StrictModeFlag strict_mode,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 // sure to always rewrite from monomorphic to megamorphic. 1796 // sure to always rewrite from monomorphic to megamorphic.
1871 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); 1797 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1872 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { 1798 if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1873 set_target(Code::cast(code)); 1799 set_target(Code::cast(code));
1874 } else if (state == MONOMORPHIC) { 1800 } else if (state == MONOMORPHIC) {
1875 set_target((strict_mode == kStrictMode) 1801 set_target((strict_mode == kStrictMode)
1876 ? megamorphic_stub_strict() 1802 ? megamorphic_stub_strict()
1877 : megamorphic_stub()); 1803 : megamorphic_stub());
1878 } 1804 }
1879 1805
1880 #ifdef DEBUG 1806 TRACE_IC("KeyedStoreIC", name, state, target());
1881 TraceIC("KeyedStoreIC", name, state, target());
1882 #endif
1883 } 1807 }
1884 1808
1885 1809
1810 #undef TRACE_IC
1811
1812
1886 // ---------------------------------------------------------------------------- 1813 // ----------------------------------------------------------------------------
1887 // Static IC stub generators. 1814 // Static IC stub generators.
1888 // 1815 //
1889 1816
1890 // Used from ic-<arch>.cc. 1817 // Used from ic-<arch>.cc.
1891 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { 1818 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
1892 HandleScope scope(isolate); 1819 HandleScope scope(isolate);
1893 ASSERT(args.length() == 2); 1820 ASSERT(args.length() == 2);
1894 CallIC ic(isolate); 1821 CallIC ic(isolate);
1895 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1822 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 #undef ADDR 2424 #undef ADDR
2498 }; 2425 };
2499 2426
2500 2427
2501 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2428 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2502 return IC_utilities[id]; 2429 return IC_utilities[id];
2503 } 2430 }
2504 2431
2505 2432
2506 } } // namespace v8::internal 2433 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698