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/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 RelocInfo::Mode mode = it.rinfo()->rmode(); | 468 RelocInfo::Mode mode = it.rinfo()->rmode(); |
| 469 if (mode == RelocInfo::EMBEDDED_OBJECT && | 469 if (mode == RelocInfo::EMBEDDED_OBJECT && |
| 470 it.rinfo()->target_object()->IsMap()) { | 470 it.rinfo()->target_object()->IsMap()) { |
| 471 it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER); | 471 it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER); |
| 472 } | 472 } |
| 473 } | 473 } |
| 474 CpuFeatures::FlushICache(stub->instruction_start(), stub->instruction_size()); | 474 CpuFeatures::FlushICache(stub->instruction_start(), stub->instruction_size()); |
| 475 } | 475 } |
| 476 | 476 |
| 477 | 477 |
| 478 void IC::Clear(Isolate* isolate, Address address, | 478 void IC::Clear(Isolate* isolate, Address address, TypeFeedbackVector* vector, |
| 479 ConstantPoolArray* constant_pool) { | 479 FeedbackVectorICSlot slot, ConstantPoolArray* constant_pool) { |
| 480 Code* target = GetTargetAtAddress(address, constant_pool); | 480 Code* target = GetTargetAtAddress(address, constant_pool); |
| 481 | 481 |
| 482 // Don't clear debug break inline cache as it will remove the break point. | 482 // Don't clear debug break inline cache as it will remove the break point. |
| 483 if (target->is_debug_stub()) return; | 483 if (target->is_debug_stub()) return; |
| 484 | 484 |
| 485 switch (target->kind()) { | 485 switch (target->kind()) { |
| 486 case Code::LOAD_IC: | 486 case Code::LOAD_IC: |
| 487 return LoadIC::Clear(isolate, address, target, constant_pool); | 487 return LoadIC::Clear(isolate, address, target, vector, slot, |
| 488 constant_pool); | |
| 488 case Code::KEYED_LOAD_IC: | 489 case Code::KEYED_LOAD_IC: |
| 489 return KeyedLoadIC::Clear(isolate, address, target, constant_pool); | 490 return KeyedLoadIC::Clear(isolate, address, target, vector, slot, |
| 491 constant_pool); | |
| 490 case Code::STORE_IC: | 492 case Code::STORE_IC: |
| 491 return StoreIC::Clear(isolate, address, target, constant_pool); | 493 return StoreIC::Clear(isolate, address, target, constant_pool); |
| 492 case Code::KEYED_STORE_IC: | 494 case Code::KEYED_STORE_IC: |
| 493 return KeyedStoreIC::Clear(isolate, address, target, constant_pool); | 495 return KeyedStoreIC::Clear(isolate, address, target, constant_pool); |
| 494 case Code::CALL_IC: | 496 case Code::CALL_IC: |
| 495 return CallIC::Clear(isolate, address, target, constant_pool); | 497 return CallIC::Clear(isolate, address, target, vector, slot, |
| 498 constant_pool); | |
| 496 case Code::COMPARE_IC: | 499 case Code::COMPARE_IC: |
| 497 return CompareIC::Clear(isolate, address, target, constant_pool); | 500 return CompareIC::Clear(isolate, address, target, constant_pool); |
| 498 case Code::COMPARE_NIL_IC: | 501 case Code::COMPARE_NIL_IC: |
| 499 return CompareNilIC::Clear(address, target, constant_pool); | 502 return CompareNilIC::Clear(address, target, constant_pool); |
| 500 case Code::BINARY_OP_IC: | 503 case Code::BINARY_OP_IC: |
| 501 case Code::TO_BOOLEAN_IC: | 504 case Code::TO_BOOLEAN_IC: |
| 502 // Clearing these is tricky and does not | 505 // Clearing these is tricky and does not |
| 503 // make any performance difference. | 506 // make any performance difference. |
| 504 return; | 507 return; |
| 505 default: | 508 default: |
| 506 UNREACHABLE(); | 509 UNREACHABLE(); |
| 507 } | 510 } |
| 508 } | 511 } |
| 509 | 512 |
| 510 | 513 |
| 511 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target, | 514 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target, |
| 515 TypeFeedbackVector* vector, FeedbackVectorICSlot slot, | |
| 512 ConstantPoolArray* constant_pool) { | 516 ConstantPoolArray* constant_pool) { |
| 513 if (IsCleared(target)) return; | 517 if (IsCleared(target)) return; |
| 514 | 518 |
| 515 // If the target is the string_stub, then don't clear it. It is the | 519 // If the target is the string_stub, then don't clear it. It is the |
| 516 // perfect stub if we continue to see strings. Holding this | 520 // perfect stub if we continue to see strings. Holding this |
| 517 // state is not preventing learning new information. | 521 // state is not preventing learning new information. |
| 518 if (target != *isolate->builtins()->KeyedLoadIC_String()) { | 522 if (target != *isolate->builtins()->KeyedLoadIC_String()) { |
| 519 // Make sure to also clear the map used in inline fast cases. If we | 523 // Make sure to also clear the map used in inline fast cases. If we |
| 520 // do not clear these maps, cached code can keep objects alive | 524 // do not clear these maps, cached code can keep objects alive |
| 521 // through the embedded maps. | 525 // through the embedded maps. |
| 522 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); | 526 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); |
| 523 } | 527 } |
| 524 } | 528 } |
| 525 | 529 |
| 526 | 530 |
| 527 void CallIC::Clear(Isolate* isolate, Address address, Code* target, | 531 void CallIC::Clear(Isolate* isolate, Address address, Code* target, |
| 532 TypeFeedbackVector* vector, FeedbackVectorICSlot slot, | |
| 528 ConstantPoolArray* constant_pool) { | 533 ConstantPoolArray* constant_pool) { |
| 529 // Currently, CallIC doesn't have state changes. | 534 if (vector != NULL) { |
| 535 Object* feedback = vector->Get(slot); | |
| 536 // Determine our state. | |
| 537 State state = FeedbackToState(isolate, vector, slot); | |
| 538 | |
| 539 if (!feedback->IsAllocationSite()) { | |
| 540 vector->Set(slot, *TypeFeedbackVector::UninitializedSentinel(isolate)); | |
| 541 // The change in state must be processed. | |
| 542 OnTypeFeedbackChanged(isolate, address, vector, state, UNINITIALIZED); | |
| 543 } | |
| 544 } | |
| 530 } | 545 } |
| 531 | 546 |
| 532 | 547 |
| 533 void LoadIC::Clear(Isolate* isolate, Address address, Code* target, | 548 void LoadIC::Clear(Isolate* isolate, Address address, Code* target, |
| 549 TypeFeedbackVector* vector, FeedbackVectorICSlot slot, | |
| 534 ConstantPoolArray* constant_pool) { | 550 ConstantPoolArray* constant_pool) { |
| 535 if (IsCleared(target)) return; | 551 if (IsCleared(target)) return; |
| 536 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC, | 552 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC, |
| 537 target->extra_ic_state()); | 553 target->extra_ic_state()); |
| 538 SetTargetAtAddress(address, code, constant_pool); | 554 SetTargetAtAddress(address, code, constant_pool); |
| 539 } | 555 } |
| 540 | 556 |
| 541 | 557 |
| 542 void StoreIC::Clear(Isolate* isolate, Address address, Code* target, | 558 void StoreIC::Clear(Isolate* isolate, Address address, Code* target, |
| 543 ConstantPoolArray* constant_pool) { | 559 ConstantPoolArray* constant_pool) { |
| (...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1922 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); | 1938 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); |
| 1923 } | 1939 } |
| 1924 DCHECK(!stub.is_null()); | 1940 DCHECK(!stub.is_null()); |
| 1925 set_target(*stub); | 1941 set_target(*stub); |
| 1926 TRACE_IC("StoreIC", key); | 1942 TRACE_IC("StoreIC", key); |
| 1927 | 1943 |
| 1928 return store_handle; | 1944 return store_handle; |
| 1929 } | 1945 } |
| 1930 | 1946 |
| 1931 | 1947 |
| 1948 // static | |
| 1949 void CallIC::OnTypeFeedbackChanged(Isolate* isolate, Address address, | |
| 1950 TypeFeedbackVector* vector, State old_state, | |
| 1951 State new_state) { | |
| 1952 Code* host = | |
| 1953 isolate->inner_pointer_to_code_cache()->GetCacheEntry(address)->code; | |
| 1954 if (host->kind() != Code::FUNCTION) return; | |
| 1955 | |
| 1956 if (FLAG_type_info_threshold > 0) { | |
| 1957 int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic. | |
| 1958 int generic_delta = 0; // "Generic" here includes megamorphic. | |
| 1959 ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta, | |
| 1960 &generic_delta); | |
| 1961 vector->change_ic_with_type_info_count(polymorphic_delta); | |
| 1962 vector->change_ic_generic_count(generic_delta); | |
| 1963 } | |
| 1964 if (host->type_feedback_info()->IsTypeFeedbackInfo()) { | |
|
ulan
2014/10/15 10:17:05
Can we have a vector without having type_feedback_
mvstanton
2014/10/16 10:54:14
Indeed, it looks like we can count on this because
| |
| 1965 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info()); | |
| 1966 info->change_own_type_change_checksum(); | |
| 1967 } | |
| 1968 host->set_profiler_ticks(0); | |
| 1969 isolate->runtime_profiler()->NotifyICChanged(); | |
| 1970 // TODO(2029): When an optimized function is patched, it would | |
| 1971 // be nice to propagate the corresponding type information to its | |
| 1972 // unoptimized version for the benefit of later inlining. | |
| 1973 } | |
| 1974 | |
| 1975 | |
| 1932 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, | 1976 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, |
| 1933 Handle<TypeFeedbackVector> vector, | 1977 Handle<TypeFeedbackVector> vector, |
| 1934 Handle<Smi> slot, const CallICState& state) { | 1978 FeedbackVectorICSlot slot, |
| 1979 const CallICState& state) { | |
| 1935 DCHECK(FLAG_use_ic && function->IsJSFunction()); | 1980 DCHECK(FLAG_use_ic && function->IsJSFunction()); |
| 1936 | 1981 |
| 1937 // Are we the array function? | 1982 // Are we the array function? |
| 1938 Handle<JSFunction> array_function = | 1983 Handle<JSFunction> array_function = |
| 1939 Handle<JSFunction>(isolate()->native_context()->array_function()); | 1984 Handle<JSFunction>(isolate()->native_context()->array_function()); |
| 1940 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { | 1985 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { |
| 1941 // Alter the slot. | 1986 // Alter the slot. |
| 1942 IC::State old_state = FeedbackToState(vector, slot); | 1987 IC::State old_state = FeedbackToState(vector, slot); |
| 1943 Object* feedback = vector->get(slot->value()); | 1988 Object* feedback = vector->Get(slot); |
| 1944 if (!feedback->IsAllocationSite()) { | 1989 if (!feedback->IsAllocationSite()) { |
| 1945 Handle<AllocationSite> new_site = | 1990 Handle<AllocationSite> new_site = |
| 1946 isolate()->factory()->NewAllocationSite(); | 1991 isolate()->factory()->NewAllocationSite(); |
| 1947 vector->set(slot->value(), *new_site); | 1992 vector->Set(slot, *new_site); |
| 1948 } | 1993 } |
| 1949 | 1994 |
| 1950 CallIC_ArrayStub stub(isolate(), state); | 1995 CallIC_ArrayStub stub(isolate(), state); |
| 1951 set_target(*stub.GetCode()); | 1996 set_target(*stub.GetCode()); |
| 1952 Handle<String> name; | 1997 Handle<String> name; |
| 1953 if (array_function->shared()->name()->IsString()) { | 1998 if (array_function->shared()->name()->IsString()) { |
| 1954 name = Handle<String>(String::cast(array_function->shared()->name()), | 1999 name = Handle<String>(String::cast(array_function->shared()->name()), |
| 1955 isolate()); | 2000 isolate()); |
| 1956 } | 2001 } |
| 1957 | 2002 |
| 1958 IC::State new_state = FeedbackToState(vector, slot); | 2003 IC::State new_state = FeedbackToState(vector, slot); |
| 1959 OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); | 2004 OnTypeFeedbackChanged(vector, old_state, new_state); |
| 1960 TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state); | 2005 TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state); |
| 1961 return true; | 2006 return true; |
| 1962 } | 2007 } |
| 1963 return false; | 2008 return false; |
| 1964 } | 2009 } |
| 1965 | 2010 |
| 1966 | 2011 |
| 1967 void CallIC::PatchMegamorphic(Handle<Object> function, | 2012 void CallIC::PatchMegamorphic(Handle<Object> function, |
| 1968 Handle<TypeFeedbackVector> vector, | 2013 Handle<TypeFeedbackVector> vector, |
| 1969 Handle<Smi> slot) { | 2014 FeedbackVectorICSlot slot) { |
| 1970 CallICState state(target()->extra_ic_state()); | 2015 CallICState state(target()->extra_ic_state()); |
| 1971 IC::State old_state = FeedbackToState(vector, slot); | 2016 IC::State old_state = FeedbackToState(vector, slot); |
| 1972 | 2017 |
| 1973 // We are going generic. | 2018 // We are going generic. |
| 1974 vector->set(slot->value(), | 2019 vector->Set(slot, *TypeFeedbackVector::MegamorphicSentinel(isolate()), |
| 1975 *TypeFeedbackVector::MegamorphicSentinel(isolate()), | |
| 1976 SKIP_WRITE_BARRIER); | 2020 SKIP_WRITE_BARRIER); |
| 1977 | 2021 |
| 1978 CallICStub stub(isolate(), state); | 2022 CallICStub stub(isolate(), state); |
| 1979 Handle<Code> code = stub.GetCode(); | 2023 Handle<Code> code = stub.GetCode(); |
| 1980 set_target(*code); | 2024 set_target(*code); |
| 1981 | 2025 |
| 1982 Handle<Object> name = isolate()->factory()->empty_string(); | 2026 Handle<Object> name = isolate()->factory()->empty_string(); |
| 1983 if (function->IsJSFunction()) { | 2027 if (function->IsJSFunction()) { |
| 1984 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); | 2028 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); |
| 1985 name = handle(js_function->shared()->name(), isolate()); | 2029 name = handle(js_function->shared()->name(), isolate()); |
| 1986 } | 2030 } |
| 1987 | 2031 |
| 1988 IC::State new_state = FeedbackToState(vector, slot); | 2032 IC::State new_state = FeedbackToState(vector, slot); |
| 1989 OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); | 2033 OnTypeFeedbackChanged(vector, old_state, new_state); |
| 1990 TRACE_VECTOR_IC("CallIC", name, old_state, new_state); | 2034 TRACE_VECTOR_IC("CallIC", name, old_state, new_state); |
| 1991 } | 2035 } |
| 1992 | 2036 |
| 1993 | 2037 |
| 1994 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function, | 2038 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function, |
| 1995 Handle<TypeFeedbackVector> vector, Handle<Smi> slot) { | 2039 Handle<TypeFeedbackVector> vector, |
| 2040 FeedbackVectorICSlot slot) { | |
| 1996 CallICState state(target()->extra_ic_state()); | 2041 CallICState state(target()->extra_ic_state()); |
| 1997 IC::State old_state = FeedbackToState(vector, slot); | 2042 IC::State old_state = FeedbackToState(vector, slot); |
| 1998 Handle<Object> name = isolate()->factory()->empty_string(); | 2043 Handle<Object> name = isolate()->factory()->empty_string(); |
| 1999 Object* feedback = vector->get(slot->value()); | 2044 Object* feedback = vector->Get(slot); |
| 2000 | 2045 |
| 2001 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. | 2046 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. |
| 2002 DCHECK(!feedback->IsSmi()); | 2047 DCHECK(!feedback->IsSmi()); |
| 2003 | 2048 |
| 2004 if (feedback->IsJSFunction() || !function->IsJSFunction()) { | 2049 if (feedback->IsJSFunction() || !function->IsJSFunction()) { |
| 2005 // We are going generic. | 2050 // We are going generic. |
| 2006 vector->set(slot->value(), | 2051 vector->Set(slot, *TypeFeedbackVector::MegamorphicSentinel(isolate()), |
| 2007 *TypeFeedbackVector::MegamorphicSentinel(isolate()), | |
| 2008 SKIP_WRITE_BARRIER); | 2052 SKIP_WRITE_BARRIER); |
| 2009 } else { | 2053 } else { |
| 2010 // The feedback is either uninitialized or an allocation site. | 2054 // The feedback is either uninitialized or an allocation site. |
| 2011 // It might be an allocation site because if we re-compile the full code | 2055 // It might be an allocation site because if we re-compile the full code |
| 2012 // to add deoptimization support, we call with the default call-ic, and | 2056 // to add deoptimization support, we call with the default call-ic, and |
| 2013 // merely need to patch the target to match the feedback. | 2057 // merely need to patch the target to match the feedback. |
| 2014 // TODO(mvstanton): the better approach is to dispense with patching | 2058 // TODO(mvstanton): the better approach is to dispense with patching |
| 2015 // altogether, which is in progress. | 2059 // altogether, which is in progress. |
| 2016 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || | 2060 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || |
| 2017 feedback->IsAllocationSite()); | 2061 feedback->IsAllocationSite()); |
| 2018 | 2062 |
| 2019 // Do we want to install a custom handler? | 2063 // Do we want to install a custom handler? |
| 2020 if (FLAG_use_ic && | 2064 if (FLAG_use_ic && |
| 2021 DoCustomHandler(receiver, function, vector, slot, state)) { | 2065 DoCustomHandler(receiver, function, vector, slot, state)) { |
| 2022 return; | 2066 return; |
| 2023 } | 2067 } |
| 2024 | 2068 |
| 2025 vector->set(slot->value(), *function); | 2069 vector->Set(slot, *function); |
| 2026 } | 2070 } |
| 2027 | 2071 |
| 2028 if (function->IsJSFunction()) { | 2072 if (function->IsJSFunction()) { |
| 2029 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); | 2073 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); |
| 2030 name = handle(js_function->shared()->name(), isolate()); | 2074 name = handle(js_function->shared()->name(), isolate()); |
| 2031 } | 2075 } |
| 2032 | 2076 |
| 2033 IC::State new_state = FeedbackToState(vector, slot); | 2077 IC::State new_state = FeedbackToState(vector, slot); |
| 2034 OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); | 2078 OnTypeFeedbackChanged(vector, old_state, new_state); |
| 2035 TRACE_VECTOR_IC("CallIC", name, old_state, new_state); | 2079 TRACE_VECTOR_IC("CallIC", name, old_state, new_state); |
| 2036 } | 2080 } |
| 2037 | 2081 |
| 2038 | 2082 |
| 2039 #undef TRACE_IC | 2083 #undef TRACE_IC |
| 2040 | 2084 |
| 2041 | 2085 |
| 2042 // ---------------------------------------------------------------------------- | 2086 // ---------------------------------------------------------------------------- |
| 2043 // Static IC stub generators. | 2087 // Static IC stub generators. |
| 2044 // | 2088 // |
| 2045 | 2089 |
| 2046 // Used from ic-<arch>.cc. | 2090 // Used from ic-<arch>.cc. |
| 2047 RUNTIME_FUNCTION(CallIC_Miss) { | 2091 RUNTIME_FUNCTION(CallIC_Miss) { |
| 2048 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2092 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2049 HandleScope scope(isolate); | 2093 HandleScope scope(isolate); |
| 2050 DCHECK(args.length() == 4); | 2094 DCHECK(args.length() == 4); |
| 2051 CallIC ic(isolate); | 2095 CallIC ic(isolate); |
| 2052 Handle<Object> receiver = args.at<Object>(0); | 2096 Handle<Object> receiver = args.at<Object>(0); |
| 2053 Handle<Object> function = args.at<Object>(1); | 2097 Handle<Object> function = args.at<Object>(1); |
| 2054 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); | 2098 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); |
| 2055 Handle<Smi> slot = args.at<Smi>(3); | 2099 Handle<Smi> slot = args.at<Smi>(3); |
| 2056 ic.HandleMiss(receiver, function, vector, slot); | 2100 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); |
| 2101 ic.HandleMiss(receiver, function, vector, vector_slot); | |
| 2057 return *function; | 2102 return *function; |
| 2058 } | 2103 } |
| 2059 | 2104 |
| 2060 | 2105 |
| 2061 RUNTIME_FUNCTION(CallIC_Customization_Miss) { | 2106 RUNTIME_FUNCTION(CallIC_Customization_Miss) { |
| 2062 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2107 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2063 HandleScope scope(isolate); | 2108 HandleScope scope(isolate); |
| 2064 DCHECK(args.length() == 4); | 2109 DCHECK(args.length() == 4); |
| 2065 // A miss on a custom call ic always results in going megamorphic. | 2110 // A miss on a custom call ic always results in going megamorphic. |
| 2066 CallIC ic(isolate); | 2111 CallIC ic(isolate); |
| 2067 Handle<Object> function = args.at<Object>(1); | 2112 Handle<Object> function = args.at<Object>(1); |
| 2068 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); | 2113 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); |
| 2069 Handle<Smi> slot = args.at<Smi>(3); | 2114 Handle<Smi> slot = args.at<Smi>(3); |
| 2070 ic.PatchMegamorphic(function, vector, slot); | 2115 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); |
| 2116 ic.PatchMegamorphic(function, vector, vector_slot); | |
| 2071 return *function; | 2117 return *function; |
| 2072 } | 2118 } |
| 2073 | 2119 |
| 2074 | 2120 |
| 2075 // Used from ic-<arch>.cc. | 2121 // Used from ic-<arch>.cc. |
| 2076 RUNTIME_FUNCTION(LoadIC_Miss) { | 2122 RUNTIME_FUNCTION(LoadIC_Miss) { |
| 2077 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2123 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2078 HandleScope scope(isolate); | 2124 HandleScope scope(isolate); |
| 2079 DCHECK(args.length() == 2); | 2125 DCHECK(args.length() == 2); |
| 2080 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); | 2126 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2699 static const Address IC_utilities[] = { | 2745 static const Address IC_utilities[] = { |
| 2700 #define ADDR(name) FUNCTION_ADDR(name), | 2746 #define ADDR(name) FUNCTION_ADDR(name), |
| 2701 IC_UTIL_LIST(ADDR) NULL | 2747 IC_UTIL_LIST(ADDR) NULL |
| 2702 #undef ADDR | 2748 #undef ADDR |
| 2703 }; | 2749 }; |
| 2704 | 2750 |
| 2705 | 2751 |
| 2706 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 2752 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
| 2707 } | 2753 } |
| 2708 } // namespace v8::internal | 2754 } // namespace v8::internal |
| OLD | NEW |