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

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

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