| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 90d77f2ae1d797e3bcf31f9b24b849d75e5477d8..2139d5c5fc2d51e8a48f0faa9ade5c1d6b50c691 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -33,6 +33,9 @@ char IC::TransitionMarkFromState(IC::State state) {
|
| // computed from the original code - not the patched code. Let
|
| // these cases fall through to the unreachable code below.
|
| case DEBUG_STUB: break;
|
| + // Type-vector-based ICs resolve state to one of the above.
|
| + case DEFAULT:
|
| + break;
|
| }
|
| UNREACHABLE();
|
| return 0;
|
| @@ -66,10 +69,20 @@ const char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) {
|
|
|
| #endif // DEBUG
|
|
|
| +
|
| void IC::TraceIC(const char* type, Handle<Object> name) {
|
| if (FLAG_trace_ic) {
|
| Code* new_target = raw_target();
|
| State new_state = new_target->ic_state();
|
| + TraceIC(type, name, state(), new_state);
|
| + }
|
| +}
|
| +
|
| +
|
| +void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
|
| + State new_state) {
|
| + if (FLAG_trace_ic) {
|
| + Code* new_target = raw_target();
|
| PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type);
|
|
|
| // TODO(jkummerow): Add support for "apply". The logic is roughly:
|
| @@ -92,10 +105,8 @@ void IC::TraceIC(const char* type, Handle<Object> name) {
|
| modifier = GetTransitionMarkModifier(
|
| KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
|
| }
|
| - PrintF(" (%c->%c%s)",
|
| - TransitionMarkFromState(state()),
|
| - TransitionMarkFromState(new_state),
|
| - modifier);
|
| + PrintF(" (%c->%c%s)", TransitionMarkFromState(old_state),
|
| + TransitionMarkFromState(new_state), modifier);
|
| #ifdef OBJECT_PRINT
|
| OFStream os(stdout);
|
| name->Print(os);
|
| @@ -107,7 +118,8 @@ void IC::TraceIC(const char* type, Handle<Object> name) {
|
| }
|
|
|
| #define TRACE_IC(type, name) TraceIC(type, name)
|
| -
|
| +#define TRACE_VECTOR_IC(type, name, old_state, new_state) \
|
| + TraceIC(type, name, old_state, new_state)
|
|
|
| IC::IC(FrameDepth depth, Isolate* isolate)
|
| : isolate_(isolate),
|
| @@ -365,6 +377,7 @@ static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state,
|
| break;
|
| case PROTOTYPE_FAILURE:
|
| case DEBUG_STUB:
|
| + case DEFAULT:
|
| UNREACHABLE();
|
| }
|
| }
|
| @@ -807,6 +820,7 @@ void IC::PatchCache(Handle<String> name, Handle<Code> code) {
|
| break;
|
| case DEBUG_STUB:
|
| break;
|
| + case DEFAULT:
|
| case GENERIC:
|
| UNREACHABLE();
|
| break;
|
| @@ -1950,6 +1964,7 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver,
|
| isolate()->native_context()->array_function());
|
| if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) {
|
| // Alter the slot.
|
| + IC::State old_state = FeedbackToState(vector, slot);
|
| Object* feedback = vector->get(slot->value());
|
| if (!feedback->IsAllocationSite()) {
|
| Handle<AllocationSite> new_site =
|
| @@ -1965,18 +1980,19 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver,
|
| isolate());
|
| }
|
|
|
| - TRACE_IC("CallIC (Array call)", name);
|
| - Object* new_feedback = vector->get(slot->value());
|
| - UpdateTypeFeedbackInfo(feedback, new_feedback);
|
| + IC::State new_state = FeedbackToState(vector, slot);
|
| + OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
|
| + TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state);
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
|
|
| -void CallIC::PatchMegamorphic(Handle<FixedArray> vector,
|
| - Handle<Smi> slot) {
|
| +void CallIC::PatchMegamorphic(Handle<Object> function,
|
| + Handle<FixedArray> vector, Handle<Smi> slot) {
|
| State state(target()->extra_ic_state());
|
| + IC::State old_state = FeedbackToState(vector, slot);
|
|
|
| // We are going generic.
|
| vector->set(slot->value(),
|
| @@ -1987,15 +2003,15 @@ void CallIC::PatchMegamorphic(Handle<FixedArray> vector,
|
| Handle<Code> code = stub.GetCode();
|
| set_target(*code);
|
|
|
| - TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
|
| -}
|
| -
|
| + Handle<Object> name = isolate()->factory()->empty_string();
|
| + if (function->IsJSFunction()) {
|
| + Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
|
| + name = handle(js_function->shared()->name(), isolate());
|
| + }
|
|
|
| -void CallIC::UpdateTypeFeedbackInfo(Object* old_feedback,
|
| - Object* new_feedback) {
|
| - IC::State old_state = FeedbackObjectToState(old_feedback);
|
| - IC::State new_state = FeedbackObjectToState(new_feedback);
|
| + IC::State new_state = FeedbackToState(vector, slot);
|
| OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
|
| + TRACE_VECTOR_IC("CallIC", name, old_state, new_state);
|
| }
|
|
|
|
|
| @@ -2004,6 +2020,8 @@ void CallIC::HandleMiss(Handle<Object> receiver,
|
| Handle<FixedArray> vector,
|
| Handle<Smi> slot) {
|
| State state(target()->extra_ic_state());
|
| + IC::State old_state = FeedbackToState(vector, slot);
|
| + Handle<Object> name = isolate()->factory()->empty_string();
|
| Object* feedback = vector->get(slot->value());
|
|
|
| // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
|
| @@ -2014,8 +2032,6 @@ void CallIC::HandleMiss(Handle<Object> receiver,
|
| vector->set(slot->value(),
|
| *TypeFeedbackInfo::MegamorphicSentinel(isolate()),
|
| SKIP_WRITE_BARRIER);
|
| -
|
| - TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
|
| } else {
|
| // The feedback is either uninitialized or an allocation site.
|
| // It might be an allocation site because if we re-compile the full code
|
| @@ -2032,14 +2048,17 @@ void CallIC::HandleMiss(Handle<Object> receiver,
|
| return;
|
| }
|
|
|
| - Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
|
| - Handle<Object> name(js_function->shared()->name(), isolate());
|
| - TRACE_IC("CallIC", name);
|
| vector->set(slot->value(), *function);
|
| }
|
|
|
| - Object* new_feedback = vector->get(slot->value());
|
| - UpdateTypeFeedbackInfo(feedback, new_feedback);
|
| + if (function->IsJSFunction()) {
|
| + Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
|
| + name = handle(js_function->shared()->name(), isolate());
|
| + }
|
| +
|
| + IC::State new_state = FeedbackToState(vector, slot);
|
| + OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
|
| + TRACE_VECTOR_IC("CallIC", name, old_state, new_state);
|
| }
|
|
|
|
|
| @@ -2074,7 +2093,7 @@ RUNTIME_FUNCTION(CallIC_Customization_Miss) {
|
| Handle<Object> function = args.at<Object>(1);
|
| Handle<FixedArray> vector = args.at<FixedArray>(2);
|
| Handle<Smi> slot = args.at<Smi>(3);
|
| - ic.PatchMegamorphic(vector, slot);
|
| + ic.PatchMegamorphic(function, vector, slot);
|
| return *function;
|
| }
|
|
|
|
|