| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 2c6d55b93fce474d6c9452de3705604f09fcc05a..7f867143f0622cf920e0a25591a703fae084b643 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -40,13 +40,13 @@ namespace v8 {
|
| namespace internal {
|
|
|
| #ifdef DEBUG
|
| -static char TransitionMarkFromState(IC::State state) {
|
| +char IC::TransitionMarkFromState(IC::State state) {
|
| switch (state) {
|
| case UNINITIALIZED: return '0';
|
| case PREMONOMORPHIC: return 'P';
|
| case MONOMORPHIC: return '1';
|
| case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
|
| - case MEGAMORPHIC: return 'N';
|
| + case MEGAMORPHIC: return IsGeneric() ? 'G' : 'N';
|
|
|
| // We never see the debugger states here, because the state is
|
| // computed from the original code - not the patched code. Let
|
| @@ -80,19 +80,7 @@ void IC::TraceIC(const char* type,
|
| raw_frame = it.frame();
|
| }
|
| }
|
| - if (raw_frame->is_java_script()) {
|
| - JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
|
| - Code* js_code = frame->unchecked_code();
|
| - // Find the function on the stack and both the active code for the
|
| - // function and the original code.
|
| - JSFunction* function = JSFunction::cast(frame->function());
|
| - function->PrintName();
|
| - int code_offset =
|
| - static_cast<int>(address() - js_code->instruction_start());
|
| - PrintF("+%d", code_offset);
|
| - } else {
|
| - PrintF("<unknown>");
|
| - }
|
| + JavaScriptFrame::PrintTop(stdout, false, true);
|
| PrintF(" (%c->%c)",
|
| TransitionMarkFromState(old_state),
|
| TransitionMarkFromState(new_state));
|
| @@ -100,13 +88,23 @@ void IC::TraceIC(const char* type,
|
| PrintF("]\n");
|
| }
|
| }
|
| -#endif // DEBUG
|
|
|
| +#define TRACE_GENERIC_IC(type, reason) \
|
| + do { \
|
| + if (FLAG_trace_ic) { \
|
| + PrintF("[%s patching generic stub in ", type); \
|
| + JavaScriptFrame::PrintTop(stdout, false, true); \
|
| + PrintF(" (%s)]\n", reason); \
|
| + } \
|
| + } while (false)
|
| +
|
| +#else
|
| +#define TRACE_GENERIC_IC(type, reason)
|
| +#endif // DEBUG
|
|
|
| #define TRACE_IC(type, name, old_state, new_target) \
|
| ASSERT((TraceIC(type, name, old_state, new_target), true))
|
|
|
| -
|
| IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
|
| ASSERT(isolate == Isolate::Current());
|
| // To improve the performance of the (much used) IC code, we unfold
|
| @@ -137,7 +135,7 @@ IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
|
|
|
|
|
| #ifdef ENABLE_DEBUGGER_SUPPORT
|
| -Address IC::OriginalCodeAddress() {
|
| +Address IC::OriginalCodeAddress() const {
|
| HandleScope scope;
|
| // Compute the JavaScript frame for the frame pointer of this IC
|
| // structure. We need this to be able to find the function
|
| @@ -1123,6 +1121,8 @@ MaybeObject* KeyedLoadIC::Load(State state,
|
| stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub);
|
| }
|
| }
|
| + } else {
|
| + TRACE_GENERIC_IC("KeyedLoadIC", "force generic");
|
| }
|
| if (!stub.is_null()) set_target(*stub);
|
| }
|
| @@ -1473,6 +1473,7 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
|
| // via megamorphic stubs, since they don't have a map in their relocation info
|
| // and so the stubs can't be harvested for the object needed for a map check.
|
| if (target()->type() != NORMAL) {
|
| + TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
|
| return generic_stub;
|
| }
|
|
|
| @@ -1494,12 +1495,14 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
|
| if (!map_added) {
|
| // If the miss wasn't due to an unseen map, a polymorphic stub
|
| // won't help, use the generic stub.
|
| + TRACE_GENERIC_IC("KeyedIC", "same map added twice");
|
| return generic_stub;
|
| }
|
|
|
| // If the maximum number of receiver maps has been exceeded, use the generic
|
| // version of the IC.
|
| if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
|
| + TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded");
|
| return generic_stub;
|
| }
|
|
|
| @@ -1685,6 +1688,8 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
| }
|
| stub = ComputeStub(receiver, stub_kind, strict_mode, stub);
|
| }
|
| + } else {
|
| + TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
|
| }
|
| }
|
| if (!stub.is_null()) set_target(*stub);
|
|
|