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

Side by Side Diff: src/ic.cc

Issue 445943002: CallIC must update type feedback info correctly. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Code comments. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/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/codegen.h" 10 #include "src/codegen.h"
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 *polymorphic_delta = 1; 363 *polymorphic_delta = 1;
364 } 364 }
365 break; 365 break;
366 case PROTOTYPE_FAILURE: 366 case PROTOTYPE_FAILURE:
367 case DEBUG_STUB: 367 case DEBUG_STUB:
368 UNREACHABLE(); 368 UNREACHABLE();
369 } 369 }
370 } 370 }
371 371
372 372
373 void IC::PostPatching(Address address, Code* target, Code* old_target) { 373 void IC::OnTypeFeedbackChanged(Isolate* isolate, Address address,
374 Isolate* isolate = target->GetHeap()->isolate(); 374 State old_state, State new_state,
375 bool target_remains_ic_stub) {
375 Code* host = isolate-> 376 Code* host = isolate->
376 inner_pointer_to_code_cache()->GetCacheEntry(address)->code; 377 inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
377 if (host->kind() != Code::FUNCTION) return; 378 if (host->kind() != Code::FUNCTION) return;
378 379
379 if (FLAG_type_info_threshold > 0 && old_target->is_inline_cache_stub() && 380 if (FLAG_type_info_threshold > 0 && target_remains_ic_stub &&
380 target->is_inline_cache_stub() &&
381 // Call ICs don't have interesting state changes from this point
382 // of view.
383 target->kind() != Code::CALL_IC &&
384 // Not all Code objects have TypeFeedbackInfo. 381 // Not all Code objects have TypeFeedbackInfo.
385 host->type_feedback_info()->IsTypeFeedbackInfo()) { 382 host->type_feedback_info()->IsTypeFeedbackInfo()) {
386 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic. 383 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic.
387 int generic_delta = 0; // "Generic" here includes megamorphic. 384 int generic_delta = 0; // "Generic" here includes megamorphic.
388 ComputeTypeInfoCountDelta(old_target->ic_state(), target->ic_state(), 385 ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
389 &polymorphic_delta, &generic_delta); 386 &generic_delta);
390 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info()); 387 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
391 info->change_ic_with_type_info_count(polymorphic_delta); 388 info->change_ic_with_type_info_count(polymorphic_delta);
392 info->change_ic_generic_count(generic_delta); 389 info->change_ic_generic_count(generic_delta);
393 } 390 }
394 if (host->type_feedback_info()->IsTypeFeedbackInfo()) { 391 if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
395 TypeFeedbackInfo* info = 392 TypeFeedbackInfo* info =
396 TypeFeedbackInfo::cast(host->type_feedback_info()); 393 TypeFeedbackInfo::cast(host->type_feedback_info());
397 info->change_own_type_change_checksum(); 394 info->change_own_type_change_checksum();
398 } 395 }
399 host->set_profiler_ticks(0); 396 host->set_profiler_ticks(0);
400 isolate->runtime_profiler()->NotifyICChanged(); 397 isolate->runtime_profiler()->NotifyICChanged();
401 // TODO(2029): When an optimized function is patched, it would 398 // TODO(2029): When an optimized function is patched, it would
402 // be nice to propagate the corresponding type information to its 399 // be nice to propagate the corresponding type information to its
403 // unoptimized version for the benefit of later inlining. 400 // unoptimized version for the benefit of later inlining.
404 } 401 }
405 402
406 403
404 void IC::PostPatching(Address address, Code* target, Code* old_target) {
405 // Type vector based ICs update these statistics at a different time because
406 // they don't always patch on state change.
407 if (target->kind() == Code::CALL_IC) return;
408
409 Isolate* isolate = target->GetHeap()->isolate();
410 State old_state = UNINITIALIZED;
411 State new_state = UNINITIALIZED;
412 bool target_remains_ic_stub = false;
413 if (old_target->is_inline_cache_stub() && target->is_inline_cache_stub()) {
414 old_state = old_target->ic_state();
415 new_state = target->ic_state();
416 target_remains_ic_stub = true;
417 }
418
419 OnTypeFeedbackChanged(isolate, address, old_state, new_state,
420 target_remains_ic_stub);
421 }
422
423
407 void IC::RegisterWeakMapDependency(Handle<Code> stub) { 424 void IC::RegisterWeakMapDependency(Handle<Code> stub) {
408 if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic && 425 if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic &&
409 stub->CanBeWeakStub()) { 426 stub->CanBeWeakStub()) {
410 DCHECK(!stub->is_weak_stub()); 427 DCHECK(!stub->is_weak_stub());
411 MapHandleList maps; 428 MapHandleList maps;
412 stub->FindAllMaps(&maps); 429 stub->FindAllMaps(&maps);
413 if (maps.length() == 1 && stub->IsWeakObjectInIC(*maps.at(0))) { 430 if (maps.length() == 1 && stub->IsWeakObjectInIC(*maps.at(0))) {
414 Map::AddDependentIC(maps.at(0), stub); 431 Map::AddDependentIC(maps.at(0), stub);
415 stub->mark_as_weak_stub(); 432 stub->mark_as_weak_stub();
416 if (FLAG_enable_ool_constant_pool) { 433 if (FLAG_enable_ool_constant_pool) {
(...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after
1913 1930
1914 CallIC_ArrayStub stub(isolate(), state); 1931 CallIC_ArrayStub stub(isolate(), state);
1915 set_target(*stub.GetCode()); 1932 set_target(*stub.GetCode());
1916 Handle<String> name; 1933 Handle<String> name;
1917 if (array_function->shared()->name()->IsString()) { 1934 if (array_function->shared()->name()->IsString()) {
1918 name = Handle<String>(String::cast(array_function->shared()->name()), 1935 name = Handle<String>(String::cast(array_function->shared()->name()),
1919 isolate()); 1936 isolate());
1920 } 1937 }
1921 1938
1922 TRACE_IC("CallIC (Array call)", name); 1939 TRACE_IC("CallIC (Array call)", name);
1940 Object* new_feedback = vector->get(slot->value());
1941 UpdateTypeFeedbackInfo(feedback, new_feedback);
1923 return true; 1942 return true;
1924 } 1943 }
1925 return false; 1944 return false;
1926 } 1945 }
1927 1946
1928 1947
1929 void CallIC::PatchMegamorphic(Handle<FixedArray> vector, 1948 void CallIC::PatchMegamorphic(Handle<FixedArray> vector,
1930 Handle<Smi> slot) { 1949 Handle<Smi> slot) {
1931 State state(target()->extra_ic_state()); 1950 State state(target()->extra_ic_state());
1932 1951
1933 // We are going generic. 1952 // We are going generic.
1934 vector->set(slot->value(), 1953 vector->set(slot->value(),
1935 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), 1954 *TypeFeedbackInfo::MegamorphicSentinel(isolate()),
1936 SKIP_WRITE_BARRIER); 1955 SKIP_WRITE_BARRIER);
1937 1956
1938 CallICStub stub(isolate(), state); 1957 CallICStub stub(isolate(), state);
1939 Handle<Code> code = stub.GetCode(); 1958 Handle<Code> code = stub.GetCode();
1940 set_target(*code); 1959 set_target(*code);
1941 1960
1942 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); 1961 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
1943 } 1962 }
1944 1963
1945 1964
1965 void CallIC::UpdateTypeFeedbackInfo(Object* old_feedback,
1966 Object* new_feedback) {
1967 IC::State old_state = FeedbackObjectToState(old_feedback);
1968 IC::State new_state = FeedbackObjectToState(new_feedback);
1969 OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
1970 }
1971
1972
1946 void CallIC::HandleMiss(Handle<Object> receiver, 1973 void CallIC::HandleMiss(Handle<Object> receiver,
1947 Handle<Object> function, 1974 Handle<Object> function,
1948 Handle<FixedArray> vector, 1975 Handle<FixedArray> vector,
1949 Handle<Smi> slot) { 1976 Handle<Smi> slot) {
1950 State state(target()->extra_ic_state()); 1977 State state(target()->extra_ic_state());
1951 Object* feedback = vector->get(slot->value()); 1978 Object* feedback = vector->get(slot->value());
1952 1979
1953 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. 1980 // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
1954 DCHECK(!feedback->IsSmi()); 1981 DCHECK(!feedback->IsSmi());
1955 1982
(...skipping 18 matching lines...) Expand all
1974 if (FLAG_use_ic && 2001 if (FLAG_use_ic &&
1975 DoCustomHandler(receiver, function, vector, slot, state)) { 2002 DoCustomHandler(receiver, function, vector, slot, state)) {
1976 return; 2003 return;
1977 } 2004 }
1978 2005
1979 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); 2006 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
1980 Handle<Object> name(js_function->shared()->name(), isolate()); 2007 Handle<Object> name(js_function->shared()->name(), isolate());
1981 TRACE_IC("CallIC", name); 2008 TRACE_IC("CallIC", name);
1982 vector->set(slot->value(), *function); 2009 vector->set(slot->value(), *function);
1983 } 2010 }
2011
2012 Object* new_feedback = vector->get(slot->value());
2013 UpdateTypeFeedbackInfo(feedback, new_feedback);
1984 } 2014 }
1985 2015
1986 2016
1987 #undef TRACE_IC 2017 #undef TRACE_IC
1988 2018
1989 2019
1990 // ---------------------------------------------------------------------------- 2020 // ----------------------------------------------------------------------------
1991 // Static IC stub generators. 2021 // Static IC stub generators.
1992 // 2022 //
1993 2023
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after
3092 #undef ADDR 3122 #undef ADDR
3093 }; 3123 };
3094 3124
3095 3125
3096 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3126 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3097 return IC_utilities[id]; 3127 return IC_utilities[id];
3098 } 3128 }
3099 3129
3100 3130
3101 } } // namespace v8::internal 3131 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698