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 |