Chromium Code Reviews| 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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 } | 369 } |
| 370 } | 370 } |
| 371 | 371 |
| 372 | 372 |
| 373 void IC::PostPatching(Address address, Code* target, Code* old_target) { | 373 void IC::PostPatching(Address address, Code* target, Code* old_target) { |
| 374 Isolate* isolate = target->GetHeap()->isolate(); | 374 Isolate* isolate = target->GetHeap()->isolate(); |
| 375 Code* host = isolate-> | 375 Code* host = isolate-> |
| 376 inner_pointer_to_code_cache()->GetCacheEntry(address)->code; | 376 inner_pointer_to_code_cache()->GetCacheEntry(address)->code; |
| 377 if (host->kind() != Code::FUNCTION) return; | 377 if (host->kind() != Code::FUNCTION) return; |
| 378 | 378 |
| 379 // Type vector based ICs update these statistics differently. | |
| 380 if (target->kind() == Code::CALL_IC) return; | |
| 381 | |
| 379 if (FLAG_type_info_threshold > 0 && old_target->is_inline_cache_stub() && | 382 if (FLAG_type_info_threshold > 0 && old_target->is_inline_cache_stub() && |
| 380 target->is_inline_cache_stub() && | 383 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. | 384 // Not all Code objects have TypeFeedbackInfo. |
| 385 host->type_feedback_info()->IsTypeFeedbackInfo()) { | 385 host->type_feedback_info()->IsTypeFeedbackInfo()) { |
| 386 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic. | 386 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic. |
| 387 int generic_delta = 0; // "Generic" here includes megamorphic. | 387 int generic_delta = 0; // "Generic" here includes megamorphic. |
| 388 ComputeTypeInfoCountDelta(old_target->ic_state(), target->ic_state(), | 388 ComputeTypeInfoCountDelta(old_target->ic_state(), target->ic_state(), |
| 389 &polymorphic_delta, &generic_delta); | 389 &polymorphic_delta, &generic_delta); |
| 390 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info()); | 390 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info()); |
| 391 info->change_ic_with_type_info_count(polymorphic_delta); | 391 info->change_ic_with_type_info_count(polymorphic_delta); |
| 392 info->change_ic_generic_count(generic_delta); | 392 info->change_ic_generic_count(generic_delta); |
| 393 } | 393 } |
| (...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1913 | 1913 |
| 1914 CallIC_ArrayStub stub(isolate(), state); | 1914 CallIC_ArrayStub stub(isolate(), state); |
| 1915 set_target(*stub.GetCode()); | 1915 set_target(*stub.GetCode()); |
| 1916 Handle<String> name; | 1916 Handle<String> name; |
| 1917 if (array_function->shared()->name()->IsString()) { | 1917 if (array_function->shared()->name()->IsString()) { |
| 1918 name = Handle<String>(String::cast(array_function->shared()->name()), | 1918 name = Handle<String>(String::cast(array_function->shared()->name()), |
| 1919 isolate()); | 1919 isolate()); |
| 1920 } | 1920 } |
| 1921 | 1921 |
| 1922 TRACE_IC("CallIC (Array call)", name); | 1922 TRACE_IC("CallIC (Array call)", name); |
| 1923 Object* new_feedback = vector->get(slot->value()); | |
| 1924 UpdateTypeFeedbackInfo(feedback, new_feedback); | |
| 1923 return true; | 1925 return true; |
| 1924 } | 1926 } |
| 1925 return false; | 1927 return false; |
| 1926 } | 1928 } |
| 1927 | 1929 |
| 1928 | 1930 |
| 1929 void CallIC::PatchMegamorphic(Handle<FixedArray> vector, | 1931 void CallIC::PatchMegamorphic(Handle<FixedArray> vector, |
| 1930 Handle<Smi> slot) { | 1932 Handle<Smi> slot) { |
| 1931 State state(target()->extra_ic_state()); | 1933 State state(target()->extra_ic_state()); |
| 1932 | 1934 |
| 1933 // We are going generic. | 1935 // We are going generic. |
| 1934 vector->set(slot->value(), | 1936 vector->set(slot->value(), |
| 1935 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), | 1937 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), |
| 1936 SKIP_WRITE_BARRIER); | 1938 SKIP_WRITE_BARRIER); |
| 1937 | 1939 |
| 1938 CallICStub stub(isolate(), state); | 1940 CallICStub stub(isolate(), state); |
| 1939 Handle<Code> code = stub.GetCode(); | 1941 Handle<Code> code = stub.GetCode(); |
| 1940 set_target(*code); | 1942 set_target(*code); |
| 1941 | 1943 |
| 1942 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); | 1944 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); |
| 1943 } | 1945 } |
| 1944 | 1946 |
| 1945 | 1947 |
| 1948 IC::State CallIC::FeedbackObjectToState(Object* feedback) { | |
| 1949 IC::State state = UNINITIALIZED; | |
| 1950 | |
| 1951 if (feedback == *TypeFeedbackInfo::MegamorphicSentinel(isolate())) { | |
| 1952 state = GENERIC; | |
| 1953 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { | |
| 1954 state = MONOMORPHIC; | |
| 1955 } else { | |
| 1956 CHECK(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())); | |
| 1957 } | |
| 1958 | |
| 1959 return state; | |
| 1960 } | |
| 1961 | |
| 1962 | |
| 1963 void CallIC::UpdateTypeFeedbackInfo(Object* old_feedback, Object* new_feedback) { | |
|
Jakob Kummerow
2014/08/06 14:49:09
nit: 80col
mvstanton
2014/08/06 15:32:33
Done.
| |
| 1964 // Convert old_feedback to an IC_State enum: | |
|
Jakob Kummerow
2014/08/06 14:49:09
This comment seems to belong to line 1971, but I d
mvstanton
2014/08/06 15:32:33
Done.
| |
| 1965 Code* host = isolate()-> | |
|
Jakob Kummerow
2014/08/06 14:49:09
Idea for reducing code duplication: pull out most
mvstanton
2014/08/06 15:32:33
Excellent idea, done. I think the cost of computin
| |
| 1966 inner_pointer_to_code_cache()->GetCacheEntry(address())->code; | |
| 1967 if (host->kind() != Code::FUNCTION) return; | |
| 1968 | |
| 1969 if (FLAG_type_info_threshold > 0 && | |
| 1970 host->type_feedback_info()->IsTypeFeedbackInfo()) { | |
| 1971 IC::State old_state = FeedbackObjectToState(old_feedback); | |
| 1972 IC::State new_state = FeedbackObjectToState(new_feedback); | |
| 1973 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic. | |
| 1974 int generic_delta = 0; // "Generic" here includes megamorphic. | |
| 1975 ComputeTypeInfoCountDelta(old_state, new_state, | |
| 1976 &polymorphic_delta, &generic_delta); | |
| 1977 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info()); | |
| 1978 info->change_ic_with_type_info_count(polymorphic_delta); | |
| 1979 info->change_ic_generic_count(generic_delta); | |
| 1980 } | |
| 1981 if (host->type_feedback_info()->IsTypeFeedbackInfo()) { | |
| 1982 TypeFeedbackInfo* info = | |
| 1983 TypeFeedbackInfo::cast(host->type_feedback_info()); | |
| 1984 info->change_own_type_change_checksum(); | |
| 1985 } | |
| 1986 host->set_profiler_ticks(0); | |
| 1987 isolate()->runtime_profiler()->NotifyICChanged(); | |
| 1988 } | |
| 1989 | |
| 1990 | |
| 1946 void CallIC::HandleMiss(Handle<Object> receiver, | 1991 void CallIC::HandleMiss(Handle<Object> receiver, |
| 1947 Handle<Object> function, | 1992 Handle<Object> function, |
| 1948 Handle<FixedArray> vector, | 1993 Handle<FixedArray> vector, |
| 1949 Handle<Smi> slot) { | 1994 Handle<Smi> slot) { |
| 1950 State state(target()->extra_ic_state()); | 1995 State state(target()->extra_ic_state()); |
| 1951 Object* feedback = vector->get(slot->value()); | 1996 Object* feedback = vector->get(slot->value()); |
| 1952 | 1997 |
| 1953 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. | 1998 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. |
| 1954 DCHECK(!feedback->IsSmi()); | 1999 DCHECK(!feedback->IsSmi()); |
| 1955 | 2000 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1974 if (FLAG_use_ic && | 2019 if (FLAG_use_ic && |
| 1975 DoCustomHandler(receiver, function, vector, slot, state)) { | 2020 DoCustomHandler(receiver, function, vector, slot, state)) { |
| 1976 return; | 2021 return; |
| 1977 } | 2022 } |
| 1978 | 2023 |
| 1979 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); | 2024 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); |
| 1980 Handle<Object> name(js_function->shared()->name(), isolate()); | 2025 Handle<Object> name(js_function->shared()->name(), isolate()); |
| 1981 TRACE_IC("CallIC", name); | 2026 TRACE_IC("CallIC", name); |
| 1982 vector->set(slot->value(), *function); | 2027 vector->set(slot->value(), *function); |
| 1983 } | 2028 } |
| 2029 | |
| 2030 Object* new_feedback = vector->get(slot->value()); | |
| 2031 UpdateTypeFeedbackInfo(feedback, new_feedback); | |
| 1984 } | 2032 } |
| 1985 | 2033 |
| 1986 | 2034 |
| 1987 #undef TRACE_IC | 2035 #undef TRACE_IC |
| 1988 | 2036 |
| 1989 | 2037 |
| 1990 // ---------------------------------------------------------------------------- | 2038 // ---------------------------------------------------------------------------- |
| 1991 // Static IC stub generators. | 2039 // Static IC stub generators. |
| 1992 // | 2040 // |
| 1993 | 2041 |
| (...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3092 #undef ADDR | 3140 #undef ADDR |
| 3093 }; | 3141 }; |
| 3094 | 3142 |
| 3095 | 3143 |
| 3096 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3144 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 3097 return IC_utilities[id]; | 3145 return IC_utilities[id]; |
| 3098 } | 3146 } |
| 3099 | 3147 |
| 3100 | 3148 |
| 3101 } } // namespace v8::internal | 3149 } } // namespace v8::internal |
| OLD | NEW |