diff --git a/src/frames.cc b/src/frames.cc index 9fd00422aa..e3ed2de4e3 100644 --- a/src/frames.cc +++ b/src/frames.cc @@ -723,12 +723,17 @@ void JavaScriptFrame::PrintTop(FILE* file, JavaScriptFrame* frame = it.frame(); if (frame->IsConstructor()) PrintF(file, "new "); // function name - Object* fun = frame->function(); - if (fun->IsJSFunction()) { - SharedFunctionInfo* shared = JSFunction::cast(fun)->shared(); - shared->DebugName()->ShortPrint(file); + Object* maybe_fun = frame->function(); + if (maybe_fun->IsJSFunction()) { + JSFunction* fun = JSFunction::cast(maybe_fun); + fun->PrintName(); + Code* js_code = frame->unchecked_code(); + Address pc = frame->pc(); + int code_offset = + static_cast(pc - js_code->instruction_start()); + PrintF("+%d", code_offset); + SharedFunctionInfo* shared = fun->shared(); if (print_line_number) { - Address pc = frame->pc(); Code* code = Code::cast( v8::internal::Isolate::Current()->heap()->FindCodeObject(pc)); int source_pos = code->SourcePosition(pc); @@ -751,7 +756,7 @@ void JavaScriptFrame::PrintTop(FILE* file, } } } else { - fun->ShortPrint(file); + PrintF(""); } if (print_args) { diff --git a/src/ic-inl.h b/src/ic-inl.h index 498cf3af31..56cea81760 100644 --- a/src/ic-inl.h +++ b/src/ic-inl.h @@ -1,4 +1,4 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -36,7 +36,7 @@ namespace v8 { namespace internal { -Address IC::address() { +Address IC::address() const { // Get the address of the call. Address result = pc() - Assembler::kCallTargetAddressOffset; diff --git a/src/ic.cc b/src/ic.cc index 2c6d55b93f..7f867143f0 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(address() - js_code->instruction_start()); - PrintF("+%d", code_offset); - } else { - PrintF(""); - } + 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 KeyedIC::ComputeStub(Handle 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 KeyedIC::ComputeStub(Handle 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); diff --git a/src/ic.h b/src/ic.h index 81aa6b7c2f..65cade4242 100644 --- a/src/ic.h +++ b/src/ic.h @@ -91,10 +91,13 @@ class IC { // Construct the IC structure with the given number of extra // JavaScript frames on the stack. IC(FrameDepth depth, Isolate* isolate); + virtual ~IC() {} // Get the call-site target; used for determining the state. - Code* target() { return GetTargetAtAddress(address()); } - inline Address address(); + Code* target() const { return GetTargetAtAddress(address()); } + inline Address address() const; + + virtual bool IsGeneric() const { return false; } // Compute the current IC state based on the target stub, receiver and name. static State StateFrom(Code* target, Object* receiver, Object* name); @@ -139,13 +142,15 @@ class IC { #ifdef ENABLE_DEBUGGER_SUPPORT // Computes the address in the original code when the code running is // containing break points (calls to DebugBreakXXX builtins). - Address OriginalCodeAddress(); + Address OriginalCodeAddress() const; #endif // Set the call-site target. void set_target(Code* code) { SetTargetAtAddress(address(), code); } #ifdef DEBUG + char TransitionMarkFromState(IC::State state); + void TraceIC(const char* type, Handle name, State old_state, @@ -452,6 +457,10 @@ class KeyedLoadIC: public KeyedIC { bool is_js_array, ElementsKind elements_kind); + virtual bool IsGeneric() const { + return target() == *generic_stub(); + } + protected: virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } @@ -477,7 +486,7 @@ class KeyedLoadIC: public KeyedIC { Handle megamorphic_stub() { return isolate()->builtins()->KeyedLoadIC_Generic(); } - Handle generic_stub() { + Handle generic_stub() const { return isolate()->builtins()->KeyedLoadIC_Generic(); } Handle pre_monomorphic_stub() { @@ -595,6 +604,11 @@ class KeyedStoreIC: public KeyedIC { bool is_js_array, ElementsKind elements_kind); + virtual bool IsGeneric() const { + return target() == *generic_stub() || + target() == *generic_stub_strict(); + } + protected: virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } @@ -632,10 +646,10 @@ class KeyedStoreIC: public KeyedIC { Handle megamorphic_stub_strict() { return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); } - Handle generic_stub() { + Handle generic_stub() const { return isolate()->builtins()->KeyedStoreIC_Generic(); } - Handle generic_stub_strict() { + Handle generic_stub_strict() const { return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); } Handle non_strict_arguments_stub() {