}
-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;
}
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);
}
+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);
}
PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ",
(bailout_type_ == LAZY ? " (lazy)" : ""),
reinterpret_cast<intptr_t>(function_));
- function_->PrintName();
+ PrintFunctionName();
PrintF(" @%d]\n", bailout_id_);
}
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(),
}
+// 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) {
}
-// 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";