Refactored deopt tracing and FindOptimizedCode. Fixed a bug when printing stubs.

Review URL: https://codereview.chromium.org/11636046

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13259 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2012-12-21 07:18:56 +00:00
parent 6323bb3e38
commit 3cff9a2a4a
4 changed files with 112 additions and 81 deletions

View File

@ -477,37 +477,32 @@ void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
}
static Code* FindOptimizedCode(Isolate* isolate,
JSFunction* function,
Deoptimizer::BailoutType type,
Address from,
Code* optimized_code) {
bool Deoptimizer::TraceEnabledFor(BailoutType type) {
switch (type) {
case Deoptimizer::EAGER:
ASSERT(from == NULL);
return function->code();
case Deoptimizer::LAZY: {
Code* compiled_code =
isolate->deoptimizer_data()->FindDeoptimizingCode(from);
return (compiled_code == NULL)
? static_cast<Code*>(isolate->heap()->FindCodeObject(from))
: compiled_code;
}
case Deoptimizer::OSR: {
// The function has already been optimized and we're transitioning
// from the unoptimized shared version to the optimized one in the
// function. The return address (from) points to unoptimized code.
Code* compiled_code = function->code();
ASSERT(compiled_code->kind() == Code::OPTIMIZED_FUNCTION);
ASSERT(!compiled_code->contains(from));
return compiled_code;
}
case Deoptimizer::DEBUGGER:
ASSERT(optimized_code->contains(from));
return optimized_code;
case EAGER:
case LAZY:
case DEBUGGER:
return FLAG_trace_deopt;
case OSR:
return FLAG_trace_osr;
}
UNREACHABLE();
return NULL;
return false;
}
const char* Deoptimizer::MessageFor(BailoutType type) {
switch (type) {
case EAGER:
case LAZY:
return "DEOPT";
case DEBUGGER:
return "DEOPT FOR DEBUGGER";
case OSR:
return "OSR";
}
UNREACHABLE();
return false;
}
@ -532,38 +527,16 @@ Deoptimizer::Deoptimizer(Isolate* isolate,
deferred_arguments_objects_values_(0),
deferred_arguments_objects_(0),
deferred_heap_numbers_(0) {
if (FLAG_trace_deopt && type != OSR) {
if (type == DEBUGGER) {
PrintF("**** DEOPT FOR DEBUGGER: ");
} else {
PrintF("**** DEOPT: ");
}
function->PrintName();
PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
bailout_id,
reinterpret_cast<intptr_t>(from),
fp_to_sp_delta - (2 * kPointerSize));
} else if (FLAG_trace_osr && type == OSR) {
PrintF("**** OSR: ");
function->PrintName();
PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
bailout_id,
reinterpret_cast<intptr_t>(from),
fp_to_sp_delta - (2 * kPointerSize));
}
// For COMPILED_STUBs called from builtins, the function pointer
// is a SMI indicating an internal frame.
// For COMPILED_STUBs called from builtins, the function pointer is a SMI
// indicating an internal frame.
if (function->IsSmi()) {
function = NULL;
}
if (function != NULL && function->IsOptimized()) {
function->shared()->increment_deopt_count();
}
compiled_code_ =
FindOptimizedCode(isolate, function, type, from, optimized_code);
if (FLAG_trace_deopt && type == EAGER) {
compiled_code_->PrintDeoptLocation(bailout_id);
}
compiled_code_ = FindOptimizedCode(function, optimized_code);
if (TraceEnabledFor(type)) Trace();
ASSERT(HEAP->allow_allocation(false));
unsigned size = ComputeInputFrameSize();
input_ = new(size) FrameDescription(size, function);
@ -571,6 +544,57 @@ Deoptimizer::Deoptimizer(Isolate* isolate,
}
Code* Deoptimizer::FindOptimizedCode(JSFunction* function,
Code* optimized_code) {
switch (bailout_type_) {
case Deoptimizer::EAGER:
ASSERT(from_ == NULL);
return function->code();
case Deoptimizer::LAZY: {
Code* compiled_code =
isolate_->deoptimizer_data()->FindDeoptimizingCode(from_);
return (compiled_code == NULL)
? static_cast<Code*>(isolate_->heap()->FindCodeObject(from_))
: compiled_code;
}
case Deoptimizer::OSR: {
// The function has already been optimized and we're transitioning
// from the unoptimized shared version to the optimized one in the
// function. The return address (from_) points to unoptimized code.
Code* compiled_code = function->code();
ASSERT(compiled_code->kind() == Code::OPTIMIZED_FUNCTION);
ASSERT(!compiled_code->contains(from_));
return compiled_code;
}
case Deoptimizer::DEBUGGER:
ASSERT(optimized_code->contains(from_));
return optimized_code;
}
UNREACHABLE();
return NULL;
}
void Deoptimizer::Trace() {
PrintF("**** %s: ", Deoptimizer::MessageFor(bailout_type_));
PrintFunctionName();
PrintF(" at id #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
bailout_id_,
reinterpret_cast<intptr_t>(from_),
fp_to_sp_delta_ - (2 * kPointerSize));
if (bailout_type_ == EAGER) compiled_code_->PrintDeoptLocation(bailout_id_);
}
void Deoptimizer::PrintFunctionName() {
if (function_->IsJSFunction()) {
function_->PrintName();
} else {
PrintF("%s", Code::Kind2String(compiled_code_->kind()));
}
}
Deoptimizer::~Deoptimizer() {
ASSERT(input_ == NULL && output_ == NULL);
}
@ -681,7 +705,7 @@ void Deoptimizer::DoComputeOutputFrames() {
PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ",
(bailout_type_ == LAZY ? " (lazy)" : ""),
reinterpret_cast<intptr_t>(function_));
function_->PrintName();
PrintFunctionName();
PrintF(" @%d]\n", bailout_id_);
}
@ -761,7 +785,7 @@ void Deoptimizer::DoComputeOutputFrames() {
JSFunction* function = output_[index]->GetFunction();
PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ",
reinterpret_cast<intptr_t>(function));
function->PrintName();
if (function != NULL) function->PrintName();
PrintF(" => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
" took %0.3f ms]\n",
node_id.ToInt(),

View File

@ -144,6 +144,9 @@ class Deoptimizer : public Malloced {
DEBUGGER
};
static bool TraceEnabledFor(BailoutType type);
static const char* MessageFor(BailoutType type);
int output_count() const { return output_count_; }
Code::Kind compiled_code_kind() const { return compiled_code_->kind(); }
@ -326,6 +329,9 @@ class Deoptimizer : public Malloced {
Address from,
int fp_to_sp_delta,
Code* optimized_code);
Code* FindOptimizedCode(JSFunction* function, Code* optimized_code);
void Trace();
void PrintFunctionName();
void DeleteFrameDescriptions();
void DoComputeOutputFrames();

View File

@ -9157,6 +9157,30 @@ void Code::PrintDeoptLocation(int bailout_id) {
}
// Identify kind of code.
const char* Code::Kind2String(Kind kind) {
switch (kind) {
case FUNCTION: return "FUNCTION";
case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION";
case COMPILED_STUB: return "COMPILED_STUB";
case STUB: return "STUB";
case BUILTIN: return "BUILTIN";
case LOAD_IC: return "LOAD_IC";
case KEYED_LOAD_IC: return "KEYED_LOAD_IC";
case STORE_IC: return "STORE_IC";
case KEYED_STORE_IC: return "KEYED_STORE_IC";
case CALL_IC: return "CALL_IC";
case KEYED_CALL_IC: return "KEYED_CALL_IC";
case UNARY_OP_IC: return "UNARY_OP_IC";
case BINARY_OP_IC: return "BINARY_OP_IC";
case COMPARE_IC: return "COMPARE_IC";
case TO_BOOLEAN_IC: return "TO_BOOLEAN_IC";
}
UNREACHABLE();
return NULL;
}
#ifdef ENABLE_DISASSEMBLER
void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
@ -9335,30 +9359,6 @@ void DeoptimizationOutputData::DeoptimizationOutputDataPrint(FILE* out) {
}
// Identify kind of code.
const char* Code::Kind2String(Kind kind) {
switch (kind) {
case FUNCTION: return "FUNCTION";
case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION";
case COMPILED_STUB: return "COMPILED_STUB";
case STUB: return "STUB";
case BUILTIN: return "BUILTIN";
case LOAD_IC: return "LOAD_IC";
case KEYED_LOAD_IC: return "KEYED_LOAD_IC";
case STORE_IC: return "STORE_IC";
case KEYED_STORE_IC: return "KEYED_STORE_IC";
case CALL_IC: return "CALL_IC";
case KEYED_CALL_IC: return "KEYED_CALL_IC";
case UNARY_OP_IC: return "UNARY_OP_IC";
case BINARY_OP_IC: return "BINARY_OP_IC";
case COMPARE_IC: return "COMPARE_IC";
case TO_BOOLEAN_IC: return "TO_BOOLEAN_IC";
}
UNREACHABLE();
return NULL;
}
const char* Code::ICState2String(InlineCacheState state) {
switch (state) {
case UNINITIALIZED: return "UNINITIALIZED";

View File

@ -4211,6 +4211,8 @@ class Code: public HeapObject {
// Flags.
STATIC_ASSERT(LAST_CODE_KIND < 16);
static const char* Kind2String(Kind kind);
// Types of stubs.
enum StubType {
NORMAL,
@ -4232,7 +4234,6 @@ class Code: public HeapObject {
#ifdef ENABLE_DISASSEMBLER
// Printing
static const char* Kind2String(Kind kind);
static const char* ICState2String(InlineCacheState state);
static const char* StubType2String(StubType type);
static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);