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

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

Issue 680883004: Introduce FeedbackNexus for vector-based ics. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment response. 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 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); 1964 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub");
1934 } 1965 }
1935 DCHECK(!stub.is_null()); 1966 DCHECK(!stub.is_null());
1936 set_target(*stub); 1967 set_target(*stub);
1937 TRACE_IC("StoreIC", key); 1968 TRACE_IC("StoreIC", key);
1938 1969
1939 return store_handle; 1970 return store_handle;
1940 } 1971 }
1941 1972
1942 1973
1943 // static
1944 void CallIC::OnTypeFeedbackChanged(Isolate* isolate, Code* host,
1945 TypeFeedbackVector* vector, State old_state,
1946 State new_state) {
1947 if (host->kind() != Code::FUNCTION) return;
1948
1949 if (FLAG_type_info_threshold > 0) {
1950 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic.
1951 int generic_delta = 0; // "Generic" here includes megamorphic.
1952 ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
1953 &generic_delta);
1954 vector->change_ic_with_type_info_count(polymorphic_delta);
1955 vector->change_ic_generic_count(generic_delta);
1956 }
1957 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
1958 info->change_own_type_change_checksum();
1959 host->set_profiler_ticks(0);
1960 isolate->runtime_profiler()->NotifyICChanged();
1961 // TODO(2029): When an optimized function is patched, it would
1962 // be nice to propagate the corresponding type information to its
1963 // unoptimized version for the benefit of later inlining.
1964 }
1965
1966
1967 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, 1974 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
1968 Handle<TypeFeedbackVector> vector, 1975 const CallICState& callic_state) {
1969 FeedbackVectorICSlot slot,
1970 const CallICState& state) {
1971 DCHECK(FLAG_use_ic && function->IsJSFunction()); 1976 DCHECK(FLAG_use_ic && function->IsJSFunction());
1972 1977
1973 // Are we the array function? 1978 // Are we the array function?
1974 Handle<JSFunction> array_function = 1979 Handle<JSFunction> array_function =
1975 Handle<JSFunction>(isolate()->native_context()->array_function()); 1980 Handle<JSFunction>(isolate()->native_context()->array_function());
1976 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { 1981 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) {
1977 // Alter the slot. 1982 // Alter the slot.
1978 IC::State old_state = FeedbackToState(isolate(), *vector, slot); 1983 CallICNexus* nexus = casted_nexus<CallICNexus>();
1979 Object* feedback = vector->Get(slot); 1984 nexus->ConfigureMonomorphicArray();
1980 if (!feedback->IsAllocationSite()) {
1981 Handle<AllocationSite> new_site =
1982 isolate()->factory()->NewAllocationSite();
1983 vector->Set(slot, *new_site);
1984 }
1985 1985
1986 CallIC_ArrayStub stub(isolate(), state); 1986 CallIC_ArrayStub stub(isolate(), callic_state);
1987 set_target(*stub.GetCode()); 1987 set_target(*stub.GetCode());
1988 Handle<String> name; 1988 Handle<String> name;
1989 if (array_function->shared()->name()->IsString()) { 1989 if (array_function->shared()->name()->IsString()) {
1990 name = Handle<String>(String::cast(array_function->shared()->name()), 1990 name = Handle<String>(String::cast(array_function->shared()->name()),
1991 isolate()); 1991 isolate());
1992 } 1992 }
1993 1993 TRACE_IC("CallIC", name);
1994 IC::State new_state = FeedbackToState(isolate(), *vector, slot); 1994 OnTypeFeedbackChanged(isolate(), get_host(), nexus->vector(), state(),
1995 OnTypeFeedbackChanged(isolate(), get_host(), *vector, old_state, new_state); 1995 MONOMORPHIC);
1996 TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state);
1997 return true; 1996 return true;
1998 } 1997 }
1999 return false; 1998 return false;
2000 } 1999 }
2001 2000
2002 2001
2003 void CallIC::PatchMegamorphic(Handle<Object> function, 2002 void CallIC::PatchMegamorphic(Handle<Object> function) {
2004 Handle<TypeFeedbackVector> vector, 2003 CallICState callic_state(target()->extra_ic_state());
2005 FeedbackVectorICSlot slot) {
2006 CallICState state(target()->extra_ic_state());
2007 IC::State old_state = FeedbackToState(isolate(), *vector, slot);
2008 2004
2009 // We are going generic. 2005 // We are going generic.
2010 vector->Set(slot, *TypeFeedbackVector::MegamorphicSentinel(isolate()), 2006 CallICNexus* nexus = casted_nexus<CallICNexus>();
2011 SKIP_WRITE_BARRIER); 2007 nexus->ConfigureGeneric();
2012 2008
2013 CallICStub stub(isolate(), state); 2009 CallICStub stub(isolate(), callic_state);
2014 Handle<Code> code = stub.GetCode(); 2010 Handle<Code> code = stub.GetCode();
2015 set_target(*code); 2011 set_target(*code);
2016 2012
2017 Handle<Object> name = isolate()->factory()->empty_string(); 2013 Handle<Object> name = isolate()->factory()->empty_string();
2018 if (function->IsJSFunction()) { 2014 if (function->IsJSFunction()) {
2019 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); 2015 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
2020 name = handle(js_function->shared()->name(), isolate()); 2016 name = handle(js_function->shared()->name(), isolate());
2021 } 2017 }
2022 2018
2023 IC::State new_state = FeedbackToState(isolate(), *vector, slot); 2019 TRACE_IC("CallIC", name);
2024 OnTypeFeedbackChanged(isolate(), get_host(), *vector, old_state, new_state); 2020 OnTypeFeedbackChanged(isolate(), get_host(), nexus->vector(), state(),
2025 TRACE_VECTOR_IC("CallIC", name, old_state, new_state); 2021 GENERIC);
2026 } 2022 }
2027 2023
2028 2024
2029 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function, 2025 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function) {
2030 Handle<TypeFeedbackVector> vector, 2026 CallICState callic_state(target()->extra_ic_state());
2031 FeedbackVectorICSlot slot) {
2032 CallICState state(target()->extra_ic_state());
2033 IC::State old_state = FeedbackToState(isolate(), *vector, slot);
2034 Handle<Object> name = isolate()->factory()->empty_string(); 2027 Handle<Object> name = isolate()->factory()->empty_string();
2035 Object* feedback = vector->Get(slot); 2028 CallICNexus* nexus = casted_nexus<CallICNexus>();
2029 Object* feedback = nexus->GetFeedback();
2036 2030
2037 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. 2031 // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
2038 DCHECK(!feedback->IsSmi()); 2032 DCHECK(!feedback->IsSmi());
2039 2033
2040 if (feedback->IsJSFunction() || !function->IsJSFunction()) { 2034 if (feedback->IsJSFunction() || !function->IsJSFunction()) {
2041 // We are going generic. 2035 // We are going generic.
2042 vector->Set(slot, *TypeFeedbackVector::MegamorphicSentinel(isolate()), 2036 nexus->ConfigureGeneric();
2043 SKIP_WRITE_BARRIER);
2044 } else { 2037 } else {
2045 // The feedback is either uninitialized or an allocation site. 2038 // The feedback is either uninitialized or an allocation site.
2046 // It might be an allocation site because if we re-compile the full code 2039 // It might be an allocation site because if we re-compile the full code
2047 // to add deoptimization support, we call with the default call-ic, and 2040 // to add deoptimization support, we call with the default call-ic, and
2048 // merely need to patch the target to match the feedback. 2041 // merely need to patch the target to match the feedback.
2049 // TODO(mvstanton): the better approach is to dispense with patching 2042 // TODO(mvstanton): the better approach is to dispense with patching
2050 // altogether, which is in progress. 2043 // altogether, which is in progress.
2051 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || 2044 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) ||
2052 feedback->IsAllocationSite()); 2045 feedback->IsAllocationSite());
2053 2046
2054 // Do we want to install a custom handler? 2047 // Do we want to install a custom handler?
2055 if (FLAG_use_ic && 2048 if (FLAG_use_ic && DoCustomHandler(receiver, function, callic_state)) {
2056 DoCustomHandler(receiver, function, vector, slot, state)) {
2057 return; 2049 return;
2058 } 2050 }
2059 2051
2060 vector->Set(slot, *function); 2052 nexus->ConfigureMonomorphic(Handle<JSFunction>::cast(function));
2061 } 2053 }
2062 2054
2063 if (function->IsJSFunction()) { 2055 if (function->IsJSFunction()) {
2064 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); 2056 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
2065 name = handle(js_function->shared()->name(), isolate()); 2057 name = handle(js_function->shared()->name(), isolate());
2066 } 2058 }
2067 2059
2068 IC::State new_state = FeedbackToState(isolate(), *vector, slot); 2060 IC::State new_state = nexus->StateFromFeedback();
2069 OnTypeFeedbackChanged(isolate(), get_host(), *vector, old_state, new_state); 2061 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), state(), new_state);
2070 TRACE_VECTOR_IC("CallIC", name, old_state, new_state); 2062 TRACE_IC("CallIC", name);
2071 } 2063 }
2072 2064
2073 2065
2074 #undef TRACE_IC 2066 #undef TRACE_IC
2075 2067
2076 2068
2077 // ---------------------------------------------------------------------------- 2069 // ----------------------------------------------------------------------------
2078 // Static IC stub generators. 2070 // Static IC stub generators.
2079 // 2071 //
2080 2072
2081 // Used from ic-<arch>.cc. 2073 // Used from ic-<arch>.cc.
2082 RUNTIME_FUNCTION(CallIC_Miss) { 2074 RUNTIME_FUNCTION(CallIC_Miss) {
2083 TimerEventScope<TimerEventIcMiss> timer(isolate); 2075 TimerEventScope<TimerEventIcMiss> timer(isolate);
2084 HandleScope scope(isolate); 2076 HandleScope scope(isolate);
2085 DCHECK(args.length() == 4); 2077 DCHECK(args.length() == 4);
2086 CallIC ic(isolate);
2087 Handle<Object> receiver = args.at<Object>(0); 2078 Handle<Object> receiver = args.at<Object>(0);
2088 Handle<Object> function = args.at<Object>(1); 2079 Handle<Object> function = args.at<Object>(1);
2089 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); 2080 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2);
2090 Handle<Smi> slot = args.at<Smi>(3); 2081 Handle<Smi> slot = args.at<Smi>(3);
2091 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); 2082 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2092 ic.HandleMiss(receiver, function, vector, vector_slot); 2083 CallICNexus nexus(vector, vector_slot);
2084 CallIC ic(isolate, &nexus);
2085 ic.HandleMiss(receiver, function);
2093 return *function; 2086 return *function;
2094 } 2087 }
2095 2088
2096 2089
2097 RUNTIME_FUNCTION(CallIC_Customization_Miss) { 2090 RUNTIME_FUNCTION(CallIC_Customization_Miss) {
2098 TimerEventScope<TimerEventIcMiss> timer(isolate); 2091 TimerEventScope<TimerEventIcMiss> timer(isolate);
2099 HandleScope scope(isolate); 2092 HandleScope scope(isolate);
2100 DCHECK(args.length() == 4); 2093 DCHECK(args.length() == 4);
2101 // A miss on a custom call ic always results in going megamorphic.
2102 CallIC ic(isolate);
2103 Handle<Object> function = args.at<Object>(1); 2094 Handle<Object> function = args.at<Object>(1);
2104 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); 2095 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2);
2105 Handle<Smi> slot = args.at<Smi>(3); 2096 Handle<Smi> slot = args.at<Smi>(3);
2106 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); 2097 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2107 ic.PatchMegamorphic(function, vector, vector_slot); 2098 CallICNexus nexus(vector, vector_slot);
2099 // A miss on a custom call ic always results in going megamorphic.
2100 CallIC ic(isolate, &nexus);
2101 ic.PatchMegamorphic(function);
2108 return *function; 2102 return *function;
2109 } 2103 }
2110 2104
2111 2105
2112 // Used from ic-<arch>.cc. 2106 // Used from ic-<arch>.cc.
2113 RUNTIME_FUNCTION(LoadIC_Miss) { 2107 RUNTIME_FUNCTION(LoadIC_Miss) {
2114 TimerEventScope<TimerEventIcMiss> timer(isolate); 2108 TimerEventScope<TimerEventIcMiss> timer(isolate);
2115 HandleScope scope(isolate); 2109 HandleScope scope(isolate);
2116 DCHECK(args.length() == 2); 2110 DCHECK(args.length() == 2);
2117 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2111 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[] = { 2730 static const Address IC_utilities[] = {
2737 #define ADDR(name) FUNCTION_ADDR(name), 2731 #define ADDR(name) FUNCTION_ADDR(name),
2738 IC_UTIL_LIST(ADDR) NULL 2732 IC_UTIL_LIST(ADDR) NULL
2739 #undef ADDR 2733 #undef ADDR
2740 }; 2734 };
2741 2735
2742 2736
2743 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 2737 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
2744 } 2738 }
2745 } // namespace v8::internal 2739 } // 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