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

Side by Side Diff: src/ic/ic.cc

Issue 683883002: Revert "Introduce FeedbackNexus for vector-based ics." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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/ic.h ('k') | src/ic/ic-inl.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 PrintF("[%s patching generic stub in ", type); \ 82 PrintF("[%s patching generic stub in ", type); \
83 PrintF("(see below) (%s)]\n", reason); \ 83 PrintF("(see below) (%s)]\n", reason); \
84 } \ 84 } \
85 } while (false) 85 } while (false)
86 86
87 #endif // DEBUG 87 #endif // DEBUG
88 88
89 89
90 void IC::TraceIC(const char* type, Handle<Object> name) { 90 void IC::TraceIC(const char* type, Handle<Object> name) {
91 if (FLAG_trace_ic) { 91 if (FLAG_trace_ic) {
92 State new_state = 92 Code* new_target = raw_target();
93 UseVector() ? nexus()->StateFromFeedback() : raw_target()->ic_state(); 93 State new_state = new_target->ic_state();
94 TraceIC(type, name, state(), new_state); 94 TraceIC(type, name, state(), new_state);
95 } 95 }
96 } 96 }
97 97
98 98
99 void IC::TraceIC(const char* type, Handle<Object> name, State old_state, 99 void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
100 State new_state) { 100 State new_state) {
101 if (FLAG_trace_ic) { 101 if (FLAG_trace_ic) {
102 Code* new_target = raw_target(); 102 Code* new_target = raw_target();
103 PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type); 103 PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type);
(...skipping 23 matching lines...) Expand all
127 #ifdef OBJECT_PRINT 127 #ifdef OBJECT_PRINT
128 OFStream os(stdout); 128 OFStream os(stdout);
129 name->Print(os); 129 name->Print(os);
130 #else 130 #else
131 name->ShortPrint(stdout); 131 name->ShortPrint(stdout);
132 #endif 132 #endif
133 PrintF("]\n"); 133 PrintF("]\n");
134 } 134 }
135 } 135 }
136 136
137 #define TRACE_IC(type, name) TraceIC(type, name)
138 #define TRACE_VECTOR_IC(type, name, old_state, new_state) \
139 TraceIC(type, name, old_state, new_state)
137 140
138 #define TRACE_IC(type, name) TraceIC(type, name) 141 IC::IC(FrameDepth depth, Isolate* isolate)
139 142 : isolate_(isolate), target_set_(false), target_maps_set_(false) {
140
141 IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus,
142 bool for_queries_only)
143 : isolate_(isolate),
144 target_set_(false),
145 target_maps_set_(false),
146 nexus_(nexus) {
147 // To improve the performance of the (much used) IC code, we unfold a few 143 // To improve the performance of the (much used) IC code, we unfold a few
148 // levels of the stack frame iteration code. This yields a ~35% speedup when 144 // levels of the stack frame iteration code. This yields a ~35% speedup when
149 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. 145 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
150 const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); 146 const Address entry = Isolate::c_entry_fp(isolate->thread_local_top());
151 Address constant_pool = NULL; 147 Address constant_pool = NULL;
152 if (FLAG_enable_ool_constant_pool) { 148 if (FLAG_enable_ool_constant_pool) {
153 constant_pool = 149 constant_pool =
154 Memory::Address_at(entry + ExitFrameConstants::kConstantPoolOffset); 150 Memory::Address_at(entry + ExitFrameConstants::kConstantPoolOffset);
155 } 151 }
156 Address* pc_address = 152 Address* pc_address =
(...skipping 18 matching lines...) Expand all
175 DCHECK(fp == frame->fp() && pc_address == frame->pc_address()); 171 DCHECK(fp == frame->fp() && pc_address == frame->pc_address());
176 #endif 172 #endif
177 fp_ = fp; 173 fp_ = fp;
178 if (FLAG_enable_ool_constant_pool) { 174 if (FLAG_enable_ool_constant_pool) {
179 raw_constant_pool_ = handle( 175 raw_constant_pool_ = handle(
180 ConstantPoolArray::cast(reinterpret_cast<Object*>(constant_pool)), 176 ConstantPoolArray::cast(reinterpret_cast<Object*>(constant_pool)),
181 isolate); 177 isolate);
182 } 178 }
183 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); 179 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
184 target_ = handle(raw_target(), isolate); 180 target_ = handle(raw_target(), isolate);
181 state_ = target_->ic_state();
185 kind_ = target_->kind(); 182 kind_ = target_->kind();
186 state_ = (!for_queries_only && UseVector()) ? nexus->StateFromFeedback()
187 : target_->ic_state();
188 old_state_ = state_;
189 extra_ic_state_ = target_->extra_ic_state(); 183 extra_ic_state_ = target_->extra_ic_state();
190 } 184 }
191 185
192 186
193 SharedFunctionInfo* IC::GetSharedFunctionInfo() const { 187 SharedFunctionInfo* IC::GetSharedFunctionInfo() const {
194 // Compute the JavaScript frame for the frame pointer of this IC 188 // Compute the JavaScript frame for the frame pointer of this IC
195 // structure. We need this to be able to find the function 189 // structure. We need this to be able to find the function
196 // corresponding to the frame. 190 // corresponding to the frame.
197 StackFrameIterator it(isolate()); 191 StackFrameIterator it(isolate());
198 while (it.frame()->fp() != this->fp()) it.Advance(); 192 while (it.frame()->fp() != this->fp()) it.Advance();
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 info->change_own_type_change_checksum(); 412 info->change_own_type_change_checksum();
419 } 413 }
420 host->set_profiler_ticks(0); 414 host->set_profiler_ticks(0);
421 isolate->runtime_profiler()->NotifyICChanged(); 415 isolate->runtime_profiler()->NotifyICChanged();
422 // TODO(2029): When an optimized function is patched, it would 416 // TODO(2029): When an optimized function is patched, it would
423 // be nice to propagate the corresponding type information to its 417 // be nice to propagate the corresponding type information to its
424 // unoptimized version for the benefit of later inlining. 418 // unoptimized version for the benefit of later inlining.
425 } 419 }
426 420
427 421
428 // static
429 void IC::OnTypeFeedbackChanged(Isolate* isolate, Code* host,
430 TypeFeedbackVector* vector, State old_state,
431 State new_state) {
432 if (host->kind() != Code::FUNCTION) return;
433
434 if (FLAG_type_info_threshold > 0) {
435 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic.
436 int generic_delta = 0; // "Generic" here includes megamorphic.
437 ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
438 &generic_delta);
439 vector->change_ic_with_type_info_count(polymorphic_delta);
440 vector->change_ic_generic_count(generic_delta);
441 }
442 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
443 info->change_own_type_change_checksum();
444 host->set_profiler_ticks(0);
445 isolate->runtime_profiler()->NotifyICChanged();
446 // TODO(2029): When an optimized function is patched, it would
447 // be nice to propagate the corresponding type information to its
448 // unoptimized version for the benefit of later inlining.
449 }
450
451
452 void IC::PostPatching(Address address, Code* target, Code* old_target) { 422 void IC::PostPatching(Address address, Code* target, Code* old_target) {
453 // Type vector based ICs update these statistics at a different time because 423 // Type vector based ICs update these statistics at a different time because
454 // they don't always patch on state change. 424 // they don't always patch on state change.
455 if (target->kind() == Code::CALL_IC) return; 425 if (target->kind() == Code::CALL_IC) return;
456 426
457 Isolate* isolate = target->GetHeap()->isolate(); 427 Isolate* isolate = target->GetHeap()->isolate();
458 State old_state = UNINITIALIZED; 428 State old_state = UNINITIALIZED;
459 State new_state = UNINITIALIZED; 429 State new_state = UNINITIALIZED;
460 bool target_remains_ic_stub = false; 430 bool target_remains_ic_stub = false;
461 if (old_target->is_inline_cache_stub() && target->is_inline_cache_stub()) { 431 if (old_target->is_inline_cache_stub() && target->is_inline_cache_stub()) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 case Code::TO_BOOLEAN_IC: 500 case Code::TO_BOOLEAN_IC:
531 // Clearing these is tricky and does not 501 // Clearing these is tricky and does not
532 // make any performance difference. 502 // make any performance difference.
533 return; 503 return;
534 default: 504 default:
535 UNREACHABLE(); 505 UNREACHABLE();
536 } 506 }
537 } 507 }
538 508
539 509
540 template <class Nexus> 510 void IC::Clear(Isolate* isolate, Code::Kind kind, Code* host,
541 void IC::Clear(Isolate* isolate, Code::Kind kind, Code* host, Nexus* nexus) { 511 TypeFeedbackVector* vector, FeedbackVectorICSlot slot) {
542 switch (kind) { 512 switch (kind) {
543 case Code::CALL_IC: 513 case Code::CALL_IC:
544 return CallIC::Clear(isolate, host, nexus); 514 return CallIC::Clear(isolate, host, vector, slot);
545 default: 515 default:
546 UNREACHABLE(); 516 UNREACHABLE();
547 } 517 }
548 } 518 }
549 519
550 520
551 // Force instantiation of template instances for vector-based IC clearing.
552 template void IC::Clear(Isolate*, Code::Kind, Code*, CallICNexus*);
553
554
555 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target, 521 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target,
556 ConstantPoolArray* constant_pool) { 522 ConstantPoolArray* constant_pool) {
557 if (IsCleared(target)) return; 523 if (IsCleared(target)) return;
558 524
559 // Make sure to also clear the map used in inline fast cases. If we 525 // Make sure to also clear the map used in inline fast cases. If we
560 // do not clear these maps, cached code can keep objects alive 526 // do not clear these maps, cached code can keep objects alive
561 // through the embedded maps. 527 // through the embedded maps.
562 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); 528 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool);
563 } 529 }
564 530
565 531
566 void CallIC::Clear(Isolate* isolate, Code* host, CallICNexus* nexus) { 532 void CallIC::Clear(Isolate* isolate, Code* host, TypeFeedbackVector* vector,
533 FeedbackVectorICSlot slot) {
534 DCHECK(vector != NULL && !slot.IsInvalid());
535 Object* feedback = vector->Get(slot);
567 // Determine our state. 536 // Determine our state.
568 Object* feedback = nexus->vector()->Get(nexus->slot()); 537 State state = FeedbackToState(isolate, vector, slot);
569 State state = nexus->StateFromFeedback();
570 538
571 if (state != UNINITIALIZED && !feedback->IsAllocationSite()) { 539 if (state != UNINITIALIZED && !feedback->IsAllocationSite()) {
572 nexus->ConfigureUninitialized(); 540 vector->Set(slot, isolate->heap()->uninitialized_symbol(),
541 SKIP_WRITE_BARRIER);
573 // The change in state must be processed. 542 // The change in state must be processed.
574 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, UNINITIALIZED); 543 OnTypeFeedbackChanged(isolate, host, vector, state, UNINITIALIZED);
575 } 544 }
576 } 545 }
577 546
578 547
579 void LoadIC::Clear(Isolate* isolate, Address address, Code* target, 548 void LoadIC::Clear(Isolate* isolate, Address address, Code* target,
580 ConstantPoolArray* constant_pool) { 549 ConstantPoolArray* constant_pool) {
581 if (IsCleared(target)) return; 550 if (IsCleared(target)) return;
582 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC, 551 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC,
583 target->extra_ic_state()); 552 target->extra_ic_state());
584 SetTargetAtAddress(address, code, constant_pool); 553 SetTargetAtAddress(address, code, constant_pool);
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 } 1939 }
1971 1940
1972 1941
1973 // static 1942 // static
1974 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 1943 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
1975 StrictMode strict_mode) { 1944 StrictMode strict_mode) {
1976 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); 1945 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
1977 } 1946 }
1978 1947
1979 1948
1949 // static
1950 void CallIC::OnTypeFeedbackChanged(Isolate* isolate, Code* host,
1951 TypeFeedbackVector* vector, State old_state,
1952 State new_state) {
1953 if (host->kind() != Code::FUNCTION) return;
1954
1955 if (FLAG_type_info_threshold > 0) {
1956 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic.
1957 int generic_delta = 0; // "Generic" here includes megamorphic.
1958 ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
1959 &generic_delta);
1960 vector->change_ic_with_type_info_count(polymorphic_delta);
1961 vector->change_ic_generic_count(generic_delta);
1962 }
1963 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
1964 info->change_own_type_change_checksum();
1965 host->set_profiler_ticks(0);
1966 isolate->runtime_profiler()->NotifyICChanged();
1967 // TODO(2029): When an optimized function is patched, it would
1968 // be nice to propagate the corresponding type information to its
1969 // unoptimized version for the benefit of later inlining.
1970 }
1971
1972
1980 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, 1973 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
1981 const CallICState& callic_state) { 1974 Handle<TypeFeedbackVector> vector,
1975 FeedbackVectorICSlot slot,
1976 const CallICState& state) {
1982 DCHECK(FLAG_use_ic && function->IsJSFunction()); 1977 DCHECK(FLAG_use_ic && function->IsJSFunction());
1983 1978
1984 // Are we the array function? 1979 // Are we the array function?
1985 Handle<JSFunction> array_function = 1980 Handle<JSFunction> array_function =
1986 Handle<JSFunction>(isolate()->native_context()->array_function()); 1981 Handle<JSFunction>(isolate()->native_context()->array_function());
1987 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { 1982 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) {
1988 // Alter the slot. 1983 // Alter the slot.
1989 CallICNexus* nexus = casted_nexus<CallICNexus>(); 1984 IC::State old_state = FeedbackToState(isolate(), *vector, slot);
1990 nexus->ConfigureMonomorphicArray(); 1985 Object* feedback = vector->Get(slot);
1986 if (!feedback->IsAllocationSite()) {
1987 Handle<AllocationSite> new_site =
1988 isolate()->factory()->NewAllocationSite();
1989 vector->Set(slot, *new_site);
1990 }
1991 1991
1992 CallIC_ArrayStub stub(isolate(), callic_state); 1992 CallIC_ArrayStub stub(isolate(), state);
1993 set_target(*stub.GetCode()); 1993 set_target(*stub.GetCode());
1994 Handle<String> name; 1994 Handle<String> name;
1995 if (array_function->shared()->name()->IsString()) { 1995 if (array_function->shared()->name()->IsString()) {
1996 name = Handle<String>(String::cast(array_function->shared()->name()), 1996 name = Handle<String>(String::cast(array_function->shared()->name()),
1997 isolate()); 1997 isolate());
1998 } 1998 }
1999 TRACE_IC("CallIC", name); 1999
2000 OnTypeFeedbackChanged(isolate(), get_host(), nexus->vector(), state(), 2000 IC::State new_state = FeedbackToState(isolate(), *vector, slot);
2001 MONOMORPHIC); 2001 OnTypeFeedbackChanged(isolate(), get_host(), *vector, old_state, new_state);
2002 TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state);
2002 return true; 2003 return true;
2003 } 2004 }
2004 return false; 2005 return false;
2005 } 2006 }
2006 2007
2007 2008
2008 void CallIC::PatchMegamorphic(Handle<Object> function) { 2009 void CallIC::PatchMegamorphic(Handle<Object> function,
2009 CallICState callic_state(target()->extra_ic_state()); 2010 Handle<TypeFeedbackVector> vector,
2011 FeedbackVectorICSlot slot) {
2012 CallICState state(target()->extra_ic_state());
2013 IC::State old_state = FeedbackToState(isolate(), *vector, slot);
2010 2014
2011 // We are going generic. 2015 // We are going generic.
2012 CallICNexus* nexus = casted_nexus<CallICNexus>(); 2016 vector->Set(slot, *TypeFeedbackVector::MegamorphicSentinel(isolate()),
2013 nexus->ConfigureGeneric(); 2017 SKIP_WRITE_BARRIER);
2014 2018
2015 CallICStub stub(isolate(), callic_state); 2019 CallICStub stub(isolate(), state);
2016 Handle<Code> code = stub.GetCode(); 2020 Handle<Code> code = stub.GetCode();
2017 set_target(*code); 2021 set_target(*code);
2018 2022
2019 Handle<Object> name = isolate()->factory()->empty_string(); 2023 Handle<Object> name = isolate()->factory()->empty_string();
2020 if (function->IsJSFunction()) { 2024 if (function->IsJSFunction()) {
2021 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); 2025 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
2022 name = handle(js_function->shared()->name(), isolate()); 2026 name = handle(js_function->shared()->name(), isolate());
2023 } 2027 }
2024 2028
2025 TRACE_IC("CallIC", name); 2029 IC::State new_state = FeedbackToState(isolate(), *vector, slot);
2026 OnTypeFeedbackChanged(isolate(), get_host(), nexus->vector(), state(), 2030 OnTypeFeedbackChanged(isolate(), get_host(), *vector, old_state, new_state);
2027 GENERIC); 2031 TRACE_VECTOR_IC("CallIC", name, old_state, new_state);
2028 } 2032 }
2029 2033
2030 2034
2031 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function) { 2035 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function,
2032 CallICState callic_state(target()->extra_ic_state()); 2036 Handle<TypeFeedbackVector> vector,
2037 FeedbackVectorICSlot slot) {
2038 CallICState state(target()->extra_ic_state());
2039 IC::State old_state = FeedbackToState(isolate(), *vector, slot);
2033 Handle<Object> name = isolate()->factory()->empty_string(); 2040 Handle<Object> name = isolate()->factory()->empty_string();
2034 CallICNexus* nexus = casted_nexus<CallICNexus>(); 2041 Object* feedback = vector->Get(slot);
2035 Object* feedback = nexus->GetFeedback();
2036 2042
2037 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. 2043 // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
2038 DCHECK(!feedback->IsSmi()); 2044 DCHECK(!feedback->IsSmi());
2039 2045
2040 if (feedback->IsJSFunction() || !function->IsJSFunction()) { 2046 if (feedback->IsJSFunction() || !function->IsJSFunction()) {
2041 // We are going generic. 2047 // We are going generic.
2042 nexus->ConfigureGeneric(); 2048 vector->Set(slot, *TypeFeedbackVector::MegamorphicSentinel(isolate()),
2049 SKIP_WRITE_BARRIER);
2043 } else { 2050 } else {
2044 // The feedback is either uninitialized or an allocation site. 2051 // The feedback is either uninitialized or an allocation site.
2045 // It might be an allocation site because if we re-compile the full code 2052 // It might be an allocation site because if we re-compile the full code
2046 // to add deoptimization support, we call with the default call-ic, and 2053 // to add deoptimization support, we call with the default call-ic, and
2047 // merely need to patch the target to match the feedback. 2054 // merely need to patch the target to match the feedback.
2048 // TODO(mvstanton): the better approach is to dispense with patching 2055 // TODO(mvstanton): the better approach is to dispense with patching
2049 // altogether, which is in progress. 2056 // altogether, which is in progress.
2050 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || 2057 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) ||
2051 feedback->IsAllocationSite()); 2058 feedback->IsAllocationSite());
2052 2059
2053 // Do we want to install a custom handler? 2060 // Do we want to install a custom handler?
2054 if (FLAG_use_ic && DoCustomHandler(receiver, function, callic_state)) { 2061 if (FLAG_use_ic &&
2062 DoCustomHandler(receiver, function, vector, slot, state)) {
2055 return; 2063 return;
2056 } 2064 }
2057 2065
2058 nexus->ConfigureMonomorphic(Handle<JSFunction>::cast(function)); 2066 vector->Set(slot, *function);
2059 } 2067 }
2060 2068
2061 if (function->IsJSFunction()) { 2069 if (function->IsJSFunction()) {
2062 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); 2070 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
2063 name = handle(js_function->shared()->name(), isolate()); 2071 name = handle(js_function->shared()->name(), isolate());
2064 } 2072 }
2065 2073
2066 IC::State new_state = nexus->StateFromFeedback(); 2074 IC::State new_state = FeedbackToState(isolate(), *vector, slot);
2067 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), state(), new_state); 2075 OnTypeFeedbackChanged(isolate(), get_host(), *vector, old_state, new_state);
2068 TRACE_IC("CallIC", name); 2076 TRACE_VECTOR_IC("CallIC", name, old_state, new_state);
2069 } 2077 }
2070 2078
2071 2079
2072 #undef TRACE_IC 2080 #undef TRACE_IC
2073 2081
2074 2082
2075 // ---------------------------------------------------------------------------- 2083 // ----------------------------------------------------------------------------
2076 // Static IC stub generators. 2084 // Static IC stub generators.
2077 // 2085 //
2078 2086
2079 // Used from ic-<arch>.cc. 2087 // Used from ic-<arch>.cc.
2080 RUNTIME_FUNCTION(CallIC_Miss) { 2088 RUNTIME_FUNCTION(CallIC_Miss) {
2081 TimerEventScope<TimerEventIcMiss> timer(isolate); 2089 TimerEventScope<TimerEventIcMiss> timer(isolate);
2082 HandleScope scope(isolate); 2090 HandleScope scope(isolate);
2083 DCHECK(args.length() == 4); 2091 DCHECK(args.length() == 4);
2092 CallIC ic(isolate);
2084 Handle<Object> receiver = args.at<Object>(0); 2093 Handle<Object> receiver = args.at<Object>(0);
2085 Handle<Object> function = args.at<Object>(1); 2094 Handle<Object> function = args.at<Object>(1);
2086 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); 2095 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2);
2087 Handle<Smi> slot = args.at<Smi>(3); 2096 Handle<Smi> slot = args.at<Smi>(3);
2088 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); 2097 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2089 CallICNexus nexus(vector, vector_slot); 2098 ic.HandleMiss(receiver, function, vector, vector_slot);
2090 CallIC ic(isolate, &nexus);
2091 ic.HandleMiss(receiver, function);
2092 return *function; 2099 return *function;
2093 } 2100 }
2094 2101
2095 2102
2096 RUNTIME_FUNCTION(CallIC_Customization_Miss) { 2103 RUNTIME_FUNCTION(CallIC_Customization_Miss) {
2097 TimerEventScope<TimerEventIcMiss> timer(isolate); 2104 TimerEventScope<TimerEventIcMiss> timer(isolate);
2098 HandleScope scope(isolate); 2105 HandleScope scope(isolate);
2099 DCHECK(args.length() == 4); 2106 DCHECK(args.length() == 4);
2107 // A miss on a custom call ic always results in going megamorphic.
2108 CallIC ic(isolate);
2100 Handle<Object> function = args.at<Object>(1); 2109 Handle<Object> function = args.at<Object>(1);
2101 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); 2110 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2);
2102 Handle<Smi> slot = args.at<Smi>(3); 2111 Handle<Smi> slot = args.at<Smi>(3);
2103 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); 2112 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2104 CallICNexus nexus(vector, vector_slot); 2113 ic.PatchMegamorphic(function, vector, vector_slot);
2105 // A miss on a custom call ic always results in going megamorphic.
2106 CallIC ic(isolate, &nexus);
2107 ic.PatchMegamorphic(function);
2108 return *function; 2114 return *function;
2109 } 2115 }
2110 2116
2111 2117
2112 // Used from ic-<arch>.cc. 2118 // Used from ic-<arch>.cc.
2113 RUNTIME_FUNCTION(LoadIC_Miss) { 2119 RUNTIME_FUNCTION(LoadIC_Miss) {
2114 TimerEventScope<TimerEventIcMiss> timer(isolate); 2120 TimerEventScope<TimerEventIcMiss> timer(isolate);
2115 HandleScope scope(isolate); 2121 HandleScope scope(isolate);
2116 DCHECK(args.length() == 2); 2122 DCHECK(args.length() == 2);
2117 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2123 LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
2736 static const Address IC_utilities[] = { 2742 static const Address IC_utilities[] = {
2737 #define ADDR(name) FUNCTION_ADDR(name), 2743 #define ADDR(name) FUNCTION_ADDR(name),
2738 IC_UTIL_LIST(ADDR) NULL 2744 IC_UTIL_LIST(ADDR) NULL
2739 #undef ADDR 2745 #undef ADDR
2740 }; 2746 };
2741 2747
2742 2748
2743 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 2749 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
2744 } 2750 }
2745 } // namespace v8::internal 2751 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698