OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |