--trace-ic: much faster and available in Release mode.
Also add IC tracing to a path where it was missing. R=jarin@chromium.org Review URL: https://codereview.chromium.org/368833003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22268 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
a0dadc8b0d
commit
3b9da14adf
@ -536,6 +536,7 @@ DEFINE_BOOL(use_idle_notification, true,
|
||||
"Use idle notification to reduce memory footprint.")
|
||||
// ic.cc
|
||||
DEFINE_BOOL(use_ic, true, "use inline caching")
|
||||
DEFINE_BOOL(trace_ic, false, "trace inline cache state transitions")
|
||||
|
||||
// macro-assembler-ia32.cc
|
||||
DEFINE_BOOL(native_code_counters, false,
|
||||
@ -724,9 +725,6 @@ DEFINE_BOOL(verify_native_context_separation, false,
|
||||
DEFINE_BOOL(print_handles, false, "report handles after GC")
|
||||
DEFINE_BOOL(print_global_handles, false, "report global handles after GC")
|
||||
|
||||
// ic.cc
|
||||
DEFINE_BOOL(trace_ic, false, "trace inline cache state transitions")
|
||||
|
||||
// interface.cc
|
||||
DEFINE_BOOL(print_interfaces, false, "print interfaces")
|
||||
DEFINE_BOOL(print_interface_details, false, "print interface inference details")
|
||||
|
@ -777,28 +777,15 @@ void JavaScriptFrame::Summarize(List<FrameSummary>* functions) {
|
||||
}
|
||||
|
||||
|
||||
void JavaScriptFrame::PrintTop(Isolate* isolate,
|
||||
FILE* file,
|
||||
bool print_args,
|
||||
void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code,
|
||||
Address pc, FILE* file,
|
||||
bool print_line_number) {
|
||||
// constructor calls
|
||||
DisallowHeapAllocation no_allocation;
|
||||
JavaScriptFrameIterator it(isolate);
|
||||
while (!it.done()) {
|
||||
if (it.frame()->is_java_script()) {
|
||||
JavaScriptFrame* frame = it.frame();
|
||||
if (frame->IsConstructor()) PrintF(file, "new ");
|
||||
// function name
|
||||
JSFunction* fun = frame->function();
|
||||
fun->PrintName();
|
||||
Code* js_code = frame->unchecked_code();
|
||||
Address pc = frame->pc();
|
||||
int code_offset =
|
||||
static_cast<int>(pc - js_code->instruction_start());
|
||||
PrintF("+%d", code_offset);
|
||||
SharedFunctionInfo* shared = fun->shared();
|
||||
PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
|
||||
function->PrintName(file);
|
||||
int code_offset = static_cast<int>(pc - code->instruction_start());
|
||||
PrintF(file, "+%d", code_offset);
|
||||
if (print_line_number) {
|
||||
Code* code = Code::cast(isolate->FindCodeObject(pc));
|
||||
SharedFunctionInfo* shared = function->shared();
|
||||
int source_pos = code->SourcePosition(pc);
|
||||
Object* maybe_script = shared->script();
|
||||
if (maybe_script->IsScript()) {
|
||||
@ -808,8 +795,7 @@ void JavaScriptFrame::PrintTop(Isolate* isolate,
|
||||
if (script_name_raw->IsString()) {
|
||||
String* script_name = String::cast(script->name());
|
||||
SmartArrayPointer<char> c_script_name =
|
||||
script_name->ToCString(DISALLOW_NULLS,
|
||||
ROBUST_STRING_TRAVERSAL);
|
||||
script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
||||
PrintF(file, " at %s:%d", c_script_name.get(), line);
|
||||
} else {
|
||||
PrintF(file, " at <unknown>:%d", line);
|
||||
@ -818,7 +804,20 @@ void JavaScriptFrame::PrintTop(Isolate* isolate,
|
||||
PrintF(file, " at <unknown>:<unknown>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
|
||||
bool print_line_number) {
|
||||
// constructor calls
|
||||
DisallowHeapAllocation no_allocation;
|
||||
JavaScriptFrameIterator it(isolate);
|
||||
while (!it.done()) {
|
||||
if (it.frame()->is_java_script()) {
|
||||
JavaScriptFrame* frame = it.frame();
|
||||
if (frame->IsConstructor()) PrintF(file, "new ");
|
||||
PrintFunctionAndOffset(frame->function(), frame->unchecked_code(),
|
||||
frame->pc(), file, print_line_number);
|
||||
if (print_args) {
|
||||
// function arguments
|
||||
// (we are intentionally only printing the actually
|
||||
|
@ -614,9 +614,11 @@ class JavaScriptFrame: public StandardFrame {
|
||||
return static_cast<JavaScriptFrame*>(frame);
|
||||
}
|
||||
|
||||
static void PrintTop(Isolate* isolate,
|
||||
FILE* file,
|
||||
bool print_args,
|
||||
static void PrintFunctionAndOffset(JSFunction* function, Code* code,
|
||||
Address pc, FILE* file,
|
||||
bool print_line_number);
|
||||
|
||||
static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
|
||||
bool print_line_number);
|
||||
|
||||
protected:
|
||||
|
68
src/ic.cc
68
src/ic.cc
@ -17,7 +17,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#ifdef DEBUG
|
||||
char IC::TransitionMarkFromState(IC::State state) {
|
||||
switch (state) {
|
||||
case UNINITIALIZED: return '0';
|
||||
@ -48,25 +47,43 @@ const char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) {
|
||||
}
|
||||
|
||||
|
||||
void IC::TraceIC(const char* type,
|
||||
Handle<Object> name) {
|
||||
#ifdef DEBUG
|
||||
|
||||
#define TRACE_GENERIC_IC(isolate, type, reason) \
|
||||
do { \
|
||||
if (FLAG_trace_ic) { \
|
||||
PrintF("[%s patching generic stub in ", type); \
|
||||
JavaScriptFrame::PrintTop(isolate, stdout, false, true); \
|
||||
PrintF(" (%s)]\n", reason); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define TRACE_GENERIC_IC(isolate, type, reason)
|
||||
|
||||
#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();
|
||||
PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type);
|
||||
StackFrameIterator it(isolate());
|
||||
while (it.frame()->fp() != this->fp()) it.Advance();
|
||||
StackFrame* raw_frame = it.frame();
|
||||
if (raw_frame->is_internal()) {
|
||||
Code* apply_builtin = isolate()->builtins()->builtin(
|
||||
Builtins::kFunctionApply);
|
||||
if (raw_frame->unchecked_code() == apply_builtin) {
|
||||
PrintF("apply from ");
|
||||
it.Advance();
|
||||
raw_frame = it.frame();
|
||||
|
||||
// TODO(jkummerow): Add support for "apply". The logic is roughly:
|
||||
// marker = [fp_ + kMarkerOffset];
|
||||
// if marker is smi and marker.value == INTERNAL and
|
||||
// the frame's code == builtin(Builtins::kFunctionApply):
|
||||
// then print "apply from" and advance one frame
|
||||
|
||||
Object* maybe_function =
|
||||
Memory::Object_at(fp_ + JavaScriptFrameConstants::kFunctionOffset);
|
||||
if (maybe_function->IsJSFunction()) {
|
||||
JSFunction* function = JSFunction::cast(maybe_function);
|
||||
JavaScriptFrame::PrintFunctionAndOffset(function, function->code(), pc(),
|
||||
stdout, true);
|
||||
}
|
||||
}
|
||||
JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
|
||||
|
||||
ExtraICState extra_state = new_target->extra_ic_state();
|
||||
const char* modifier = "";
|
||||
if (new_target->kind() == Code::KEYED_STORE_IC) {
|
||||
@ -83,21 +100,8 @@ void IC::TraceIC(const char* type,
|
||||
}
|
||||
}
|
||||
|
||||
#define TRACE_GENERIC_IC(isolate, type, reason) \
|
||||
do { \
|
||||
if (FLAG_trace_ic) { \
|
||||
PrintF("[%s patching generic stub in ", type); \
|
||||
JavaScriptFrame::PrintTop(isolate, stdout, false, true); \
|
||||
PrintF(" (%s)]\n", reason); \
|
||||
} \
|
||||
} while (false)
|
||||
#define TRACE_IC(type, name) TraceIC(type, name)
|
||||
|
||||
#else
|
||||
#define TRACE_GENERIC_IC(isolate, type, reason)
|
||||
#endif // DEBUG
|
||||
|
||||
#define TRACE_IC(type, name) \
|
||||
ASSERT((TraceIC(type, name), true))
|
||||
|
||||
IC::IC(FrameDepth depth, Isolate* isolate)
|
||||
: isolate_(isolate),
|
||||
@ -616,7 +620,11 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<String> name) {
|
||||
uint32_t index;
|
||||
if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
|
||||
// Rewrite to the generic keyed load stub.
|
||||
if (FLAG_use_ic) set_target(*generic_stub());
|
||||
if (FLAG_use_ic) {
|
||||
set_target(*generic_stub());
|
||||
TRACE_IC("LoadIC", name);
|
||||
TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index");
|
||||
}
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate(),
|
||||
|
Loading…
Reference in New Issue
Block a user