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

Side by Side Diff: src/ic.cc

Issue 25228005: Encapsulate IC::State into the IC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 if (mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 65 if (mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
66 return ".IGNORE_OOB"; 66 return ".IGNORE_OOB";
67 } 67 }
68 if (IsGrowStoreMode(mode)) return ".GROW"; 68 if (IsGrowStoreMode(mode)) return ".GROW";
69 return ""; 69 return "";
70 } 70 }
71 71
72 72
73 void IC::TraceIC(const char* type, 73 void IC::TraceIC(const char* type,
74 Handle<Object> name, 74 Handle<Object> name,
75 State old_state,
76 Code* new_target) { 75 Code* new_target) {
77 if (FLAG_trace_ic) { 76 if (FLAG_trace_ic) {
78 Object* undef = new_target->GetHeap()->undefined_value(); 77 State new_state = new_target->ic_state();
79 State new_state = StateFrom(new_target, undef, undef);
80 PrintF("[%s in ", type); 78 PrintF("[%s in ", type);
81 Isolate* isolate = new_target->GetIsolate(); 79 Isolate* isolate = new_target->GetIsolate();
82 StackFrameIterator it(isolate); 80 StackFrameIterator it(isolate);
83 while (it.frame()->fp() != this->fp()) it.Advance(); 81 while (it.frame()->fp() != this->fp()) it.Advance();
84 StackFrame* raw_frame = it.frame(); 82 StackFrame* raw_frame = it.frame();
85 if (raw_frame->is_internal()) { 83 if (raw_frame->is_internal()) {
86 Code* apply_builtin = isolate->builtins()->builtin( 84 Code* apply_builtin = isolate->builtins()->builtin(
87 Builtins::kFunctionApply); 85 Builtins::kFunctionApply);
88 if (raw_frame->unchecked_code() == apply_builtin) { 86 if (raw_frame->unchecked_code() == apply_builtin) {
89 PrintF("apply from "); 87 PrintF("apply from ");
90 it.Advance(); 88 it.Advance();
91 raw_frame = it.frame(); 89 raw_frame = it.frame();
92 } 90 }
93 } 91 }
94 JavaScriptFrame::PrintTop(isolate, stdout, false, true); 92 JavaScriptFrame::PrintTop(isolate, stdout, false, true);
95 Code::ExtraICState state = new_target->extra_ic_state(); 93 Code::ExtraICState extra_state = new_target->extra_ic_state();
96 const char* modifier = 94 const char* modifier =
97 GetTransitionMarkModifier(Code::GetKeyedAccessStoreMode(state)); 95 GetTransitionMarkModifier(Code::GetKeyedAccessStoreMode(extra_state));
98 PrintF(" (%c->%c%s)", 96 PrintF(" (%c->%c%s)",
99 TransitionMarkFromState(old_state), 97 TransitionMarkFromState(state()),
100 TransitionMarkFromState(new_state), 98 TransitionMarkFromState(new_state),
101 modifier); 99 modifier);
102 name->Print(); 100 name->Print();
103 PrintF("]\n"); 101 PrintF("]\n");
104 } 102 }
105 } 103 }
106 104
107 #define TRACE_GENERIC_IC(isolate, type, reason) \ 105 #define TRACE_GENERIC_IC(isolate, type, reason) \
108 do { \ 106 do { \
109 if (FLAG_trace_ic) { \ 107 if (FLAG_trace_ic) { \
110 PrintF("[%s patching generic stub in ", type); \ 108 PrintF("[%s patching generic stub in ", type); \
111 JavaScriptFrame::PrintTop(isolate, stdout, false, true); \ 109 JavaScriptFrame::PrintTop(isolate, stdout, false, true); \
112 PrintF(" (%s)]\n", reason); \ 110 PrintF(" (%s)]\n", reason); \
113 } \ 111 } \
114 } while (false) 112 } while (false)
115 113
116 #else 114 #else
117 #define TRACE_GENERIC_IC(isolate, type, reason) 115 #define TRACE_GENERIC_IC(isolate, type, reason)
118 #endif // DEBUG 116 #endif // DEBUG
119 117
120 #define TRACE_IC(type, name, old_state, new_target) \ 118 #define TRACE_IC(type, name, new_target) \
121 ASSERT((TraceIC(type, name, old_state, *new_target), true)) 119 ASSERT((TraceIC(type, name, *new_target), true))
122 120
123 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { 121 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
124 // To improve the performance of the (much used) IC code, we unfold a few 122 // To improve the performance of the (much used) IC code, we unfold a few
125 // levels of the stack frame iteration code. This yields a ~35% speedup when 123 // levels of the stack frame iteration code. This yields a ~35% speedup when
126 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. 124 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
127 const Address entry = 125 const Address entry =
128 Isolate::c_entry_fp(isolate->thread_local_top()); 126 Isolate::c_entry_fp(isolate->thread_local_top());
129 Address* pc_address = 127 Address* pc_address =
130 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); 128 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
131 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 129 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
132 // If there's another JavaScript frame on the stack or a 130 // If there's another JavaScript frame on the stack or a
133 // StubFailureTrampoline, we need to look one frame further down the stack to 131 // StubFailureTrampoline, we need to look one frame further down the stack to
134 // find the frame pointer and the return address stack slot. 132 // find the frame pointer and the return address stack slot.
135 if (depth == EXTRA_CALL_FRAME) { 133 if (depth == EXTRA_CALL_FRAME) {
136 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; 134 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset;
137 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); 135 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset);
138 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); 136 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
139 } 137 }
140 #ifdef DEBUG 138 #ifdef DEBUG
141 StackFrameIterator it(isolate); 139 StackFrameIterator it(isolate);
142 for (int i = 0; i < depth + 1; i++) it.Advance(); 140 for (int i = 0; i < depth + 1; i++) it.Advance();
143 StackFrame* frame = it.frame(); 141 StackFrame* frame = it.frame();
144 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); 142 ASSERT(fp == frame->fp() && pc_address == frame->pc_address());
145 #endif 143 #endif
146 fp_ = fp; 144 fp_ = fp;
147 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); 145 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
148 target_ = handle(raw_target(), isolate); 146 target_ = handle(raw_target(), isolate);
147 state_ = target_->ic_state();
149 } 148 }
150 149
151 150
152 #ifdef ENABLE_DEBUGGER_SUPPORT 151 #ifdef ENABLE_DEBUGGER_SUPPORT
153 Address IC::OriginalCodeAddress() const { 152 Address IC::OriginalCodeAddress() const {
154 HandleScope scope(isolate()); 153 HandleScope scope(isolate());
155 // Compute the JavaScript frame for the frame pointer of this IC 154 // Compute the JavaScript frame for the frame pointer of this IC
156 // structure. We need this to be able to find the function 155 // structure. We need this to be able to find the function
157 // corresponding to the frame. 156 // corresponding to the frame.
158 StackFrameIterator it(isolate()); 157 StackFrameIterator it(isolate());
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 global->LocalLookupRealNamedProperty(Name::cast(name), &lookup); 254 global->LocalLookupRealNamedProperty(Name::cast(name), &lookup);
256 if (!lookup.IsFound()) return false; 255 if (!lookup.IsFound()) return false;
257 PropertyCell* cell = global->GetPropertyCell(&lookup); 256 PropertyCell* cell = global->GetPropertyCell(&lookup);
258 return cell->type()->IsConstant(); 257 return cell->type()->IsConstant();
259 } 258 }
260 259
261 return false; 260 return false;
262 } 261 }
263 262
264 263
265 IC::State IC::StateFrom(Code* target, Object* receiver, Object* name) { 264 void IC::UpdateState(Object* receiver, Object* name) {
266 IC::State state = target->ic_state(); 265 if (state() != MONOMORPHIC || !name->IsString()) return;
266 if (receiver->IsUndefined() || receiver->IsNull()) return;
267 267
268 if (state != MONOMORPHIC || !name->IsString()) return state; 268 Code::Kind kind = target()->kind();
269 if (receiver->IsUndefined() || receiver->IsNull()) return state;
270
271 Code::Kind kind = target->kind();
272 // Remove the target from the code cache if it became invalid 269 // Remove the target from the code cache if it became invalid
273 // because of changes in the prototype chain to avoid hitting it 270 // because of changes in the prototype chain to avoid hitting it
274 // again. 271 // again.
275 // Call stubs handle this later to allow extra IC state 272 // Call stubs handle this later to allow extra IC state
276 // transitions. 273 // transitions.
277 if (kind != Code::CALL_IC && kind != Code::KEYED_CALL_IC && 274 if (kind != Code::CALL_IC && kind != Code::KEYED_CALL_IC &&
278 TryRemoveInvalidPrototypeDependentStub(target, receiver, name)) { 275 TryRemoveInvalidPrototypeDependentStub(*target_, receiver, name)) {
279 return MONOMORPHIC_PROTOTYPE_FAILURE; 276 MarkMonomorphicPrototypeFailure();
277 return;
280 } 278 }
281 279
282 // The builtins object is special. It only changes when JavaScript 280 // The builtins object is special. It only changes when JavaScript
283 // builtins are loaded lazily. It is important to keep inline 281 // builtins are loaded lazily. It is important to keep inline
284 // caches for the builtins object monomorphic. Therefore, if we get 282 // caches for the builtins object monomorphic. Therefore, if we get
285 // an inline cache miss for the builtins object after lazily loading 283 // an inline cache miss for the builtins object after lazily loading
286 // JavaScript builtins, we return uninitialized as the state to 284 // JavaScript builtins, we return uninitialized as the state to
287 // force the inline cache back to monomorphic state. 285 // force the inline cache back to monomorphic state.
288 if (receiver->IsJSBuiltinsObject()) { 286 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED;
289 return UNINITIALIZED;
290 }
291
292 return MONOMORPHIC;
293 } 287 }
294 288
295 289
296 RelocInfo::Mode IC::ComputeMode() { 290 RelocInfo::Mode IC::ComputeMode() {
297 Address addr = address(); 291 Address addr = address();
298 Code* code = Code::cast(isolate()->FindCodeObject(addr)); 292 Code* code = Code::cast(isolate()->FindCodeObject(addr));
299 for (RelocIterator it(code, RelocInfo::kCodeTargetMask); 293 for (RelocIterator it(code, RelocInfo::kCodeTargetMask);
300 !it.done(); it.next()) { 294 !it.done(); it.next()) {
301 RelocInfo* info = it.rinfo(); 295 RelocInfo* info = it.rinfo();
302 if (info->pc() == addr) return info->rmode(); 296 if (info->pc() == addr) return info->rmode();
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 // Change the receiver to the result of calling ToObject on it. 526 // Change the receiver to the result of calling ToObject on it.
533 const int argc = this->target()->arguments_count(); 527 const int argc = this->target()->arguments_count();
534 StackFrameLocator locator(isolate()); 528 StackFrameLocator locator(isolate());
535 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 529 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
536 int index = frame->ComputeExpressionsCount() - (argc + 1); 530 int index = frame->ComputeExpressionsCount() - (argc + 1);
537 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); 531 frame->SetExpression(index, *isolate()->factory()->ToObject(object));
538 } 532 }
539 } 533 }
540 534
541 535
542 MaybeObject* CallICBase::LoadFunction(State state, 536 MaybeObject* CallICBase::LoadFunction(Code::ExtraICState extra_ic_state,
543 Code::ExtraICState extra_ic_state,
544 Handle<Object> object, 537 Handle<Object> object,
545 Handle<String> name) { 538 Handle<String> name) {
546 bool use_ic = FLAG_use_ic; 539 bool use_ic = FLAG_use_ic;
547 if (object->IsJSObject()) { 540 if (object->IsJSObject()) {
548 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 541 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
549 if (receiver->map()->is_deprecated()) { 542 if (receiver->map()->is_deprecated()) {
550 use_ic = false; 543 use_ic = false;
551 JSObject::MigrateInstance(receiver); 544 JSObject::MigrateInstance(receiver);
552 } 545 }
553 } 546 }
(...skipping 25 matching lines...) Expand all
579 572
580 if (!lookup.IsFound()) { 573 if (!lookup.IsFound()) {
581 // If the object does not have the requested property, check which 574 // If the object does not have the requested property, check which
582 // exception we need to throw. 575 // exception we need to throw.
583 return IsUndeclaredGlobal(object) 576 return IsUndeclaredGlobal(object)
584 ? ReferenceError("not_defined", name) 577 ? ReferenceError("not_defined", name)
585 : TypeError("undefined_method", object, name); 578 : TypeError("undefined_method", object, name);
586 } 579 }
587 580
588 // Lookup is valid: Update inline cache and stub cache. 581 // Lookup is valid: Update inline cache and stub cache.
589 if (use_ic) UpdateCaches(&lookup, state, extra_ic_state, object, name); 582 if (use_ic) UpdateCaches(&lookup, extra_ic_state, object, name);
590 583
591 // Get the property. 584 // Get the property.
592 PropertyAttributes attr; 585 PropertyAttributes attr;
593 Handle<Object> result = 586 Handle<Object> result =
594 Object::GetProperty(object, object, &lookup, name, &attr); 587 Object::GetProperty(object, object, &lookup, name, &attr);
595 RETURN_IF_EMPTY_HANDLE(isolate(), result); 588 RETURN_IF_EMPTY_HANDLE(isolate(), result);
596 589
597 if (lookup.IsInterceptor() && attr == ABSENT) { 590 if (lookup.IsInterceptor() && attr == ABSENT) {
598 // If the object does not have the requested property, check which 591 // If the object does not have the requested property, check which
599 // exception we need to throw. 592 // exception we need to throw.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 } 662 }
670 break; 663 break;
671 default: 664 default:
672 return false; 665 return false;
673 } 666 }
674 return false; 667 return false;
675 } 668 }
676 669
677 670
678 Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, 671 Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
679 State state,
680 Code::ExtraICState extra_state, 672 Code::ExtraICState extra_state,
681 Handle<Object> object, 673 Handle<Object> object,
682 Handle<String> name) { 674 Handle<String> name) {
683 int argc = target()->arguments_count(); 675 int argc = target()->arguments_count();
684 Handle<JSObject> holder(lookup->holder(), isolate()); 676 Handle<JSObject> holder(lookup->holder(), isolate());
685 switch (lookup->type()) { 677 switch (lookup->type()) {
686 case FIELD: { 678 case FIELD: {
687 PropertyIndex index = lookup->GetFieldIndex(); 679 PropertyIndex index = lookup->GetFieldIndex();
688 return isolate()->stub_cache()->ComputeCallField( 680 return isolate()->stub_cache()->ComputeCallField(
689 argc, kind_, extra_state, name, object, holder, index); 681 argc, kind_, extra_state, name, object, holder, index);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 ASSERT(HasInterceptorGetter(*holder)); 717 ASSERT(HasInterceptorGetter(*holder));
726 return isolate()->stub_cache()->ComputeCallInterceptor( 718 return isolate()->stub_cache()->ComputeCallInterceptor(
727 argc, kind_, extra_state, name, object, holder); 719 argc, kind_, extra_state, name, object, holder);
728 default: 720 default:
729 return Handle<Code>::null(); 721 return Handle<Code>::null();
730 } 722 }
731 } 723 }
732 724
733 725
734 void CallICBase::UpdateCaches(LookupResult* lookup, 726 void CallICBase::UpdateCaches(LookupResult* lookup,
735 State state,
736 Code::ExtraICState extra_ic_state, 727 Code::ExtraICState extra_ic_state,
737 Handle<Object> object, 728 Handle<Object> object,
738 Handle<String> name) { 729 Handle<String> name) {
739 // Bail out if we didn't find a result. 730 // Bail out if we didn't find a result.
740 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 731 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
741 732
742 // Compute the number of arguments. 733 // Compute the number of arguments.
743 int argc = target()->arguments_count(); 734 int argc = target()->arguments_count();
744 Handle<Code> code; 735 Handle<Code> code;
745 if (state == UNINITIALIZED) { 736 if (state() == UNINITIALIZED) {
746 // This is the first time we execute this inline cache. 737 // This is the first time we execute this inline cache.
747 // Set the target to the pre monomorphic stub to delay 738 // Set the target to the pre monomorphic stub to delay
748 // setting the monomorphic state. 739 // setting the monomorphic state.
749 code = isolate()->stub_cache()->ComputeCallPreMonomorphic( 740 code = isolate()->stub_cache()->ComputeCallPreMonomorphic(
750 argc, kind_, extra_ic_state); 741 argc, kind_, extra_ic_state);
751 } else if (state == MONOMORPHIC) { 742 } else if (state() == MONOMORPHIC) {
752 if (kind_ == Code::CALL_IC && 743 if (kind_ == Code::CALL_IC &&
753 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { 744 TryUpdateExtraICState(lookup, object, &extra_ic_state)) {
754 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, 745 code = ComputeMonomorphicStub(lookup, extra_ic_state, object, name);
755 object, name);
756 } else if (TryRemoveInvalidPrototypeDependentStub(*target(), 746 } else if (TryRemoveInvalidPrototypeDependentStub(*target(),
757 *object, 747 *object,
758 *name)) { 748 *name)) {
759 state = MONOMORPHIC_PROTOTYPE_FAILURE; 749 MarkMonomorphicPrototypeFailure();
760 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, 750 code = ComputeMonomorphicStub(lookup, extra_ic_state, object, name);
761 object, name);
762 } else { 751 } else {
763 code = isolate()->stub_cache()->ComputeCallMegamorphic( 752 code = isolate()->stub_cache()->ComputeCallMegamorphic(
764 argc, kind_, extra_ic_state); 753 argc, kind_, extra_ic_state);
765 } 754 }
766 } else { 755 } else {
767 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, 756 code = ComputeMonomorphicStub(lookup, extra_ic_state, object, name);
768 object, name);
769 } 757 }
770 758
771 // If there's no appropriate stub we simply avoid updating the caches. 759 // If there's no appropriate stub we simply avoid updating the caches.
772 if (code.is_null()) return; 760 if (code.is_null()) return;
773 761
774 // Patch the call site depending on the state of the cache. 762 // Patch the call site depending on the state of the cache.
775 switch (state) { 763 switch (state()) {
776 case UNINITIALIZED: 764 case UNINITIALIZED:
777 case MONOMORPHIC_PROTOTYPE_FAILURE: 765 case MONOMORPHIC_PROTOTYPE_FAILURE:
778 case PREMONOMORPHIC: 766 case PREMONOMORPHIC:
779 case MONOMORPHIC: 767 case MONOMORPHIC:
780 set_target(*code); 768 set_target(*code);
781 break; 769 break;
782 case MEGAMORPHIC: { 770 case MEGAMORPHIC: {
783 // Cache code holding map should be consistent with 771 // Cache code holding map should be consistent with
784 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. 772 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
785 Handle<JSObject> cache_object = object->IsJSObject() 773 Handle<JSObject> cache_object = object->IsJSObject()
786 ? Handle<JSObject>::cast(object) 774 ? Handle<JSObject>::cast(object)
787 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())), 775 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())),
788 isolate()); 776 isolate());
789 // Update the stub cache. 777 // Update the stub cache.
790 UpdateMegamorphicCache(cache_object->map(), *name, *code); 778 UpdateMegamorphicCache(cache_object->map(), *name, *code);
791 break; 779 break;
792 } 780 }
793 case DEBUG_STUB: 781 case DEBUG_STUB:
794 break; 782 break;
795 case POLYMORPHIC: 783 case POLYMORPHIC:
796 case GENERIC: 784 case GENERIC:
797 UNREACHABLE(); 785 UNREACHABLE();
798 break; 786 break;
799 } 787 }
800 788
801 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", 789 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", name, target());
802 name, state, target());
803 } 790 }
804 791
805 792
806 MaybeObject* KeyedCallIC::LoadFunction(State state, 793 MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object,
807 Handle<Object> object,
808 Handle<Object> key) { 794 Handle<Object> key) {
809 if (key->IsInternalizedString()) { 795 if (key->IsInternalizedString()) {
810 return CallICBase::LoadFunction(state, 796 return CallICBase::LoadFunction(Code::kNoExtraICState,
811 Code::kNoExtraICState,
812 object, 797 object,
813 Handle<String>::cast(key)); 798 Handle<String>::cast(key));
814 } 799 }
815 800
816 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 801 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
817 if (object->IsJSObject()) { 802 if (object->IsJSObject()) {
818 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 803 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
819 if (receiver->map()->is_deprecated()) { 804 if (receiver->map()->is_deprecated()) {
820 use_ic = false; 805 use_ic = false;
821 JSObject::MigrateInstance(receiver); 806 JSObject::MigrateInstance(receiver);
822 } 807 }
823 } 808 }
824 809
825 if (object->IsUndefined() || object->IsNull()) { 810 if (object->IsUndefined() || object->IsNull()) {
826 return TypeError("non_object_property_call", object, key); 811 return TypeError("non_object_property_call", object, key);
827 } 812 }
828 813
829 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 814 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
830 815
831 if (use_ic && state != MEGAMORPHIC) { 816 if (use_ic && state() != MEGAMORPHIC) {
832 int argc = target()->arguments_count(); 817 int argc = target()->arguments_count();
833 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( 818 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic(
834 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 819 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
835 if (object->IsJSObject()) { 820 if (object->IsJSObject()) {
836 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 821 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
837 if (receiver->elements()->map() == 822 if (receiver->elements()->map() ==
838 isolate()->heap()->non_strict_arguments_elements_map()) { 823 isolate()->heap()->non_strict_arguments_elements_map()) {
839 stub = isolate()->stub_cache()->ComputeCallArguments(argc); 824 stub = isolate()->stub_cache()->ComputeCallArguments(argc);
840 } 825 }
841 } 826 }
842 ASSERT(!stub.is_null()); 827 ASSERT(!stub.is_null());
843 set_target(*stub); 828 set_target(*stub);
844 TRACE_IC("KeyedCallIC", key, state, target()); 829 TRACE_IC("KeyedCallIC", key, target());
845 } 830 }
846 831
847 Handle<Object> result = GetProperty(isolate(), object, key); 832 Handle<Object> result = GetProperty(isolate(), object, key);
848 RETURN_IF_EMPTY_HANDLE(isolate(), result); 833 RETURN_IF_EMPTY_HANDLE(isolate(), result);
849 834
850 // Make receiver an object if the callee requires it. Strict mode or builtin 835 // Make receiver an object if the callee requires it. Strict mode or builtin
851 // functions do not wrap the receiver, non-strict functions and objects 836 // functions do not wrap the receiver, non-strict functions and objects
852 // called as functions do. 837 // called as functions do.
853 ReceiverToObjectIfRequired(result, object); 838 ReceiverToObjectIfRequired(result, object);
854 if (result->IsJSFunction()) return *result; 839 if (result->IsJSFunction()) return *result;
855 840
856 result = TryCallAsFunction(result); 841 result = TryCallAsFunction(result);
857 if (result->IsJSFunction()) return *result; 842 if (result->IsJSFunction()) return *result;
858 843
859 return TypeError("property_not_function", object, key); 844 return TypeError("property_not_function", object, key);
860 } 845 }
861 846
862 847
863 MaybeObject* LoadIC::Load(State state, 848 MaybeObject* LoadIC::Load(Handle<Object> object,
864 Handle<Object> object,
865 Handle<String> name) { 849 Handle<String> name) {
866 // If the object is undefined or null it's illegal to try to get any 850 // If the object is undefined or null it's illegal to try to get any
867 // of its properties; throw a TypeError in that case. 851 // of its properties; throw a TypeError in that case.
868 if (object->IsUndefined() || object->IsNull()) { 852 if (object->IsUndefined() || object->IsNull()) {
869 return TypeError("non_object_property_load", object, name); 853 return TypeError("non_object_property_load", object, name);
870 } 854 }
871 855
872 bool use_ic = FLAG_use_ic; 856 bool use_ic = FLAG_use_ic;
873 857
874 if (use_ic) { 858 if (use_ic) {
875 // Use specialized code for getting the length of strings and 859 // Use specialized code for getting the length of strings and
876 // string wrapper objects. The length property of string wrapper 860 // string wrapper objects. The length property of string wrapper
877 // objects is read-only and therefore always returns the length of 861 // objects is read-only and therefore always returns the length of
878 // the underlying string value. See ECMA-262 15.5.5.1. 862 // the underlying string value. See ECMA-262 15.5.5.1.
879 if (object->IsStringWrapper() && 863 if (object->IsStringWrapper() &&
880 name->Equals(isolate()->heap()->length_string())) { 864 name->Equals(isolate()->heap()->length_string())) {
881 Handle<Code> stub; 865 Handle<Code> stub;
882 if (state == UNINITIALIZED) { 866 if (state() == UNINITIALIZED) {
883 stub = pre_monomorphic_stub(); 867 stub = pre_monomorphic_stub();
884 } else if (state == PREMONOMORPHIC || state == MONOMORPHIC) { 868 } else if (state() == PREMONOMORPHIC || state() == MONOMORPHIC) {
885 StringLengthStub string_length_stub(kind()); 869 StringLengthStub string_length_stub(kind());
886 stub = string_length_stub.GetCode(isolate()); 870 stub = string_length_stub.GetCode(isolate());
887 } else if (state != MEGAMORPHIC) { 871 } else if (state() != MEGAMORPHIC) {
888 ASSERT(state != GENERIC); 872 ASSERT(state() != GENERIC);
889 stub = megamorphic_stub(); 873 stub = megamorphic_stub();
890 } 874 }
891 if (!stub.is_null()) { 875 if (!stub.is_null()) {
892 set_target(*stub); 876 set_target(*stub);
893 #ifdef DEBUG 877 #ifdef DEBUG
894 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n"); 878 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n");
895 #endif 879 #endif
896 } 880 }
897 // Get the string if we have a string wrapper object. 881 // Get the string if we have a string wrapper object.
898 String* string = String::cast(JSValue::cast(*object)->value()); 882 String* string = String::cast(JSValue::cast(*object)->value());
899 return Smi::FromInt(string->length()); 883 return Smi::FromInt(string->length());
900 } 884 }
901 885
902 // Use specialized code for getting prototype of functions. 886 // Use specialized code for getting prototype of functions.
903 if (object->IsJSFunction() && 887 if (object->IsJSFunction() &&
904 name->Equals(isolate()->heap()->prototype_string()) && 888 name->Equals(isolate()->heap()->prototype_string()) &&
905 Handle<JSFunction>::cast(object)->should_have_prototype()) { 889 Handle<JSFunction>::cast(object)->should_have_prototype()) {
906 Handle<Code> stub; 890 Handle<Code> stub;
907 if (state == UNINITIALIZED) { 891 if (state() == UNINITIALIZED) {
908 stub = pre_monomorphic_stub(); 892 stub = pre_monomorphic_stub();
909 } else if (state == PREMONOMORPHIC) { 893 } else if (state() == PREMONOMORPHIC) {
910 FunctionPrototypeStub function_prototype_stub(kind()); 894 FunctionPrototypeStub function_prototype_stub(kind());
911 stub = function_prototype_stub.GetCode(isolate()); 895 stub = function_prototype_stub.GetCode(isolate());
912 } else if (state != MEGAMORPHIC) { 896 } else if (state() != MEGAMORPHIC) {
913 ASSERT(state != GENERIC); 897 ASSERT(state() != GENERIC);
914 stub = megamorphic_stub(); 898 stub = megamorphic_stub();
915 } 899 }
916 if (!stub.is_null()) { 900 if (!stub.is_null()) {
917 set_target(*stub); 901 set_target(*stub);
918 #ifdef DEBUG 902 #ifdef DEBUG
919 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); 903 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
920 #endif 904 #endif
921 } 905 }
922 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); 906 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object));
923 } 907 }
(...skipping 22 matching lines...) Expand all
946 930
947 // If we did not find a property, check if we need to throw an exception. 931 // If we did not find a property, check if we need to throw an exception.
948 if (!lookup.IsFound()) { 932 if (!lookup.IsFound()) {
949 if (IsUndeclaredGlobal(object)) { 933 if (IsUndeclaredGlobal(object)) {
950 return ReferenceError("not_defined", name); 934 return ReferenceError("not_defined", name);
951 } 935 }
952 LOG(isolate(), SuspectReadEvent(*name, *object)); 936 LOG(isolate(), SuspectReadEvent(*name, *object));
953 } 937 }
954 938
955 // Update inline cache and stub cache. 939 // Update inline cache and stub cache.
956 if (use_ic) UpdateCaches(&lookup, state, object, name); 940 if (use_ic) UpdateCaches(&lookup, object, name);
957 941
958 PropertyAttributes attr; 942 PropertyAttributes attr;
959 if (lookup.IsInterceptor() || lookup.IsHandler()) { 943 if (lookup.IsInterceptor() || lookup.IsHandler()) {
960 // Get the property. 944 // Get the property.
961 Handle<Object> result = 945 Handle<Object> result =
962 Object::GetProperty(object, object, &lookup, name, &attr); 946 Object::GetProperty(object, object, &lookup, name, &attr);
963 RETURN_IF_EMPTY_HANDLE(isolate(), result); 947 RETURN_IF_EMPTY_HANDLE(isolate(), result);
964 // If the property is not present, check if we need to throw an 948 // If the property is not present, check if we need to throw an
965 // exception. 949 // exception.
966 if (attr == ABSENT && IsUndeclaredGlobal(object)) { 950 if (attr == ABSENT && IsUndeclaredGlobal(object)) {
(...skipping 14 matching lines...) Expand all
981 if (!receiver_maps->at(current).is_null() && 965 if (!receiver_maps->at(current).is_null() &&
982 receiver_maps->at(current).is_identical_to(new_receiver_map)) { 966 receiver_maps->at(current).is_identical_to(new_receiver_map)) {
983 return false; 967 return false;
984 } 968 }
985 } 969 }
986 receiver_maps->Add(new_receiver_map); 970 receiver_maps->Add(new_receiver_map);
987 return true; 971 return true;
988 } 972 }
989 973
990 974
991 bool IC::UpdatePolymorphicIC(State state, 975 bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
992 Handle<HeapObject> receiver,
993 Handle<String> name, 976 Handle<String> name,
994 Handle<Code> code) { 977 Handle<Code> code) {
995 if (!code->is_handler()) return false; 978 if (!code->is_handler()) return false;
996 979
997 MapHandleList receiver_maps; 980 MapHandleList receiver_maps;
998 CodeHandleList handlers; 981 CodeHandleList handlers;
999 982
1000 int number_of_valid_maps; 983 int number_of_valid_maps;
1001 int handler_to_overwrite = -1; 984 int handler_to_overwrite = -1;
1002 Handle<Map> new_receiver_map(receiver->map()); 985 Handle<Map> new_receiver_map(receiver->map());
(...skipping 11 matching lines...) Expand all
1014 // If the receiver map is already in the polymorphic IC, this indicates 997 // If the receiver map is already in the polymorphic IC, this indicates
1015 // there was a prototoype chain failure. In that case, just overwrite the 998 // there was a prototoype chain failure. In that case, just overwrite the
1016 // handler. 999 // handler.
1017 } else if (map.is_identical_to(new_receiver_map)) { 1000 } else if (map.is_identical_to(new_receiver_map)) {
1018 number_of_valid_maps--; 1001 number_of_valid_maps--;
1019 handler_to_overwrite = i; 1002 handler_to_overwrite = i;
1020 } 1003 }
1021 } 1004 }
1022 1005
1023 if (number_of_valid_maps >= 4) return false; 1006 if (number_of_valid_maps >= 4) return false;
1024 1007 if (number_of_maps == 0) return false;
1025 // Only allow 0 maps in case target() was reset to UNINITIALIZED by the GC.
1026 // In that case, allow the IC to go back monomorphic.
1027 if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) {
1028 return false;
1029 }
1030 1008
1031 if (!target()->FindHandlers(&handlers, receiver_maps.length())) { 1009 if (!target()->FindHandlers(&handlers, receiver_maps.length())) {
1032 return false; 1010 return false;
1033 } 1011 }
1034 } 1012 }
1035 1013
1036 number_of_valid_maps++; 1014 number_of_valid_maps++;
1037 if (handler_to_overwrite >= 0) { 1015 if (handler_to_overwrite >= 0) {
1038 handlers.Set(handler_to_overwrite, code); 1016 handlers.Set(handler_to_overwrite, code);
1039 } else { 1017 } else {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 IsMoreGeneralElementsKindTransition( 1059 IsMoreGeneralElementsKindTransition(
1082 current_map->elements_kind(), receiver_elements_kind); 1060 current_map->elements_kind(), receiver_elements_kind);
1083 Map* transitioned_map = more_general_transition 1061 Map* transitioned_map = more_general_transition
1084 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) 1062 ? current_map->LookupElementsTransitionMap(receiver_elements_kind)
1085 : NULL; 1063 : NULL;
1086 1064
1087 return transitioned_map == receiver_map; 1065 return transitioned_map == receiver_map;
1088 } 1066 }
1089 1067
1090 1068
1091 void IC::PatchCache(State state, 1069 void IC::PatchCache(Handle<HeapObject> receiver,
1092 Handle<HeapObject> receiver,
1093 Handle<String> name, 1070 Handle<String> name,
1094 Handle<Code> code) { 1071 Handle<Code> code) {
1095 switch (state) { 1072 switch (state()) {
1096 case UNINITIALIZED: 1073 case UNINITIALIZED:
1097 case PREMONOMORPHIC: 1074 case PREMONOMORPHIC:
1098 case MONOMORPHIC_PROTOTYPE_FAILURE: 1075 case MONOMORPHIC_PROTOTYPE_FAILURE:
1099 UpdateMonomorphicIC(receiver, code, name); 1076 UpdateMonomorphicIC(receiver, code, name);
1100 break; 1077 break;
1101 case MONOMORPHIC: 1078 case MONOMORPHIC:
1102 ASSERT(!target().is_identical_to(code)); 1079 ASSERT(!target().is_identical_to(code));
1103 if (!target()->is_keyed_stub()) { 1080 if (!target()->is_keyed_stub()) {
1104 bool is_same_handler = false; 1081 bool is_same_handler = false;
1105 { 1082 {
1106 DisallowHeapAllocation no_allocation; 1083 DisallowHeapAllocation no_allocation;
1107 Code* old_handler = target()->FindFirstHandler(); 1084 Code* old_handler = target()->FindFirstHandler();
1108 is_same_handler = old_handler == *code; 1085 is_same_handler = old_handler == *code;
1109 } 1086 }
1110 if (is_same_handler 1087 if (is_same_handler
1111 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { 1088 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
1112 UpdateMonomorphicIC(receiver, code, name); 1089 UpdateMonomorphicIC(receiver, code, name);
1113 break; 1090 break;
1114 } 1091 }
1115 if (UpdatePolymorphicIC(state, receiver, name, code)) { 1092 if (UpdatePolymorphicIC(receiver, name, code)) {
1116 break; 1093 break;
1117 } 1094 }
1118 1095
1119 CopyICToMegamorphicCache(name); 1096 CopyICToMegamorphicCache(name);
1120 } 1097 }
1121 1098
1122 UpdateMegamorphicCache(receiver->map(), *name, *code); 1099 UpdateMegamorphicCache(receiver->map(), *name, *code);
1123 set_target(*megamorphic_stub()); 1100 set_target(*megamorphic_stub());
1124 break; 1101 break;
1125 case MEGAMORPHIC: 1102 case MEGAMORPHIC:
1126 UpdateMegamorphicCache(receiver->map(), *name, *code); 1103 UpdateMegamorphicCache(receiver->map(), *name, *code);
1127 break; 1104 break;
1128 case POLYMORPHIC: 1105 case POLYMORPHIC:
1129 if (target()->is_keyed_stub()) { 1106 if (target()->is_keyed_stub()) {
1130 // When trying to patch a polymorphic keyed stub with anything other 1107 // When trying to patch a polymorphic keyed stub with anything other
1131 // than another polymorphic stub, go generic. 1108 // than another polymorphic stub, go generic.
1132 set_target(*generic_stub()); 1109 set_target(*generic_stub());
1133 } else { 1110 } else {
1134 if (UpdatePolymorphicIC(state, receiver, name, code)) { 1111 if (UpdatePolymorphicIC(receiver, name, code)) {
1135 break; 1112 break;
1136 } 1113 }
1137 CopyICToMegamorphicCache(name); 1114 CopyICToMegamorphicCache(name);
1138 UpdateMegamorphicCache(receiver->map(), *name, *code); 1115 UpdateMegamorphicCache(receiver->map(), *name, *code);
1139 set_target(*megamorphic_stub()); 1116 set_target(*megamorphic_stub());
1140 } 1117 }
1141 break; 1118 break;
1142 case DEBUG_STUB: 1119 case DEBUG_STUB:
1143 break; 1120 break;
1144 case GENERIC: 1121 case GENERIC:
1145 UNREACHABLE(); 1122 UNREACHABLE();
1146 break; 1123 break;
1147 } 1124 }
1148 } 1125 }
1149 1126
1150 1127
1151 static void GetReceiverMapsForStub(Handle<Code> stub,
1152 MapHandleList* result) {
1153 ASSERT(stub->is_inline_cache_stub());
1154 switch (stub->ic_state()) {
1155 case MONOMORPHIC: {
1156 Map* map = stub->FindFirstMap();
1157 if (map != NULL) {
1158 result->Add(Handle<Map>(map));
1159 }
1160 break;
1161 }
1162 case POLYMORPHIC: {
1163 DisallowHeapAllocation no_allocation;
1164 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1165 for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
1166 RelocInfo* info = it.rinfo();
1167 Handle<Object> object(info->target_object(), stub->GetIsolate());
1168 if (object->IsString()) break;
1169 ASSERT(object->IsMap());
1170 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
1171 }
1172 break;
1173 }
1174 case MEGAMORPHIC:
1175 break;
1176 case UNINITIALIZED:
1177 case PREMONOMORPHIC:
1178 case MONOMORPHIC_PROTOTYPE_FAILURE:
1179 case GENERIC:
1180 case DEBUG_STUB:
1181 UNREACHABLE();
1182 break;
1183 }
1184 }
1185
1186
1187 void LoadIC::UpdateCaches(LookupResult* lookup, 1128 void LoadIC::UpdateCaches(LookupResult* lookup,
1188 State state,
1189 Handle<Object> object, 1129 Handle<Object> object,
1190 Handle<String> name) { 1130 Handle<String> name) {
1191 // TODO(verwaest): It would be nice to support loading fields from smis as 1131 // TODO(verwaest): It would be nice to support loading fields from smis as
1192 // well. For now just fail to update the cache. 1132 // well. For now just fail to update the cache.
1193 if (!object->IsHeapObject()) return; 1133 if (!object->IsHeapObject()) return;
1194 1134
1195 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object); 1135 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
1196 1136
1197 Handle<Code> code; 1137 Handle<Code> code;
1198 if (state == UNINITIALIZED) { 1138 if (state() == UNINITIALIZED) {
1199 // This is the first time we execute this inline cache. 1139 // This is the first time we execute this inline cache.
1200 // Set the target to the pre monomorphic stub to delay 1140 // Set the target to the pre monomorphic stub to delay
1201 // setting the monomorphic state. 1141 // setting the monomorphic state.
1202 code = pre_monomorphic_stub(); 1142 code = pre_monomorphic_stub();
1203 } else if (!lookup->IsCacheable()) { 1143 } else if (!lookup->IsCacheable()) {
1204 // Bail out if the result is not cacheable. 1144 // Bail out if the result is not cacheable.
1205 code = slow_stub(); 1145 code = slow_stub();
1206 } else if (object->IsString() && 1146 } else if (object->IsString() &&
1207 name->Equals(isolate()->heap()->length_string())) { 1147 name->Equals(isolate()->heap()->length_string())) {
1208 int length_index = String::kLengthOffset / kPointerSize; 1148 int length_index = String::kLengthOffset / kPointerSize;
1209 if (target()->is_load_stub()) { 1149 if (target()->is_load_stub()) {
1210 LoadFieldStub stub(true, length_index, Representation::Tagged()); 1150 LoadFieldStub stub(true, length_index, Representation::Tagged());
1211 code = stub.GetCode(isolate()); 1151 code = stub.GetCode(isolate());
1212 } else { 1152 } else {
1213 KeyedLoadFieldStub stub(true, length_index, Representation::Tagged()); 1153 KeyedLoadFieldStub stub(true, length_index, Representation::Tagged());
1214 code = stub.GetCode(isolate()); 1154 code = stub.GetCode(isolate());
1215 } 1155 }
1216 } else if (!object->IsJSObject()) { 1156 } else if (!object->IsJSObject()) {
1217 // TODO(jkummerow): It would be nice to support non-JSObjects in 1157 // TODO(jkummerow): It would be nice to support non-JSObjects in
1218 // ComputeLoadHandler, then we wouldn't need to go generic here. 1158 // ComputeLoadHandler, then we wouldn't need to go generic here.
1219 code = slow_stub(); 1159 code = slow_stub();
1220 } else { 1160 } else {
1221 code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name); 1161 code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name);
1222 if (code.is_null()) code = slow_stub(); 1162 if (code.is_null()) code = slow_stub();
1223 } 1163 }
1224 1164
1225 PatchCache(state, receiver, name, code); 1165 PatchCache(receiver, name, code);
1226 TRACE_IC("LoadIC", name, state, target()); 1166 TRACE_IC("LoadIC", name, target());
1227 } 1167 }
1228 1168
1229 1169
1230 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { 1170 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
1231 // Cache code holding map should be consistent with 1171 // Cache code holding map should be consistent with
1232 // GenerateMonomorphicCacheProbe. 1172 // GenerateMonomorphicCacheProbe.
1233 isolate()->stub_cache()->Set(name, map, code); 1173 isolate()->stub_cache()->Set(name, map, code);
1234 } 1174 }
1235 1175
1236 1176
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 } 1279 }
1340 } 1280 }
1341 } else if (key->IsUndefined()) { 1281 } else if (key->IsUndefined()) {
1342 key = isolate->factory()->undefined_string(); 1282 key = isolate->factory()->undefined_string();
1343 } 1283 }
1344 return key; 1284 return key;
1345 } 1285 }
1346 1286
1347 1287
1348 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { 1288 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
1349 State ic_state = target()->ic_state();
1350
1351 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1289 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1352 // via megamorphic stubs, since they don't have a map in their relocation info 1290 // via megamorphic stubs, since they don't have a map in their relocation info
1353 // and so the stubs can't be harvested for the object needed for a map check. 1291 // and so the stubs can't be harvested for the object needed for a map check.
1354 if (target()->type() != Code::NORMAL) { 1292 if (target()->type() != Code::NORMAL) {
1355 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); 1293 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type");
1356 return generic_stub(); 1294 return generic_stub();
1357 } 1295 }
1358 1296
1359 Handle<Map> receiver_map(receiver->map(), isolate()); 1297 Handle<Map> receiver_map(receiver->map(), isolate());
1360 MapHandleList target_receiver_maps; 1298 MapHandleList target_receiver_maps;
1361 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { 1299 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
1362 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1300 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1363 // yet will do so and stay there. 1301 // yet will do so and stay there.
1364 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1302 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1365 } 1303 }
1366 1304
1367 if (target().is_identical_to(string_stub())) { 1305 if (target().is_identical_to(string_stub())) {
1368 target_receiver_maps.Add(isolate()->factory()->string_map()); 1306 target_receiver_maps.Add(isolate()->factory()->string_map());
1369 } else { 1307 } else {
1370 GetReceiverMapsForStub(target(), &target_receiver_maps); 1308 target()->FindAllMaps(&target_receiver_maps);
1371 if (target_receiver_maps.length() == 0) { 1309 if (target_receiver_maps.length() == 0) {
1372 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1310 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1373 } 1311 }
1374 } 1312 }
1375 1313
1376 // The first time a receiver is seen that is a transitioned version of the 1314 // The first time a receiver is seen that is a transitioned version of the
1377 // previous monomorphic receiver type, assume the new ElementsKind is the 1315 // previous monomorphic receiver type, assume the new ElementsKind is the
1378 // monomorphic type. This benefits global arrays that only transition 1316 // monomorphic type. This benefits global arrays that only transition
1379 // once, and all call sites accessing them are faster if they remain 1317 // once, and all call sites accessing them are faster if they remain
1380 // monomorphic. If this optimistic assumption is not true, the IC will 1318 // monomorphic. If this optimistic assumption is not true, the IC will
1381 // miss again and it will become polymorphic and support both the 1319 // miss again and it will become polymorphic and support both the
1382 // untransitioned and transitioned maps. 1320 // untransitioned and transitioned maps.
1383 if (ic_state == MONOMORPHIC && 1321 if (state() == MONOMORPHIC &&
1384 IsMoreGeneralElementsKindTransition( 1322 IsMoreGeneralElementsKindTransition(
1385 target_receiver_maps.at(0)->elements_kind(), 1323 target_receiver_maps.at(0)->elements_kind(),
1386 receiver->GetElementsKind())) { 1324 receiver->GetElementsKind())) {
1387 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1325 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1388 } 1326 }
1389 1327
1390 ASSERT(ic_state != GENERIC); 1328 ASSERT(state() != GENERIC);
1391 1329
1392 // Determine the list of receiver maps that this call site has seen, 1330 // Determine the list of receiver maps that this call site has seen,
1393 // adding the map that was just encountered. 1331 // adding the map that was just encountered.
1394 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1332 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
1395 // If the miss wasn't due to an unseen map, a polymorphic stub 1333 // If the miss wasn't due to an unseen map, a polymorphic stub
1396 // won't help, use the generic stub. 1334 // won't help, use the generic stub.
1397 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); 1335 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice");
1398 return generic_stub(); 1336 return generic_stub();
1399 } 1337 }
1400 1338
1401 // If the maximum number of receiver maps has been exceeded, use the generic 1339 // If the maximum number of receiver maps has been exceeded, use the generic
1402 // version of the IC. 1340 // version of the IC.
1403 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1341 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1404 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1342 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded");
1405 return generic_stub(); 1343 return generic_stub();
1406 } 1344 }
1407 1345
1408 return isolate()->stub_cache()->ComputeLoadElementPolymorphic( 1346 return isolate()->stub_cache()->ComputeLoadElementPolymorphic(
1409 &target_receiver_maps); 1347 &target_receiver_maps);
1410 } 1348 }
1411 1349
1412 1350
1413 MaybeObject* KeyedLoadIC::Load(State state, 1351 MaybeObject* KeyedLoadIC::Load(Handle<Object> object,
1414 Handle<Object> object,
1415 Handle<Object> key, 1352 Handle<Object> key,
1416 ICMissMode miss_mode) { 1353 ICMissMode miss_mode) {
1417 // Check for values that can be converted into an internalized string directly 1354 // Check for values that can be converted into an internalized string directly
1418 // or is representable as a smi. 1355 // or is representable as a smi.
1419 key = TryConvertKey(key, isolate()); 1356 key = TryConvertKey(key, isolate());
1420 1357
1421 if (key->IsInternalizedString()) { 1358 if (key->IsInternalizedString()) {
1422 return LoadIC::Load(state, object, Handle<String>::cast(key)); 1359 return LoadIC::Load(object, Handle<String>::cast(key));
1423 } 1360 }
1424 1361
1425 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 1362 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
1426 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 1363 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
1427 1364
1428 if (use_ic) { 1365 if (use_ic) {
1429 Handle<Code> stub = generic_stub(); 1366 Handle<Code> stub = generic_stub();
1430 if (miss_mode != MISS_FORCE_GENERIC) { 1367 if (miss_mode != MISS_FORCE_GENERIC) {
1431 if (object->IsString() && key->IsNumber()) { 1368 if (object->IsString() && key->IsNumber()) {
1432 if (state == UNINITIALIZED) { 1369 if (state() == UNINITIALIZED) {
1433 stub = string_stub(); 1370 stub = string_stub();
1434 } 1371 }
1435 } else if (object->IsJSObject()) { 1372 } else if (object->IsJSObject()) {
1436 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1373 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1437 if (receiver->map()->is_deprecated()) { 1374 if (receiver->map()->is_deprecated()) {
1438 use_ic = false; 1375 use_ic = false;
1439 JSObject::MigrateInstance(receiver); 1376 JSObject::MigrateInstance(receiver);
1440 } 1377 }
1441 1378
1442 if (receiver->elements()->map() == 1379 if (receiver->elements()->map() ==
1443 isolate()->heap()->non_strict_arguments_elements_map()) { 1380 isolate()->heap()->non_strict_arguments_elements_map()) {
1444 stub = non_strict_arguments_stub(); 1381 stub = non_strict_arguments_stub();
1445 } else if (receiver->HasIndexedInterceptor()) { 1382 } else if (receiver->HasIndexedInterceptor()) {
1446 stub = indexed_interceptor_stub(); 1383 stub = indexed_interceptor_stub();
1447 } else if (!key->ToSmi()->IsFailure() && 1384 } else if (!key->ToSmi()->IsFailure() &&
1448 (!target().is_identical_to(non_strict_arguments_stub()))) { 1385 (!target().is_identical_to(non_strict_arguments_stub()))) {
1449 stub = LoadElementStub(receiver); 1386 stub = LoadElementStub(receiver);
1450 } 1387 }
1451 } 1388 }
1452 } else { 1389 } else {
1453 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic"); 1390 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic");
1454 } 1391 }
1455 if (use_ic) { 1392 if (use_ic) {
1456 ASSERT(!stub.is_null()); 1393 ASSERT(!stub.is_null());
1457 set_target(*stub); 1394 set_target(*stub);
1458 TRACE_IC("KeyedLoadIC", key, state, target()); 1395 TRACE_IC("KeyedLoadIC", key, target());
1459 } 1396 }
1460 } 1397 }
1461 1398
1462 1399
1463 return Runtime::GetObjectPropertyOrFail(isolate(), object, key); 1400 return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
1464 } 1401 }
1465 1402
1466 1403
1467 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, 1404 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
1468 Handle<JSObject> receiver, 1405 Handle<JSObject> receiver,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 return generic_stub(); 1459 return generic_stub();
1523 } 1460 }
1524 return Handle<Code>::null(); 1461 return Handle<Code>::null();
1525 } 1462 }
1526 1463
1527 1464
1528 static bool LookupForWrite(Handle<JSObject> receiver, 1465 static bool LookupForWrite(Handle<JSObject> receiver,
1529 Handle<String> name, 1466 Handle<String> name,
1530 Handle<Object> value, 1467 Handle<Object> value,
1531 LookupResult* lookup, 1468 LookupResult* lookup,
1532 IC::State* state) { 1469 IC* ic) {
1533 Handle<JSObject> holder = receiver; 1470 Handle<JSObject> holder = receiver;
1534 receiver->Lookup(*name, lookup); 1471 receiver->Lookup(*name, lookup);
1535 if (lookup->IsFound()) { 1472 if (lookup->IsFound()) {
1536 if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false; 1473 if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false;
1537 1474
1538 if (lookup->holder() == *receiver) { 1475 if (lookup->holder() == *receiver) {
1539 if (lookup->IsInterceptor() && 1476 if (lookup->IsInterceptor() &&
1540 receiver->GetNamedInterceptor()->setter()->IsUndefined()) { 1477 receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
1541 receiver->LocalLookupRealNamedProperty(*name, lookup); 1478 receiver->LocalLookupRealNamedProperty(*name, lookup);
1542 return lookup->IsFound() && 1479 return lookup->IsFound() &&
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 ASSERT(!receiver->map()->is_deprecated()); 1513 ASSERT(!receiver->map()->is_deprecated());
1577 if (!value->FitsRepresentation(target_details.representation())) { 1514 if (!value->FitsRepresentation(target_details.representation())) {
1578 Handle<Map> target(lookup->GetTransitionMapFromMap(receiver->map())); 1515 Handle<Map> target(lookup->GetTransitionMapFromMap(receiver->map()));
1579 Map::GeneralizeRepresentation( 1516 Map::GeneralizeRepresentation(
1580 target, target->LastAdded(), 1517 target, target->LastAdded(),
1581 value->OptimalRepresentation(), FORCE_FIELD); 1518 value->OptimalRepresentation(), FORCE_FIELD);
1582 // Lookup the transition again since the transition tree may have changed 1519 // Lookup the transition again since the transition tree may have changed
1583 // entirely by the migration above. 1520 // entirely by the migration above.
1584 receiver->map()->LookupTransition(*holder, *name, lookup); 1521 receiver->map()->LookupTransition(*holder, *name, lookup);
1585 if (!lookup->IsTransition()) return false; 1522 if (!lookup->IsTransition()) return false;
1586 *state = MONOMORPHIC_PROTOTYPE_FAILURE; 1523 ic->MarkMonomorphicPrototypeFailure();
1587 } 1524 }
1588 return true; 1525 return true;
1589 } 1526 }
1590 1527
1591 1528
1592 MaybeObject* StoreIC::Store(State state, 1529 MaybeObject* StoreIC::Store(Handle<Object> object,
1593 Handle<Object> object,
1594 Handle<String> name, 1530 Handle<String> name,
1595 Handle<Object> value, 1531 Handle<Object> value,
1596 JSReceiver::StoreFromKeyed store_mode) { 1532 JSReceiver::StoreFromKeyed store_mode) {
1597 // Handle proxies. 1533 // Handle proxies.
1598 if (object->IsJSProxy()) { 1534 if (object->IsJSProxy()) {
1599 Handle<Object> result = JSReceiver::SetProperty( 1535 Handle<Object> result = JSReceiver::SetProperty(
1600 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode()); 1536 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode());
1601 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1537 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1602 return *result; 1538 return *result;
1603 } 1539 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1649 // to have fast properties but a read-only length. 1585 // to have fast properties but a read-only length.
1650 if (use_ic && 1586 if (use_ic &&
1651 receiver->IsJSArray() && 1587 receiver->IsJSArray() &&
1652 name->Equals(isolate()->heap()->length_string()) && 1588 name->Equals(isolate()->heap()->length_string()) &&
1653 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && 1589 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
1654 receiver->HasFastProperties() && 1590 receiver->HasFastProperties() &&
1655 !receiver->map()->is_frozen()) { 1591 !receiver->map()->is_frozen()) {
1656 Handle<Code> stub = 1592 Handle<Code> stub =
1657 StoreArrayLengthStub(kind(), strict_mode()).GetCode(isolate()); 1593 StoreArrayLengthStub(kind(), strict_mode()).GetCode(isolate());
1658 set_target(*stub); 1594 set_target(*stub);
1659 TRACE_IC("StoreIC", name, state, stub); 1595 TRACE_IC("StoreIC", name, stub);
1660 Handle<Object> result = JSReceiver::SetProperty( 1596 Handle<Object> result = JSReceiver::SetProperty(
1661 receiver, name, value, NONE, strict_mode(), store_mode); 1597 receiver, name, value, NONE, strict_mode(), store_mode);
1662 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1598 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1663 return *result; 1599 return *result;
1664 } 1600 }
1665 1601
1666 if (receiver->IsJSGlobalProxy()) { 1602 if (receiver->IsJSGlobalProxy()) {
1667 if (use_ic && kind() != Code::KEYED_STORE_IC) { 1603 if (use_ic && kind() != Code::KEYED_STORE_IC) {
1668 // Generate a generic stub that goes to the runtime when we see a global 1604 // Generate a generic stub that goes to the runtime when we see a global
1669 // proxy as receiver. 1605 // proxy as receiver.
1670 Handle<Code> stub = global_proxy_stub(); 1606 Handle<Code> stub = global_proxy_stub();
1671 set_target(*stub); 1607 set_target(*stub);
1672 TRACE_IC("StoreIC", name, state, stub); 1608 TRACE_IC("StoreIC", name, stub);
1673 } 1609 }
1674 Handle<Object> result = JSReceiver::SetProperty( 1610 Handle<Object> result = JSReceiver::SetProperty(
1675 receiver, name, value, NONE, strict_mode(), store_mode); 1611 receiver, name, value, NONE, strict_mode(), store_mode);
1676 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1612 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1677 return *result; 1613 return *result;
1678 } 1614 }
1679 1615
1680 LookupResult lookup(isolate()); 1616 LookupResult lookup(isolate());
1681 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state); 1617 bool can_store = LookupForWrite(receiver, name, value, &lookup, this);
1682 if (!can_store && 1618 if (!can_store &&
1683 strict_mode() == kStrictMode && 1619 strict_mode() == kStrictMode &&
1684 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1620 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1685 IsUndeclaredGlobal(object)) { 1621 IsUndeclaredGlobal(object)) {
1686 // Strict mode doesn't allow setting non-existent global property. 1622 // Strict mode doesn't allow setting non-existent global property.
1687 return ReferenceError("not_defined", name); 1623 return ReferenceError("not_defined", name);
1688 } 1624 }
1689 if (use_ic) { 1625 if (use_ic) {
1690 if (state == UNINITIALIZED) { 1626 if (state() == UNINITIALIZED) {
1691 Handle<Code> stub = pre_monomorphic_stub(); 1627 Handle<Code> stub = pre_monomorphic_stub();
1692 set_target(*stub); 1628 set_target(*stub);
1693 TRACE_IC("StoreIC", name, state, stub); 1629 TRACE_IC("StoreIC", name, stub);
1694 } else if (can_store) { 1630 } else if (can_store) {
1695 UpdateCaches(&lookup, state, receiver, name, value); 1631 UpdateCaches(&lookup, receiver, name, value);
1696 } else if (!name->IsCacheable(isolate()) || 1632 } else if (!name->IsCacheable(isolate()) ||
1697 lookup.IsNormal() || 1633 lookup.IsNormal() ||
1698 (lookup.IsField() && lookup.CanHoldValue(value))) { 1634 (lookup.IsField() && lookup.CanHoldValue(value))) {
1699 Handle<Code> stub = generic_stub(); 1635 Handle<Code> stub = generic_stub();
1700 set_target(*stub); 1636 set_target(*stub);
1701 } 1637 }
1702 } 1638 }
1703 1639
1704 // Set the property. 1640 // Set the property.
1705 Handle<Object> result = JSReceiver::SetProperty( 1641 Handle<Object> result = JSReceiver::SetProperty(
1706 receiver, name, value, NONE, strict_mode(), store_mode); 1642 receiver, name, value, NONE, strict_mode(), store_mode);
1707 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1643 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1708 return *result; 1644 return *result;
1709 } 1645 }
1710 1646
1711 1647
1712 void StoreIC::UpdateCaches(LookupResult* lookup, 1648 void StoreIC::UpdateCaches(LookupResult* lookup,
1713 State state,
1714 Handle<JSObject> receiver, 1649 Handle<JSObject> receiver,
1715 Handle<String> name, 1650 Handle<String> name,
1716 Handle<Object> value) { 1651 Handle<Object> value) {
1717 ASSERT(!receiver->IsJSGlobalProxy()); 1652 ASSERT(!receiver->IsJSGlobalProxy());
1718 ASSERT(lookup->IsFound()); 1653 ASSERT(lookup->IsFound());
1719 1654
1720 // These are not cacheable, so we never see such LookupResults here. 1655 // These are not cacheable, so we never see such LookupResults here.
1721 ASSERT(!lookup->IsHandler()); 1656 ASSERT(!lookup->IsHandler());
1722 1657
1723 Handle<Code> code = ComputeStoreMonomorphic(lookup, receiver, name, value); 1658 Handle<Code> code = ComputeStoreMonomorphic(lookup, receiver, name, value);
1724 if (code.is_null()) { 1659 if (code.is_null()) {
1725 set_target(*generic_stub()); 1660 set_target(*generic_stub());
1726 return; 1661 return;
1727 } 1662 }
1728 1663
1729 PatchCache(state, receiver, name, code); 1664 PatchCache(receiver, name, code);
1730 TRACE_IC("StoreIC", name, state, target()); 1665 TRACE_IC("StoreIC", name, target());
1731 } 1666 }
1732 1667
1733 1668
1734 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, 1669 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
1735 Handle<JSObject> receiver, 1670 Handle<JSObject> receiver,
1736 Handle<String> name, 1671 Handle<String> name,
1737 Handle<Object> value) { 1672 Handle<Object> value) {
1738 Handle<JSObject> holder(lookup->holder()); 1673 Handle<JSObject> holder(lookup->holder());
1739 switch (lookup->type()) { 1674 switch (lookup->type()) {
1740 case FIELD: 1675 case FIELD:
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1819 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, 1754 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
1820 KeyedAccessStoreMode store_mode) { 1755 KeyedAccessStoreMode store_mode) {
1821 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1756 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1822 // via megamorphic stubs, since they don't have a map in their relocation info 1757 // via megamorphic stubs, since they don't have a map in their relocation info
1823 // and so the stubs can't be harvested for the object needed for a map check. 1758 // and so the stubs can't be harvested for the object needed for a map check.
1824 if (target()->type() != Code::NORMAL) { 1759 if (target()->type() != Code::NORMAL) {
1825 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); 1760 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type");
1826 return generic_stub(); 1761 return generic_stub();
1827 } 1762 }
1828 1763
1829 State ic_state = target()->ic_state();
1830 Handle<Map> receiver_map(receiver->map(), isolate()); 1764 Handle<Map> receiver_map(receiver->map(), isolate());
1831 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { 1765 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
1832 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1766 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1833 // yet will do so and stay there. 1767 // yet will do so and stay there.
1834 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); 1768 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode);
1835 store_mode = GetNonTransitioningStoreMode(store_mode); 1769 store_mode = GetNonTransitioningStoreMode(store_mode);
1836 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1770 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1837 monomorphic_map, strict_mode(), store_mode); 1771 monomorphic_map, strict_mode(), store_mode);
1838 } 1772 }
1839 1773
1840 MapHandleList target_receiver_maps; 1774 MapHandleList target_receiver_maps;
1841 target()->FindAllMaps(&target_receiver_maps); 1775 target()->FindAllMaps(&target_receiver_maps);
1842 if (target_receiver_maps.length() == 0) { 1776 if (target_receiver_maps.length() == 0) {
1843 // In the case that there is a non-map-specific IC is installed (e.g. keyed 1777 // In the case that there is a non-map-specific IC is installed (e.g. keyed
1844 // stores into properties in dictionary mode), then there will be not 1778 // stores into properties in dictionary mode), then there will be not
1845 // receiver maps in the target. 1779 // receiver maps in the target.
1846 return generic_stub(); 1780 return generic_stub();
1847 } 1781 }
1848 1782
1849 // There are several special cases where an IC that is MONOMORPHIC can still 1783 // There are several special cases where an IC that is MONOMORPHIC can still
1850 // transition to a different GetNonTransitioningStoreMode IC that handles a 1784 // transition to a different GetNonTransitioningStoreMode IC that handles a
1851 // superset of the original IC. Handle those here if the receiver map hasn't 1785 // superset of the original IC. Handle those here if the receiver map hasn't
1852 // changed or it has transitioned to a more general kind. 1786 // changed or it has transitioned to a more general kind.
1853 KeyedAccessStoreMode old_store_mode = 1787 KeyedAccessStoreMode old_store_mode =
1854 Code::GetKeyedAccessStoreMode(target()->extra_ic_state()); 1788 Code::GetKeyedAccessStoreMode(target()->extra_ic_state());
1855 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); 1789 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1856 if (ic_state == MONOMORPHIC) { 1790 if (state() == MONOMORPHIC) {
1857 // If the "old" and "new" maps are in the same elements map family, stay 1791 // If the "old" and "new" maps are in the same elements map family, stay
1858 // MONOMORPHIC and use the map for the most generic ElementsKind. 1792 // MONOMORPHIC and use the map for the most generic ElementsKind.
1859 Handle<Map> transitioned_receiver_map = receiver_map; 1793 Handle<Map> transitioned_receiver_map = receiver_map;
1860 if (IsTransitionStoreMode(store_mode)) { 1794 if (IsTransitionStoreMode(store_mode)) {
1861 transitioned_receiver_map = 1795 transitioned_receiver_map =
1862 ComputeTransitionedMap(receiver, store_mode); 1796 ComputeTransitionedMap(receiver, store_mode);
1863 } 1797 }
1864 if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) { 1798 if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) {
1865 // Element family is the same, use the "worst" case map. 1799 // Element family is the same, use the "worst" case map.
1866 store_mode = GetNonTransitioningStoreMode(store_mode); 1800 store_mode = GetNonTransitioningStoreMode(store_mode);
1867 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1801 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1868 transitioned_receiver_map, strict_mode(), store_mode); 1802 transitioned_receiver_map, strict_mode(), store_mode);
1869 } else if (*previous_receiver_map == receiver->map() && 1803 } else if (*previous_receiver_map == receiver->map() &&
1870 old_store_mode == STANDARD_STORE && 1804 old_store_mode == STANDARD_STORE &&
1871 (IsGrowStoreMode(store_mode) || 1805 (IsGrowStoreMode(store_mode) ||
1872 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1806 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
1873 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { 1807 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
1874 // A "normal" IC that handles stores can switch to a version that can 1808 // A "normal" IC that handles stores can switch to a version that can
1875 // grow at the end of the array, handle OOB accesses or copy COW arrays 1809 // grow at the end of the array, handle OOB accesses or copy COW arrays
1876 // and still stay MONOMORPHIC. 1810 // and still stay MONOMORPHIC.
1877 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1811 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1878 receiver_map, strict_mode(), store_mode); 1812 receiver_map, strict_mode(), store_mode);
1879 } 1813 }
1880 } 1814 }
1881 1815
1882 ASSERT(ic_state != GENERIC); 1816 ASSERT(state() != GENERIC);
1883 1817
1884 bool map_added = 1818 bool map_added =
1885 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1819 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1886 1820
1887 if (IsTransitionStoreMode(store_mode)) { 1821 if (IsTransitionStoreMode(store_mode)) {
1888 Handle<Map> transitioned_receiver_map = 1822 Handle<Map> transitioned_receiver_map =
1889 ComputeTransitionedMap(receiver, store_mode); 1823 ComputeTransitionedMap(receiver, store_mode);
1890 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, 1824 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
1891 transitioned_receiver_map); 1825 transitioned_receiver_map);
1892 } 1826 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 Heap* heap = receiver->GetHeap(); 1986 Heap* heap = receiver->GetHeap();
2053 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { 1987 if (receiver->elements()->map() == heap->fixed_cow_array_map()) {
2054 return STORE_NO_TRANSITION_HANDLE_COW; 1988 return STORE_NO_TRANSITION_HANDLE_COW;
2055 } else { 1989 } else {
2056 return STANDARD_STORE; 1990 return STANDARD_STORE;
2057 } 1991 }
2058 } 1992 }
2059 } 1993 }
2060 1994
2061 1995
2062 MaybeObject* KeyedStoreIC::Store(State state, 1996 MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
2063 Handle<Object> object,
2064 Handle<Object> key, 1997 Handle<Object> key,
2065 Handle<Object> value, 1998 Handle<Object> value,
2066 ICMissMode miss_mode) { 1999 ICMissMode miss_mode) {
2067 // Check for values that can be converted into an internalized string directly 2000 // Check for values that can be converted into an internalized string directly
2068 // or is representable as a smi. 2001 // or is representable as a smi.
2069 key = TryConvertKey(key, isolate()); 2002 key = TryConvertKey(key, isolate());
2070 2003
2071 if (key->IsInternalizedString()) { 2004 if (key->IsInternalizedString()) {
2072 return StoreIC::Store(state, 2005 return StoreIC::Store(object,
2073 object,
2074 Handle<String>::cast(key), 2006 Handle<String>::cast(key),
2075 value, 2007 value,
2076 JSReceiver::MAY_BE_STORE_FROM_KEYED); 2008 JSReceiver::MAY_BE_STORE_FROM_KEYED);
2077 } 2009 }
2078 2010
2079 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() && 2011 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() &&
2080 !(FLAG_harmony_observation && object->IsJSObject() && 2012 !(FLAG_harmony_observation && object->IsJSObject() &&
2081 JSObject::cast(*object)->map()->is_observed()); 2013 JSObject::cast(*object)->map()->is_observed());
2082 if (use_ic && !object->IsSmi()) { 2014 if (use_ic && !object->IsSmi()) {
2083 // Don't use ICs for maps of the objects in Array's prototype chain. We 2015 // Don't use ICs for maps of the objects in Array's prototype chain. We
(...skipping 24 matching lines...) Expand all
2108 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number"); 2040 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number");
2109 } 2041 }
2110 } else { 2042 } else {
2111 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "not an object"); 2043 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "not an object");
2112 } 2044 }
2113 } else { 2045 } else {
2114 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic"); 2046 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic");
2115 } 2047 }
2116 ASSERT(!stub.is_null()); 2048 ASSERT(!stub.is_null());
2117 set_target(*stub); 2049 set_target(*stub);
2118 TRACE_IC("KeyedStoreIC", key, state, target()); 2050 TRACE_IC("KeyedStoreIC", key, target());
2119 } 2051 }
2120 2052
2121 return Runtime::SetObjectPropertyOrFail( 2053 return Runtime::SetObjectPropertyOrFail(
2122 isolate(), object , key, value, NONE, strict_mode()); 2054 isolate(), object , key, value, NONE, strict_mode());
2123 } 2055 }
2124 2056
2125 2057
2126 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, 2058 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
2127 Handle<JSObject> receiver, 2059 Handle<JSObject> receiver,
2128 Handle<String> name, 2060 Handle<String> name,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2171 2103
2172 // ---------------------------------------------------------------------------- 2104 // ----------------------------------------------------------------------------
2173 // Static IC stub generators. 2105 // Static IC stub generators.
2174 // 2106 //
2175 2107
2176 // Used from ic-<arch>.cc. 2108 // Used from ic-<arch>.cc.
2177 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { 2109 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
2178 HandleScope scope(isolate); 2110 HandleScope scope(isolate);
2179 ASSERT(args.length() == 2); 2111 ASSERT(args.length() == 2);
2180 CallIC ic(isolate); 2112 CallIC ic(isolate);
2181 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2113 ic.UpdateState(args[0], args[1]);
2182 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 2114 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
2183 MaybeObject* maybe_result = ic.LoadFunction(state, 2115 MaybeObject* maybe_result = ic.LoadFunction(extra_ic_state,
2184 extra_ic_state,
2185 args.at<Object>(0), 2116 args.at<Object>(0),
2186 args.at<String>(1)); 2117 args.at<String>(1));
2187 JSFunction* raw_function; 2118 JSFunction* raw_function;
2188 if (!maybe_result->To(&raw_function)) return maybe_result; 2119 if (!maybe_result->To(&raw_function)) return maybe_result;
2189 2120
2190 // The first time the inline cache is updated may be the first time the 2121 // The first time the inline cache is updated may be the first time the
2191 // function it references gets called. If the function is lazily compiled 2122 // function it references gets called. If the function is lazily compiled
2192 // then the first call will trigger a compilation. We check for this case 2123 // then the first call will trigger a compilation. We check for this case
2193 // and we do the compilation immediately, instead of waiting for the stub 2124 // and we do the compilation immediately, instead of waiting for the stub
2194 // currently attached to the JSFunction object to trigger compilation. 2125 // currently attached to the JSFunction object to trigger compilation.
2195 if (raw_function->is_compiled()) return raw_function; 2126 if (raw_function->is_compiled()) return raw_function;
2196 2127
2197 Handle<JSFunction> function(raw_function); 2128 Handle<JSFunction> function(raw_function);
2198 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 2129 JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
2199 return *function; 2130 return *function;
2200 } 2131 }
2201 2132
2202 2133
2203 // Used from ic-<arch>.cc. 2134 // Used from ic-<arch>.cc.
2204 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { 2135 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
2205 HandleScope scope(isolate); 2136 HandleScope scope(isolate);
2206 ASSERT(args.length() == 2); 2137 ASSERT(args.length() == 2);
2207 KeyedCallIC ic(isolate); 2138 KeyedCallIC ic(isolate);
2208 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2139 ic.UpdateState(args[0], args[1]);
2209 MaybeObject* maybe_result = 2140 MaybeObject* maybe_result =
2210 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); 2141 ic.LoadFunction(args.at<Object>(0), args.at<Object>(1));
2211 // Result could be a function or a failure. 2142 // Result could be a function or a failure.
2212 JSFunction* raw_function = NULL; 2143 JSFunction* raw_function = NULL;
2213 if (!maybe_result->To(&raw_function)) return maybe_result; 2144 if (!maybe_result->To(&raw_function)) return maybe_result;
2214 2145
2215 if (raw_function->is_compiled()) return raw_function; 2146 if (raw_function->is_compiled()) return raw_function;
2216 2147
2217 Handle<JSFunction> function(raw_function, isolate); 2148 Handle<JSFunction> function(raw_function, isolate);
2218 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 2149 JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
2219 return *function; 2150 return *function;
2220 } 2151 }
2221 2152
2222 2153
2223 // Used from ic-<arch>.cc. 2154 // Used from ic-<arch>.cc.
2224 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { 2155 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
2225 HandleScope scope(isolate); 2156 HandleScope scope(isolate);
2226 ASSERT(args.length() == 2); 2157 ASSERT(args.length() == 2);
2227 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2158 LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2228 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2159 ic.UpdateState(args[0], args[1]);
2229 return ic.Load(state, args.at<Object>(0), args.at<String>(1)); 2160 return ic.Load(args.at<Object>(0), args.at<String>(1));
2230 } 2161 }
2231 2162
2232 2163
2233 // Used from ic-<arch>.cc 2164 // Used from ic-<arch>.cc
2234 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { 2165 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) {
2235 HandleScope scope(isolate); 2166 HandleScope scope(isolate);
2236 ASSERT(args.length() == 2); 2167 ASSERT(args.length() == 2);
2237 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2168 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2238 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2169 ic.UpdateState(args[0], args[1]);
2239 return ic.Load(state, args.at<Object>(0), args.at<Object>(1), MISS); 2170 return ic.Load(args.at<Object>(0), args.at<Object>(1), MISS);
2240 } 2171 }
2241 2172
2242 2173
2243 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) { 2174 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) {
2244 HandleScope scope(isolate); 2175 HandleScope scope(isolate);
2245 ASSERT(args.length() == 2); 2176 ASSERT(args.length() == 2);
2246 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate); 2177 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
2247 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2178 ic.UpdateState(args[0], args[1]);
2248 return ic.Load(state, args.at<Object>(0), args.at<Object>(1), MISS); 2179 return ic.Load(args.at<Object>(0), args.at<Object>(1), MISS);
2249 } 2180 }
2250 2181
2251 2182
2252 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) { 2183 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) {
2253 HandleScope scope(isolate); 2184 HandleScope scope(isolate);
2254 ASSERT(args.length() == 2); 2185 ASSERT(args.length() == 2);
2255 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2186 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2256 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2187 ic.UpdateState(args[0], args[1]);
2257 return ic.Load(state, 2188 return ic.Load(args.at<Object>(0),
2258 args.at<Object>(0),
2259 args.at<Object>(1), 2189 args.at<Object>(1),
2260 MISS_FORCE_GENERIC); 2190 MISS_FORCE_GENERIC);
2261 } 2191 }
2262 2192
2263 2193
2264 // Used from ic-<arch>.cc. 2194 // Used from ic-<arch>.cc.
2265 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { 2195 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
2266 HandleScope scope(isolate); 2196 HandleScope scope(isolate);
2267 ASSERT(args.length() == 3); 2197 ASSERT(args.length() == 3);
2268 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2198 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2269 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2199 ic.UpdateState(args[0], args[1]);
2270 return ic.Store(state, 2200 return ic.Store(args.at<Object>(0),
2271 args.at<Object>(0),
2272 args.at<String>(1), 2201 args.at<String>(1),
2273 args.at<Object>(2)); 2202 args.at<Object>(2));
2274 } 2203 }
2275 2204
2276 2205
2277 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { 2206 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) {
2278 HandleScope scope(isolate); 2207 HandleScope scope(isolate);
2279 ASSERT(args.length() == 3); 2208 ASSERT(args.length() == 3);
2280 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2209 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2281 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2210 ic.UpdateState(args[0], args[1]);
2282 return ic.Store(state, 2211 return ic.Store(args.at<Object>(0),
2283 args.at<Object>(0),
2284 args.at<String>(1), 2212 args.at<String>(1),
2285 args.at<Object>(2)); 2213 args.at<Object>(2));
2286 } 2214 }
2287 2215
2288 2216
2289 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { 2217 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
2290 SealHandleScope shs(isolate); 2218 SealHandleScope shs(isolate);
2291 2219
2292 ASSERT(args.length() == 2); 2220 ASSERT(args.length() == 2);
2293 JSArray* receiver = JSArray::cast(args[0]); 2221 JSArray* receiver = JSArray::cast(args[0]);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 // Return the stored value. 2286 // Return the stored value.
2359 return value; 2287 return value;
2360 } 2288 }
2361 2289
2362 2290
2363 // Used from ic-<arch>.cc. 2291 // Used from ic-<arch>.cc.
2364 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { 2292 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
2365 HandleScope scope(isolate); 2293 HandleScope scope(isolate);
2366 ASSERT(args.length() == 3); 2294 ASSERT(args.length() == 3);
2367 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2295 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2368 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2296 ic.UpdateState(args[0], args[1]);
2369 return ic.Store(state, 2297 return ic.Store(args.at<Object>(0),
2370 args.at<Object>(0),
2371 args.at<Object>(1), 2298 args.at<Object>(1),
2372 args.at<Object>(2), 2299 args.at<Object>(2),
2373 MISS); 2300 MISS);
2374 } 2301 }
2375 2302
2376 2303
2377 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { 2304 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) {
2378 HandleScope scope(isolate); 2305 HandleScope scope(isolate);
2379 ASSERT(args.length() == 3); 2306 ASSERT(args.length() == 3);
2380 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2307 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2381 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2308 ic.UpdateState(args[0], args[1]);
2382 return ic.Store(state, 2309 return ic.Store(args.at<Object>(0),
2383 args.at<Object>(0),
2384 args.at<Object>(1), 2310 args.at<Object>(1),
2385 args.at<Object>(2), 2311 args.at<Object>(2),
2386 MISS); 2312 MISS);
2387 } 2313 }
2388 2314
2389 2315
2390 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { 2316 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) {
2391 HandleScope scope(isolate); 2317 HandleScope scope(isolate);
2392 ASSERT(args.length() == 3); 2318 ASSERT(args.length() == 3);
2393 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2319 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
(...skipping 26 matching lines...) Expand all
2420 value, 2346 value,
2421 NONE, 2347 NONE,
2422 strict_mode); 2348 strict_mode);
2423 } 2349 }
2424 2350
2425 2351
2426 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { 2352 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
2427 HandleScope scope(isolate); 2353 HandleScope scope(isolate);
2428 ASSERT(args.length() == 3); 2354 ASSERT(args.length() == 3);
2429 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2355 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2430 IC::State state = IC::StateFrom(*ic.target(), args[0], args[1]); 2356 ic.UpdateState(args[0], args[1]);
2431 return ic.Store(state, 2357 return ic.Store(args.at<Object>(0),
2432 args.at<Object>(0),
2433 args.at<Object>(1), 2358 args.at<Object>(1),
2434 args.at<Object>(2), 2359 args.at<Object>(2),
2435 MISS_FORCE_GENERIC); 2360 MISS_FORCE_GENERIC);
2436 } 2361 }
2437 2362
2438 2363
2439 RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) { 2364 RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) {
2440 HandleScope scope(isolate); 2365 HandleScope scope(isolate);
2441 ASSERT(args.length() == 4); 2366 ASSERT(args.length() == 4);
2442 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2367 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
2951 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { 2876 RUNTIME_FUNCTION(Code*, CompareIC_Miss) {
2952 HandleScope scope(isolate); 2877 HandleScope scope(isolate);
2953 ASSERT(args.length() == 3); 2878 ASSERT(args.length() == 3);
2954 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); 2879 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2)));
2955 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); 2880 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1));
2956 return ic.raw_target(); 2881 return ic.raw_target();
2957 } 2882 }
2958 2883
2959 2884
2960 void CompareNilIC::Clear(Address address, Code* target) { 2885 void CompareNilIC::Clear(Address address, Code* target) {
2961 if (target->ic_state() == UNINITIALIZED) return; 2886 if (IsCleared(target)) return;
2962 Code::ExtraICState state = target->extended_extra_ic_state(); 2887 Code::ExtraICState state = target->extended_extra_ic_state();
2963 2888
2964 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); 2889 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED);
2965 stub.ClearState(); 2890 stub.ClearState();
2966 2891
2967 Code* code = NULL; 2892 Code* code = NULL;
2968 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); 2893 CHECK(stub.FindCodeInCache(&code, target->GetIsolate()));
2969 2894
2970 SetTargetAtAddress(address, code); 2895 SetTargetAtAddress(address, code);
2971 } 2896 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3031 set_target(*code); 2956 set_target(*code);
3032 return Smi::FromInt(to_boolean_value ? 1 : 0); 2957 return Smi::FromInt(to_boolean_value ? 1 : 0);
3033 } 2958 }
3034 2959
3035 2960
3036 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { 2961 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) {
3037 ASSERT(args.length() == 1); 2962 ASSERT(args.length() == 1);
3038 HandleScope scope(isolate); 2963 HandleScope scope(isolate);
3039 Handle<Object> object = args.at<Object>(0); 2964 Handle<Object> object = args.at<Object>(0);
3040 ToBooleanIC ic(isolate); 2965 ToBooleanIC ic(isolate);
3041 Code::ExtraICState ic_state = ic.target()->extended_extra_ic_state(); 2966 Code::ExtraICState extra_ic_state = ic.target()->extended_extra_ic_state();
3042 return ic.ToBoolean(object, ic_state); 2967 return ic.ToBoolean(object, extra_ic_state);
3043 } 2968 }
3044 2969
3045 2970
3046 static const Address IC_utilities[] = { 2971 static const Address IC_utilities[] = {
3047 #define ADDR(name) FUNCTION_ADDR(name), 2972 #define ADDR(name) FUNCTION_ADDR(name),
3048 IC_UTIL_LIST(ADDR) 2973 IC_UTIL_LIST(ADDR)
3049 NULL 2974 NULL
3050 #undef ADDR 2975 #undef ADDR
3051 }; 2976 };
3052 2977
3053 2978
3054 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2979 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3055 return IC_utilities[id]; 2980 return IC_utilities[id];
3056 } 2981 }
3057 2982
3058 2983
3059 } } // namespace v8::internal 2984 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698