| 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 |