Allow redirecting disassembly and deoptimization traces into a file.
authorvegorov@chromium.org <vegorov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Nov 2013 16:35:27 +0000 (16:35 +0000)
committervegorov@chromium.org <vegorov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Nov 2013 16:35:27 +0000 (16:35 +0000)
This is controlled by two flags:

--redirect_code_traces
--redirect_code_traces_to=<filename>

When redirection is enabled but --redirect_code_traces_to is not specified traces are written to a file code-<pid>-<isolate>.asm. This mangling scheme matches hydrogen.cfg and allows easy discovery of compilation artifacts in a multi-V8 environment (e.g. when compilation is traced from inside Chromium).

D8 defines --redirect_code_traces_to=code.asm similar to hydrogen.cfg redirection.

BUG=
R=danno@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17571 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

17 files changed:
src/assembler.cc
src/builtins.cc
src/code-stubs.cc
src/codegen.cc
src/d8.cc
src/deoptimizer.cc
src/deoptimizer.h
src/flag-definitions.h
src/isolate.cc
src/isolate.h
src/jsregexp.cc
src/objects-printer.cc
src/objects.cc
src/objects.h
src/safepoint-table.cc
src/safepoint-table.h
src/stub-cache.cc

index 0e05c2c7c7ce6f0fecacf1fff129686822394ce9..eb88922d195a1451ec033a844556bf65d1e193d5 100644 (file)
@@ -826,7 +826,7 @@ void RelocInfo::Print(Isolate* isolate, FILE* out) {
     PrintF(out, " (%s)  (%p)", Code::Kind2String(code->kind()),
            target_address());
     if (rmode_ == CODE_TARGET_WITH_ID) {
-      PrintF(" (id=%d)", static_cast<int>(data_));
+      PrintF(out, " (id=%d)", static_cast<int>(data_));
     }
   } else if (IsPosition(rmode_)) {
     PrintF(out, "  (%" V8_PTR_PREFIX "d)", data());
index b614904c9f468ba08708c8a3bb96710598415ab2..758967ec08d875ce5ccab732d4d120366e6a5079 100644 (file)
@@ -1750,9 +1750,10 @@ void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
       builtins_[i] = code;
 #ifdef ENABLE_DISASSEMBLER
       if (FLAG_print_builtin_code) {
-        PrintF("Builtin: %s\n", functions[i].s_name);
-        Code::cast(code)->Disassemble(functions[i].s_name);
-        PrintF("\n");
+        CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
+        PrintF(trace_scope.file(), "Builtin: %s\n", functions[i].s_name);
+        Code::cast(code)->Disassemble(functions[i].s_name, trace_scope.file());
+        PrintF(trace_scope.file(), "\n");
       }
 #endif
     } else {
index e68a5dd0c8bbf12a67d9399b6add259539f8cd96..afa3cd09e90e906746098471fb323501fb40955f 100644 (file)
@@ -160,8 +160,9 @@ Handle<Code> CodeStub::GetCode(Isolate* isolate) {
 
 #ifdef ENABLE_DISASSEMBLER
     if (FLAG_print_code_stubs) {
-      new_object->Disassemble(*GetName());
-      PrintF("\n");
+      CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
+      new_object->Disassemble(*GetName(), trace_scope.file());
+      PrintF(trace_scope.file(), "\n");
     }
 #endif
 
index 573ddc6ce765af0cf2af2a8e25962a18ead2ed48..28f7d6c099e0a25fc1750e0bcd066ae24a634fa1 100644 (file)
@@ -136,10 +136,12 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
     FunctionLiteral* function = info->function();
     bool print_source = code->kind() == Code::OPTIMIZED_FUNCTION ||
         code->kind() == Code::FUNCTION;
+
+    CodeTracer::Scope tracing_scope(info->isolate()->GetCodeTracer());
     if (print_source) {
       Handle<Script> script = info->script();
       if (!script->IsUndefined() && !script->source()->IsUndefined()) {
-        PrintF("--- Raw source ---\n");
+        PrintF(tracing_scope.file(), "--- Raw source ---\n");
         ConsStringIteratorOp op;
         StringCharacterStream stream(String::cast(script->source()),
                                      &op,
@@ -149,31 +151,36 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
         int source_len =
             function->end_position() - function->start_position() + 1;
         for (int i = 0; i < source_len; i++) {
-          if (stream.HasMore()) PrintF("%c", stream.GetNext());
+          if (stream.HasMore()) {
+            PrintF(tracing_scope.file(), "%c", stream.GetNext());
+          }
         }
-        PrintF("\n\n");
+        PrintF(tracing_scope.file(), "\n\n");
       }
     }
     if (info->IsOptimizing()) {
       if (FLAG_print_unopt_code) {
-        PrintF("--- Unoptimized code ---\n");
+        PrintF(tracing_scope.file(), "--- Unoptimized code ---\n");
         info->closure()->shared()->code()->Disassemble(
-            *function->debug_name()->ToCString());
+            *function->debug_name()->ToCString(), tracing_scope.file());
       }
-      PrintF("--- Optimized code ---\n");
+      PrintF(tracing_scope.file(), "--- Optimized code ---\n");
     } else {
-      PrintF("--- Code ---\n");
+      PrintF(tracing_scope.file(), "--- Code ---\n");
     }
     if (print_source) {
-      PrintF("source_position = %d\n", function->start_position());
+      PrintF(tracing_scope.file(),
+             "source_position = %d\n", function->start_position());
     }
     if (info->IsStub()) {
       CodeStub::Major major_key = info->code_stub()->MajorKey();
-      code->Disassemble(CodeStub::MajorName(major_key, false));
+      code->Disassemble(CodeStub::MajorName(major_key, false),
+                        tracing_scope.file());
     } else {
-      code->Disassemble(*function->debug_name()->ToCString());
+      code->Disassemble(*function->debug_name()->ToCString(),
+                        tracing_scope.file());
     }
-    PrintF("--- End code ---\n");
+    PrintF(tracing_scope.file(), "--- End code ---\n");
   }
 #endif  // ENABLE_DISASSEMBLER
 }
index 357c8a48992bdb157de3df6133ae8abd847f6bc5..17bd6713637c7054bde9ca5240975f48b4f5a307 100644 (file)
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -1585,6 +1585,7 @@ static void SetStandaloneFlagsViaCommandLine() {
   char **fake_argv = new char*[2];
   fake_argv[0] = NULL;
   fake_argv[1] = strdup("--trace-hydrogen-file=hydrogen.cfg");
+  fake_argv[2] = strdup("--redirect-code-traces-to=code.asm");
   v8::V8::SetFlagsFromCommandLine(&fake_argc, fake_argv, false);
   free(fake_argv[1]);
   delete[] fake_argv;
@@ -1674,6 +1675,7 @@ int Shell::Main(int argc, char* argv[]) {
   v8::V8::InitializeICU();
 #ifndef V8_SHARED
   i::FLAG_trace_hydrogen_file = "hydrogen.cfg";
+  i::FLAG_redirect_code_traces_to = "code.asm";
 #else
   SetStandaloneFlagsViaCommandLine();
 #endif
index 96871d610f48d09f367d30d56149d6001aaa3d95..4f2cd03c04edc364c06b66ffe1273dac6e71ac2b 100644 (file)
@@ -344,9 +344,11 @@ void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
       shared->EvictFromOptimizedCodeMap(code, "deoptimized function");
 
       if (FLAG_trace_deopt) {
-        PrintF("[deoptimizer unlinked: ");
-        function->PrintName();
-        PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
+        CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
+        PrintF(scope.file(), "[deoptimizer unlinked: ");
+        function->PrintName(scope.file());
+        PrintF(scope.file(),
+               " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
       }
     }
   };
@@ -409,7 +411,8 @@ void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
 
 void Deoptimizer::DeoptimizeAll(Isolate* isolate) {
   if (FLAG_trace_deopt) {
-    PrintF("[deoptimize all code in all contexts]\n");
+    CodeTracer::Scope scope(isolate->GetCodeTracer());
+    PrintF(scope.file(), "[deoptimize all code in all contexts]\n");
   }
   DisallowHeapAllocation no_allocation;
   // For all contexts, mark all code, then deoptimize.
@@ -425,7 +428,8 @@ void Deoptimizer::DeoptimizeAll(Isolate* isolate) {
 
 void Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) {
   if (FLAG_trace_deopt) {
-    PrintF("[deoptimize marked code in all contexts]\n");
+    CodeTracer::Scope scope(isolate->GetCodeTracer());
+    PrintF(scope.file(), "[deoptimize marked code in all contexts]\n");
   }
   DisallowHeapAllocation no_allocation;
   // For all contexts, deoptimize code already marked.
@@ -440,7 +444,8 @@ void Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) {
 
 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) {
   if (FLAG_trace_deopt) {
-    PrintF("[deoptimize global object @ 0x%08" V8PRIxPTR "]\n",
+    CodeTracer::Scope scope(object->GetHeap()->isolate()->GetCodeTracer());
+    PrintF(scope.file(), "[deoptimize global object @ 0x%08" V8PRIxPTR "]\n",
         reinterpret_cast<intptr_t>(object));
   }
   if (object->IsJSGlobalProxy()) {
@@ -541,7 +546,7 @@ Deoptimizer::Deoptimizer(Isolate* isolate,
       materialized_objects_(NULL),
       materialization_value_index_(0),
       materialization_object_index_(0),
-      trace_(false) {
+      trace_scope_(NULL) {
   // For COMPILED_STUBs called from builtins, the function pointer is a SMI
   // indicating an internal frame.
   if (function->IsSmi()) {
@@ -571,7 +576,8 @@ Deoptimizer::Deoptimizer(Isolate* isolate,
   StackFrame::Type frame_type = function == NULL
       ? StackFrame::STUB
       : StackFrame::JAVA_SCRIPT;
-  trace_ = TraceEnabledFor(type, frame_type);
+  trace_scope_ = TraceEnabledFor(type, frame_type) ?
+      new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL;
 #ifdef DEBUG
   CHECK(AllowHeapAllocation::IsAllowed());
   disallow_heap_allocation_ = new DisallowHeapAllocation();
@@ -604,9 +610,10 @@ Code* Deoptimizer::FindOptimizedCode(JSFunction* function,
 
 void Deoptimizer::PrintFunctionName() {
   if (function_->IsJSFunction()) {
-    function_->PrintName();
+    function_->PrintName(trace_scope_->file());
   } else {
-    PrintF("%s", Code::Kind2String(compiled_code_->kind()));
+    PrintF(trace_scope_->file(),
+           "%s", Code::Kind2String(compiled_code_->kind()));
   }
 }
 
@@ -614,6 +621,7 @@ void Deoptimizer::PrintFunctionName() {
 Deoptimizer::~Deoptimizer() {
   ASSERT(input_ == NULL && output_ == NULL);
   ASSERT(disallow_heap_allocation_ == NULL);
+  delete trace_scope_;
 }
 
 
@@ -681,13 +689,13 @@ int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
       return data->PcAndState(i)->value();
     }
   }
-  PrintF("[couldn't find pc offset for node=%d]\n", id.ToInt());
-  PrintF("[method: %s]\n", *shared->DebugName()->ToCString());
+  PrintF(stderr, "[couldn't find pc offset for node=%d]\n", id.ToInt());
+  PrintF(stderr, "[method: %s]\n", *shared->DebugName()->ToCString());
   // Print the source code if available.
   HeapStringAllocator string_allocator;
   StringStream stream(&string_allocator);
   shared->SourceCodePrint(&stream, -1);
-  PrintF("[source:\n%s\n]", *stream.ToCString());
+  PrintF(stderr, "[source:\n%s\n]", *stream.ToCString());
 
   FATAL("unable to find pc offset during deoptimization");
   return -1;
@@ -722,15 +730,19 @@ void Deoptimizer::DoComputeOutputFrames() {
     LOG(isolate(), CodeDeoptEvent(compiled_code_));
   }
   ElapsedTimer timer;
-  if (trace_) {
+  if (trace_scope_ != NULL) {
     timer.Start();
-    PrintF("[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ",
+    PrintF(trace_scope_->file(),
+           "[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ",
            MessageFor(bailout_type_),
            reinterpret_cast<intptr_t>(function_));
     PrintFunctionName();
-    PrintF(" @%d, FP to SP delta: %d]\n", bailout_id_, fp_to_sp_delta_);
+    PrintF(trace_scope_->file(),
+           " @%d, FP to SP delta: %d]\n",
+           bailout_id_,
+           fp_to_sp_delta_);
     if (bailout_type_ == EAGER || bailout_type_ == SOFT) {
-      compiled_code_->PrintDeoptLocation(bailout_id_);
+      compiled_code_->PrintDeoptLocation(trace_scope_->file(), bailout_id_);
     }
   }
 
@@ -803,15 +815,17 @@ void Deoptimizer::DoComputeOutputFrames() {
   }
 
   // Print some helpful diagnostic information.
-  if (trace_) {
+  if (trace_scope_ != NULL) {
     double ms = timer.Elapsed().InMillisecondsF();
     int index = output_count_ - 1;  // Index of the topmost frame.
     JSFunction* function = output_[index]->GetFunction();
-    PrintF("[deoptimizing (%s): end 0x%08" V8PRIxPTR " ",
+    PrintF(trace_scope_->file(),
+           "[deoptimizing (%s): end 0x%08" V8PRIxPTR " ",
            MessageFor(bailout_type_),
            reinterpret_cast<intptr_t>(function));
     PrintFunctionName();
-    PrintF(" @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
+    PrintF(trace_scope_->file(),
+           " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
            " took %0.3f ms]\n",
            bailout_id_,
            node_id.ToInt(),
@@ -839,10 +853,11 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
   }
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
-  if (trace_) {
-    PrintF("  translating ");
-    function->PrintName();
-    PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(), "  translating ");
+    function->PrintName(trace_scope_->file());
+    PrintF(trace_scope_->file(),
+           " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
   }
 
   // The 'fixed' part of the frame consists of the incoming parameters and
@@ -909,8 +924,9 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
     value = output_[frame_index - 1]->GetPc();
   }
   output_frame->SetCallerPc(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR  " ; caller's pc\n",
            top_address + output_offset, output_offset, value);
   }
@@ -932,8 +948,9 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
       has_alignment_padding_ * kPointerSize) == fp_value);
   output_frame->SetFp(fp_value);
   if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; caller's fp\n",
            fp_value, output_offset, value);
   }
@@ -954,8 +971,9 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
   output_frame->SetFrameSlot(output_offset, value);
   output_frame->SetContext(value);
   if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR "; context\n",
            top_address + output_offset, output_offset, value);
   }
@@ -968,8 +986,9 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
   // input frame.
   ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR "; function\n",
            top_address + output_offset, output_offset, value);
   }
@@ -1017,8 +1036,9 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
-  if (trace_) {
-    PrintF("  translating arguments adaptor => height=%d\n", height_in_bytes);
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "  translating arguments adaptor => height=%d\n", height_in_bytes);
   }
 
   unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
@@ -1052,8 +1072,9 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
   output_offset -= kPCOnStackSize;
   intptr_t callers_pc = output_[frame_index - 1]->GetPc();
   output_frame->SetCallerPc(output_offset, callers_pc);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; caller's pc\n",
            top_address + output_offset, output_offset, callers_pc);
   }
@@ -1064,8 +1085,9 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
   output_frame->SetCallerFp(output_offset, value);
   intptr_t fp_value = top_address + output_offset;
   output_frame->SetFp(fp_value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; caller's fp\n",
            fp_value, output_offset, value);
   }
@@ -1075,8 +1097,9 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
   intptr_t context = reinterpret_cast<intptr_t>(
       Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   output_frame->SetFrameSlot(output_offset, context);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; context (adaptor sentinel)\n",
            top_address + output_offset, output_offset, context);
   }
@@ -1085,8 +1108,9 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(function);
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; function\n",
            top_address + output_offset, output_offset, value);
   }
@@ -1095,8 +1119,9 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; argc (%d)\n",
            top_address + output_offset, output_offset, value, height - 1);
   }
@@ -1120,8 +1145,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
-  if (trace_) {
-    PrintF("  translating construct stub => height=%d\n", height_in_bytes);
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "  translating construct stub => height=%d\n", height_in_bytes);
   }
 
   unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize;
@@ -1163,8 +1189,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   output_offset -= kPCOnStackSize;
   intptr_t callers_pc = output_[frame_index - 1]->GetPc();
   output_frame->SetCallerPc(output_offset, callers_pc);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; caller's pc\n",
            top_address + output_offset, output_offset, callers_pc);
   }
@@ -1175,8 +1202,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   output_frame->SetCallerFp(output_offset, value);
   intptr_t fp_value = top_address + output_offset;
   output_frame->SetFp(fp_value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; caller's fp\n",
            fp_value, output_offset, value);
   }
@@ -1185,8 +1213,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = output_[frame_index - 1]->GetContext();
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; context\n",
            top_address + output_offset, output_offset, value);
   }
@@ -1195,8 +1224,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; function (construct sentinel)\n",
            top_address + output_offset, output_offset, value);
   }
@@ -1205,8 +1235,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(construct_stub);
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; code object\n",
            top_address + output_offset, output_offset, value);
   }
@@ -1215,8 +1246,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; argc (%d)\n",
            top_address + output_offset, output_offset, value, height - 1);
   }
@@ -1227,8 +1259,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
     output_offset -= kPointerSize;
     value = reinterpret_cast<intptr_t>(function);
     output_frame->SetFrameSlot(output_offset, value);
-    if (trace_) {
-      PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+    if (trace_scope_ != NULL) {
+      PrintF(trace_scope_->file(),
+             "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
              V8PRIxPTR " ; constructor function\n",
              top_address + output_offset, output_offset, value);
     }
@@ -1239,8 +1272,9 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; allocated receiver\n",
            top_address + output_offset, output_offset, value);
   }
@@ -1264,8 +1298,9 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
   unsigned height = 0;
   unsigned height_in_bytes = height * kPointerSize;
   const char* kind = is_setter_stub_frame ? "setter" : "getter";
-  if (trace_) {
-    PrintF("  translating %s stub => height=%u\n", kind, height_in_bytes);
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "  translating %s stub => height=%u\n", kind, height_in_bytes);
   }
 
   // We need 1 stack entry for the return address + 4 stack entries from
@@ -1300,8 +1335,9 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
   output_offset -= kPCOnStackSize;
   intptr_t callers_pc = output_[frame_index - 1]->GetPc();
   output_frame->SetCallerPc(output_offset, callers_pc);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
            " ; caller's pc\n",
            top_address + output_offset, output_offset, callers_pc);
   }
@@ -1312,8 +1348,9 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
   output_frame->SetCallerFp(output_offset, value);
   intptr_t fp_value = top_address + output_offset;
   output_frame->SetFp(fp_value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
            " ; caller's fp\n",
            fp_value, output_offset, value);
   }
@@ -1322,8 +1359,9 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = output_[frame_index - 1]->GetContext();
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
            " ; context\n",
            top_address + output_offset, output_offset, value);
   }
@@ -1332,8 +1370,9 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
            " ; function (%s sentinel)\n",
            top_address + output_offset, output_offset, value, kind);
   }
@@ -1346,8 +1385,9 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
   Code* accessor_stub = isolate_->builtins()->builtin(name);
   value = reinterpret_cast<intptr_t>(accessor_stub);
   output_frame->SetFrameSlot(output_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
            " ; code object\n",
            top_address + output_offset, output_offset, value);
   }
@@ -1423,8 +1463,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
   int input_frame_size = input_->GetFrameSize();
   int output_frame_size = height_in_bytes + fixed_frame_size;
-  if (trace_) {
-    PrintF("  translating %s => StubFailureTrampolineStub, height=%d\n",
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "  translating %s => StubFailureTrampolineStub, height=%d\n",
            CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false),
            height_in_bytes);
   }
@@ -1449,8 +1490,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   unsigned output_frame_offset = output_frame_size - kFPOnStackSize;
   intptr_t value = input_->GetFrameSlot(input_frame_offset);
   output_frame->SetCallerPc(output_frame_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; caller's pc\n",
            top_address + output_frame_offset, output_frame_offset, value);
   }
@@ -1463,8 +1505,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   intptr_t frame_ptr = input_->GetRegister(fp_reg.code());
   output_frame->SetRegister(fp_reg.code(), frame_ptr);
   output_frame->SetFp(frame_ptr);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; caller's fp\n",
            top_address + output_frame_offset, output_frame_offset, value);
   }
@@ -1476,8 +1519,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   output_frame->SetRegister(context_reg.code(), value);
   output_frame_offset -= kPointerSize;
   output_frame->SetFrameSlot(output_frame_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; context\n",
            top_address + output_frame_offset, output_frame_offset, value);
   }
@@ -1487,8 +1531,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   value = reinterpret_cast<intptr_t>(
       Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE));
   output_frame->SetFrameSlot(output_frame_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; function (stub failure sentinel)\n",
            top_address + output_frame_offset, output_frame_offset, value);
   }
@@ -1509,8 +1554,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   }
 
   output_frame->SetFrameSlot(args_arguments_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; args.arguments %s\n",
            top_address + args_arguments_offset, args_arguments_offset, value,
            arg_count_known ? "" : "(the hole)");
@@ -1520,8 +1566,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   int length_frame_offset = output_frame_offset;
   value = arg_count_known ? caller_arg_count : the_hole;
   output_frame->SetFrameSlot(length_frame_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; args.length %s\n",
            top_address + length_frame_offset, length_frame_offset, value,
            arg_count_known ? "" : "(the hole)");
@@ -1531,8 +1578,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
   value = frame_ptr + StandardFrameConstants::kCallerSPOffset -
       (output_frame_size - output_frame_offset) + kPointerSize;
   output_frame->SetFrameSlot(output_frame_offset, value);
-  if (trace_) {
-    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+  if (trace_scope_ != NULL) {
+    PrintF(trace_scope_->file(),
+           "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
            V8PRIxPTR " ; args*\n",
            top_address + output_frame_offset, output_frame_offset, value);
   }
@@ -1550,8 +1598,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
     value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
         (caller_arg_count - 1) * kPointerSize;
     output_frame->SetFrameSlot(args_arguments_offset, value);
-    if (trace_) {
-      PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+    if (trace_scope_ != NULL) {
+      PrintF(trace_scope_->file(),
+             "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
              V8PRIxPTR " ; args.arguments\n",
              top_address + args_arguments_offset, args_arguments_offset, value);
     }
@@ -1654,7 +1703,8 @@ Handle<Object> Deoptimizer::MaterializeNextHeapObject() {
         break;
       }
       default:
-        PrintF("[couldn't handle instance type %d]\n", map->instance_type());
+        PrintF(stderr,
+               "[couldn't handle instance type %d]\n", map->instance_type());
         UNREACHABLE();
     }
   }
@@ -1699,8 +1749,9 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
   for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
     HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i];
     Handle<Object> num = isolate_->factory()->NewNumber(d.value());
-    if (trace_) {
-      PrintF("Materialized a new heap number %p [%e] in slot %p\n",
+    if (trace_scope_ != NULL) {
+      PrintF(trace_scope_->file(),
+             "Materialized a new heap number %p [%e] in slot %p\n",
              reinterpret_cast<void*>(*num),
              d.value(),
              d.destination());
@@ -1713,8 +1764,9 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
     HeapNumberMaterializationDescriptor<int> d =
         deferred_objects_double_values_[i];
     Handle<Object> num = isolate_->factory()->NewNumber(d.value());
-    if (trace_) {
-      PrintF("Materialized a new heap number %p [%e] for object at %d\n",
+    if (trace_scope_ != NULL) {
+      PrintF(trace_scope_->file(),
+             "Materialized a new heap number %p [%e] for object at %d\n",
              reinterpret_cast<void*>(*num),
              d.value(),
              d.destination());
@@ -1742,19 +1794,21 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
       // the materialized object into the frame slot.
       Handle<Object> object = MaterializeNextHeapObject();
       Memory::Object_at(descriptor.slot_address()) = *object;
-      if (trace_) {
+      if (trace_scope_ != NULL) {
         if (descriptor.is_arguments()) {
-          PrintF("Materialized %sarguments object of length %d for %p: ",
+          PrintF(trace_scope_->file(),
+                 "Materialized %sarguments object of length %d for %p: ",
                  ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "",
                  Handle<JSObject>::cast(object)->elements()->length(),
                  reinterpret_cast<void*>(descriptor.slot_address()));
         } else {
-          PrintF("Materialized captured object of size %d for %p: ",
+          PrintF(trace_scope_->file(),
+                 "Materialized captured object of size %d for %p: ",
                  Handle<HeapObject>::cast(object)->Size(),
                  reinterpret_cast<void*>(descriptor.slot_address()));
         }
-        object->ShortPrint();
-        PrintF("\n");
+        object->ShortPrint(trace_scope_->file());
+        PrintF(trace_scope_->file(), "\n");
       }
     }
 
@@ -1786,8 +1840,9 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
       int index = (info->parameters_count() - 1) -
           static_cast<int>(slot - parameters_top) / kPointerSize;
 
-      if (trace_) {
-        PrintF("Materializing a new heap number %p [%e] in slot %p"
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "Materializing a new heap number %p [%e] in slot %p"
                "for parameter slot #%d\n",
                reinterpret_cast<void*>(*num),
                d.value(),
@@ -1802,8 +1857,9 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
       int index = info->expression_count() - 1 -
           static_cast<int>(slot - expressions_top) / kPointerSize;
 
-      if (trace_) {
-        PrintF("Materializing a new heap number %p [%e] in slot %p"
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "Materializing a new heap number %p [%e] in slot %p"
                "for expression slot #%d\n",
                reinterpret_cast<void*>(*num),
                d.value(),
@@ -1852,14 +1908,18 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
     case Translation::REGISTER: {
       int input_reg = iterator->Next();
       intptr_t input_value = input_->GetRegister(input_reg);
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF("0x%08" V8PRIxPTR " ; %s ", input_value,
+        PrintF(trace_scope_->file(),
+               "0x%08" V8PRIxPTR " ; %s ", input_value,
                converter.NameOfCPURegister(input_reg));
-        reinterpret_cast<Object*>(input_value)->ShortPrint();
-        PrintF("\n");
+        reinterpret_cast<Object*>(input_value)->ShortPrint(
+            trace_scope_->file());
+        PrintF(trace_scope_->file(),
+               "\n");
       }
       AddObjectTaggedValue(input_value);
       return;
@@ -1869,11 +1929,13 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
       int input_reg = iterator->Next();
       intptr_t value = input_->GetRegister(input_reg);
       bool is_smi = Smi::IsValid(value);
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF("%" V8PRIdPTR " ; %s (%s)\n", value,
+        PrintF(trace_scope_->file(),
+               "%" V8PRIdPTR " ; %s (%s)\n", value,
                converter.NameOfCPURegister(input_reg),
                TraceValueType(is_smi));
       }
@@ -1892,11 +1954,13 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
       int input_reg = iterator->Next();
       uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
       bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF("%" V8PRIdPTR " ; uint %s (%s)\n", value,
+        PrintF(trace_scope_->file(),
+               "%" V8PRIdPTR " ; uint %s (%s)\n", value,
                converter.NameOfCPURegister(input_reg),
                TraceValueType(is_smi));
       }
@@ -1914,11 +1978,13 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
     case Translation::DOUBLE_REGISTER: {
       int input_reg = iterator->Next();
       double value = input_->GetDoubleRegister(input_reg);
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF("%e ; %s\n", value,
+        PrintF(trace_scope_->file(),
+               "%e ; %s\n", value,
                DoubleRegister::AllocationIndexToString(input_reg));
       }
       AddObjectDoubleValue(value);
@@ -1929,13 +1995,17 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
       int input_slot_index = iterator->Next();
       unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
       intptr_t input_value = input_->GetFrameSlot(input_offset);
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF("0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset);
-        reinterpret_cast<Object*>(input_value)->ShortPrint();
-        PrintF("\n");
+        PrintF(trace_scope_->file(),
+               "0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset);
+        reinterpret_cast<Object*>(input_value)->ShortPrint(
+            trace_scope_->file());
+        PrintF(trace_scope_->file(),
+               "\n");
       }
       AddObjectTaggedValue(input_value);
       return;
@@ -1946,11 +2016,13 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
       unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
       intptr_t value = input_->GetFrameSlot(input_offset);
       bool is_smi = Smi::IsValid(value);
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF("%" V8PRIdPTR " ; [sp + %d] (%s)\n",
+        PrintF(trace_scope_->file(),
+               "%" V8PRIdPTR " ; [sp + %d] (%s)\n",
                value, input_offset, TraceValueType(is_smi));
       }
       if (is_smi) {
@@ -1970,11 +2042,13 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
       uintptr_t value =
           static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
       bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF("%" V8PRIdPTR " ; [sp + %d] (uint %s)\n",
+        PrintF(trace_scope_->file(),
+               "%" V8PRIdPTR " ; [sp + %d] (uint %s)\n",
                value, input_offset, TraceValueType(is_smi));
       }
       if (is_smi) {
@@ -1992,11 +2066,13 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
       int input_slot_index = iterator->Next();
       unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
       double value = input_->GetDoubleFrameSlot(input_offset);
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF("%e ; [sp + %d]\n", value, input_offset);
+        PrintF(trace_scope_->file(),
+               "%e ; [sp + %d]\n", value, input_offset);
       }
       AddObjectDoubleValue(value);
       return;
@@ -2004,12 +2080,14 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
 
     case Translation::LITERAL: {
       Object* literal = ComputeLiteral(iterator->Next());
-      if (trace_) {
-        PrintF("      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        literal->ShortPrint();
-        PrintF(" ; literal\n");
+        literal->ShortPrint(trace_scope_->file());
+        PrintF(trace_scope_->file(),
+               " ; literal\n");
       }
       intptr_t value = reinterpret_cast<intptr_t>(literal);
       AddObjectTaggedValue(value);
@@ -2018,12 +2096,14 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
 
     case Translation::DUPLICATED_OBJECT: {
       int object_index = iterator->Next();
-      if (trace_) {
-        PrintF("      nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        isolate_->heap()->arguments_marker()->ShortPrint();
-        PrintF(" ; duplicate of object #%d\n", object_index);
+        isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file());
+        PrintF(trace_scope_->file(),
+               " ; duplicate of object #%d\n", object_index);
       }
       // Use the materialization marker value as a sentinel and fill in
       // the object after the deoptimized frame is built.
@@ -2038,12 +2118,14 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
     case Translation::CAPTURED_OBJECT: {
       int length = iterator->Next();
       bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
-      if (trace_) {
-        PrintF("      nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "      nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        isolate_->heap()->arguments_marker()->ShortPrint();
-        PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args);
+        isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file());
+        PrintF(trace_scope_->file(),
+               " ; object (length = %d, is_args = %d)\n", length, is_args);
       }
       // Use the materialization marker value as a sentinel and fill in
       // the object after the deoptimized frame is built.
@@ -2089,15 +2171,17 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
     case Translation::REGISTER: {
       int input_reg = iterator->Next();
       intptr_t input_value = input_->GetRegister(input_reg);
-      if (trace_) {
+      if (trace_scope_ != NULL) {
         PrintF(
+            trace_scope_->file(),
             "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ",
             output_[frame_index]->GetTop() + output_offset,
             output_offset,
             input_value,
             converter.NameOfCPURegister(input_reg));
-        reinterpret_cast<Object*>(input_value)->ShortPrint();
-        PrintF("\n");
+        reinterpret_cast<Object*>(input_value)->ShortPrint(
+            trace_scope_->file());
+        PrintF(trace_scope_->file(), "\n");
       }
       output_[frame_index]->SetFrameSlot(output_offset, input_value);
       return;
@@ -2108,8 +2192,9 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
       intptr_t value = input_->GetRegister(input_reg);
       bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
           Smi::IsValid(value);
-      if (trace_) {
+      if (trace_scope_ != NULL) {
         PrintF(
+            trace_scope_->file(),
             "    0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
             output_[frame_index]->GetTop() + output_offset,
             output_offset,
@@ -2139,8 +2224,9 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
       uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
       bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
           (value <= static_cast<uintptr_t>(Smi::kMaxValue));
-      if (trace_) {
+      if (trace_scope_ != NULL) {
         PrintF(
+            trace_scope_->file(),
             "    0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIuPTR
             " ; uint %s (%s)\n",
             output_[frame_index]->GetTop() + output_offset,
@@ -2169,8 +2255,9 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
     case Translation::DOUBLE_REGISTER: {
       int input_reg = iterator->Next();
       double value = input_->GetDoubleRegister(input_reg);
-      if (trace_) {
-        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "    0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n",
                output_[frame_index]->GetTop() + output_offset,
                output_offset,
                value,
@@ -2187,15 +2274,18 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
       int input_slot_index = iterator->Next();
       unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
       intptr_t input_value = input_->GetFrameSlot(input_offset);
-      if (trace_) {
-        PrintF("    0x%08" V8PRIxPTR ": ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "    0x%08" V8PRIxPTR ": ",
                output_[frame_index]->GetTop() + output_offset);
-        PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ",
+        PrintF(trace_scope_->file(),
+               "[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ",
                output_offset,
                input_value,
                input_offset);
-        reinterpret_cast<Object*>(input_value)->ShortPrint();
-        PrintF("\n");
+        reinterpret_cast<Object*>(input_value)->ShortPrint(
+            trace_scope_->file());
+        PrintF(trace_scope_->file(), "\n");
       }
       output_[frame_index]->SetFrameSlot(output_offset, input_value);
       return;
@@ -2207,10 +2297,12 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
       intptr_t value = input_->GetFrameSlot(input_offset);
       bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
           Smi::IsValid(value);
-      if (trace_) {
-        PrintF("    0x%08" V8PRIxPTR ": ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "    0x%08" V8PRIxPTR ": ",
                output_[frame_index]->GetTop() + output_offset);
-        PrintF("[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n",
+        PrintF(trace_scope_->file(),
+               "[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n",
                output_offset,
                value,
                input_offset,
@@ -2240,10 +2332,12 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
           static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
       bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
           (value <= static_cast<uintptr_t>(Smi::kMaxValue));
-      if (trace_) {
-        PrintF("    0x%08" V8PRIxPTR ": ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "    0x%08" V8PRIxPTR ": ",
                output_[frame_index]->GetTop() + output_offset);
-        PrintF("[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n",
+        PrintF(trace_scope_->file(),
+               "[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n",
                output_offset,
                value,
                input_offset,
@@ -2270,8 +2364,9 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
       int input_slot_index = iterator->Next();
       unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
       double value = input_->GetDoubleFrameSlot(input_offset);
-      if (trace_) {
-        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "    0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n",
                output_[frame_index]->GetTop() + output_offset,
                output_offset,
                value,
@@ -2286,12 +2381,13 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
 
     case Translation::LITERAL: {
       Object* literal = ComputeLiteral(iterator->Next());
-      if (trace_) {
-        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "    0x%08" V8PRIxPTR ": [top + %d] <- ",
                output_[frame_index]->GetTop() + output_offset,
                output_offset);
-        literal->ShortPrint();
-        PrintF(" ; literal\n");
+        literal->ShortPrint(trace_scope_->file());
+        PrintF(trace_scope_->file(), " ; literal\n");
       }
       intptr_t value = reinterpret_cast<intptr_t>(literal);
       output_[frame_index]->SetFrameSlot(output_offset, value);
@@ -2300,12 +2396,14 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
 
     case Translation::DUPLICATED_OBJECT: {
       int object_index = iterator->Next();
-      if (trace_) {
-        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "    0x%08" V8PRIxPTR ": [top + %d] <- ",
                output_[frame_index]->GetTop() + output_offset,
                output_offset);
-        isolate_->heap()->arguments_marker()->ShortPrint();
-        PrintF(" ; duplicate of object #%d\n", object_index);
+        isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file());
+        PrintF(trace_scope_->file(),
+               " ; duplicate of object #%d\n", object_index);
       }
       // Use the materialization marker value as a sentinel and fill in
       // the object after the deoptimized frame is built.
@@ -2321,12 +2419,14 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
     case Translation::CAPTURED_OBJECT: {
       int length = iterator->Next();
       bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
-      if (trace_) {
-        PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- ",
+      if (trace_scope_ != NULL) {
+        PrintF(trace_scope_->file(),
+               "    0x%08" V8PRIxPTR ": [top + %d] <- ",
                output_[frame_index]->GetTop() + output_offset,
                output_offset);
-        isolate_->heap()->arguments_marker()->ShortPrint();
-        PrintF(" ; object (length = %d, is_args = %d)\n", length, is_args);
+        isolate_->heap()->arguments_marker()->ShortPrint(trace_scope_->file());
+        PrintF(trace_scope_->file(),
+               " ; object (length = %d, is_args = %d)\n", length, is_args);
       }
       // Use the materialization marker value as a sentinel and fill in
       // the object after the deoptimized frame is built.
index 4e9d281ea52f762305a3435b364b88674dd2f55f..f5530a8f18f54381b3eea41d96c6a12abe5b4b06 100644 (file)
@@ -451,7 +451,7 @@ class Deoptimizer : public Malloced {
   DisallowHeapAllocation* disallow_heap_allocation_;
 #endif  // DEBUG
 
-  bool trace_;
+  CodeTracer::Scope* trace_scope_;
 
   static const int table_entry_size_;
 
index 9228944d00e342eafa30aecc453bff1508f0632d..f0444d1f26a823296c265caf858bd54811a4c3ad 100644 (file)
@@ -795,6 +795,12 @@ DEFINE_bool(log_timer_events, false,
 DEFINE_implication(log_timer_events, log_internal_timer_events)
 DEFINE_implication(log_internal_timer_events, prof)
 
+DEFINE_bool(redirect_code_traces, false,
+            "output deopt information and disassembly into file "
+            "code-<pid>-<isolate id>.asm")
+DEFINE_string(redirect_code_traces_to, NULL,
+            "output deopt information and disassembly into the given file")
+
 //
 // Disassembler only flags
 //
index 71cd301581fae8c3679c546f3ff4a2834440b365..0e764bfb692b1dd685d3b5dd2ef62f19c560ee1e 100644 (file)
@@ -2465,6 +2465,12 @@ HTracer* Isolate::GetHTracer() {
 }
 
 
+CodeTracer* Isolate::GetCodeTracer() {
+  if (code_tracer() == NULL) set_code_tracer(new CodeTracer(id()));
+  return code_tracer();
+}
+
+
 Map* Isolate::get_initial_js_array_map(ElementsKind kind) {
   Context* native_context = context()->native_context();
   Object* maybe_map_array = native_context->js_array_maps();
index cef7159cfc5a65394e25a118cb07fa79ab647469..c13714f68246cd7f39702c3a1e998ae91df7a116 100644 (file)
@@ -55,6 +55,7 @@ class Bootstrapper;
 class CodeGenerator;
 class CodeRange;
 struct CodeStubInterfaceDescriptor;
+class CodeTracer;
 class CompilationCache;
 class ContextSlotCache;
 class ContextSwitcher;
@@ -377,6 +378,7 @@ typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache;
   V(bool, observer_delivery_pending, false)                                    \
   V(HStatistics*, hstatistics, NULL)                                           \
   V(HTracer*, htracer, NULL)                                                   \
+  V(CodeTracer*, code_tracer, NULL)                                            \
   ISOLATE_DEBUGGER_INIT_LIST(V)
 
 class Isolate {
@@ -1126,6 +1128,7 @@ class Isolate {
 
   HStatistics* GetHStatistics();
   HTracer* GetHTracer();
+  CodeTracer* GetCodeTracer();
 
   FunctionEntryHook function_entry_hook() { return function_entry_hook_; }
   void set_function_entry_hook(FunctionEntryHook function_entry_hook) {
@@ -1507,6 +1510,73 @@ inline void Context::mark_out_of_memory() {
   native_context()->set_out_of_memory(GetIsolate()->heap()->true_value());
 }
 
+class CodeTracer V8_FINAL : public Malloced {
+ public:
+  explicit CodeTracer(int isolate_id)
+      : file_(NULL),
+        scope_depth_(0) {
+    if (!ShouldRedirect()) {
+      file_ = stdout;
+      return;
+    }
+
+    if (FLAG_redirect_code_traces_to == NULL) {
+      OS::SNPrintF(filename_,
+                   "code-%d-%d.asm",
+                   OS::GetCurrentProcessId(),
+                   isolate_id);
+    } else {
+      OS::StrNCpy(filename_, FLAG_redirect_code_traces_to, filename_.length());
+    }
+
+    WriteChars(filename_.start(), "", 0, false);
+  }
+
+  class Scope {
+   public:
+    explicit Scope(CodeTracer* tracer) : tracer_(tracer) { tracer->OpenFile(); }
+    ~Scope() { tracer_->CloseFile();  }
+
+    FILE* file() const { return tracer_->file(); }
+
+   private:
+    CodeTracer* tracer_;
+  };
+
+  void OpenFile() {
+    if (!ShouldRedirect()) {
+      return;
+    }
+
+    if (file_ == NULL) {
+      file_ = OS::FOpen(filename_.start(), "a");
+    }
+
+    scope_depth_++;
+  }
+
+  void CloseFile() {
+    if (!ShouldRedirect()) {
+      return;
+    }
+
+    if (--scope_depth_ == 0) {
+      fclose(file_);
+      file_ = NULL;
+    }
+  }
+
+  FILE* file() const { return file_; }
+
+ private:
+  static bool ShouldRedirect() {
+    return FLAG_redirect_code_traces;
+  }
+
+  EmbeddedVector<char, 128> filename_;
+  FILE* file_;
+  int scope_depth_;
+};
 
 } }  // namespace v8::internal
 
index 3a3d91599c3ea045893f7b0ef773c6533499ed5a..1f3f2a172ab5196c8a9dfe98216ec2350d41b50f 100644 (file)
@@ -1150,7 +1150,9 @@ RegExpEngine::CompilationResult RegExpCompiler::Assemble(
   work_list_ = NULL;
 #ifdef DEBUG
   if (FLAG_print_code) {
-    Handle<Code>::cast(code)->Disassemble(*pattern->ToCString());
+    CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer());
+    Handle<Code>::cast(code)->Disassemble(*pattern->ToCString(),
+                                          trace_scope.file());
   }
   if (FLAG_trace_regexp_assembler) {
     delete macro_assembler_;
index 60c1ef4c38e2c21d7a4d52799dc82744def79055..37ae9b6d7a925acb4d1e0dcb14d96a4712f60fd4 100644 (file)
@@ -830,7 +830,7 @@ void JSTypedArray::JSTypedArrayPrint(FILE* out) {
   byte_length()->ShortPrint(out);
   PrintF(out, "\n - length = ");
   length()->ShortPrint(out);
-  PrintF("\n");
+  PrintF(out, "\n");
   PrintElements(out);
 }
 
@@ -844,7 +844,7 @@ void JSDataView::JSDataViewPrint(FILE* out) {
   byte_offset()->ShortPrint(out);
   PrintF(out, "\n - byte_length = ");
   byte_length()->ShortPrint(out);
-  PrintF("\n");
+  PrintF(out, "\n");
 }
 
 
index 489f3f5ac7a6ecbdf136c203f3c5df97289af406..441c25e70c649aecb7b54f49d5670c1daf136569 100644 (file)
@@ -10831,7 +10831,7 @@ Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) {
 }
 
 
-void Code::PrintDeoptLocation(int bailout_id) {
+void Code::PrintDeoptLocation(FILE* out, int bailout_id) {
   const char* last_comment = NULL;
   int mask = RelocInfo::ModeMask(RelocInfo::COMMENT)
       | RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
@@ -10845,7 +10845,7 @@ void Code::PrintDeoptLocation(int bailout_id) {
           (bailout_id == Deoptimizer::GetDeoptimizationId(
               GetIsolate(), info->target_address(), Deoptimizer::SOFT))) {
         CHECK(RelocInfo::IsRuntimeEntry(info->rmode()));
-        PrintF("            %s\n", last_comment);
+        PrintF(out, "            %s\n", last_comment);
         return;
       }
     }
@@ -11047,10 +11047,10 @@ void DeoptimizationOutputData::DeoptimizationOutputDataPrint(FILE* out) {
          this->DeoptPoints());
   if (this->DeoptPoints() == 0) return;
 
-  PrintF("%6s  %8s  %s\n", "ast id", "pc", "state");
+  PrintF(out, "%6s  %8s  %s\n", "ast id", "pc", "state");
   for (int i = 0; i < this->DeoptPoints(); i++) {
     int pc_and_state = this->PcAndState(i)->value();
-    PrintF("%6d  %8d  %s\n",
+    PrintF(out, "%6d  %8d  %s\n",
            this->AstId(i).ToInt(),
            FullCodeGenerator::PcField::decode(pc_and_state),
            FullCodeGenerator::State2String(
@@ -11161,7 +11161,7 @@ void Code::Disassemble(const char* name, FILE* out) {
         DeoptimizationInputData::cast(this->deoptimization_data());
     data->DeoptimizationInputDataPrint(out);
   }
-  PrintF("\n");
+  PrintF(out, "\n");
 
   if (is_crankshafted()) {
     SafepointTable table(this);
@@ -11169,7 +11169,7 @@ void Code::Disassemble(const char* name, FILE* out) {
     for (unsigned i = 0; i < table.length(); i++) {
       unsigned pc_offset = table.GetPcOffset(i);
       PrintF(out, "%p  %4d  ", (instruction_start() + pc_offset), pc_offset);
-      table.PrintEntry(i);
+      table.PrintEntry(i, out);
       PrintF(out, " (sp -> fp)");
       SafepointEntry entry = table.GetEntry(i);
       if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
@@ -11210,7 +11210,7 @@ void Code::Disassemble(const char* name, FILE* out) {
 #endif
   }
 
-  PrintF("RelocInfo (size = %d)\n", relocation_size());
+  PrintF(out, "RelocInfo (size = %d)\n", relocation_size());
   for (RelocIterator it(this); !it.done(); it.next()) {
     it.rinfo()->Print(GetIsolate(), out);
   }
index 46394074dec2fcc616eb9136d24dcaf879b91fb5..4a8cd896f297a9aab77a682dbcd21eae2ab7a0ac 100644 (file)
@@ -5376,7 +5376,7 @@ class Code: public HeapObject {
     return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
   }
 
-  void PrintDeoptLocation(int bailout_id);
+  void PrintDeoptLocation(FILE* out, int bailout_id);
   bool CanDeoptAt(Address pc);
 
 #ifdef VERIFY_HEAP
index b56556572ebcd03fba08260f6793784e945961dd..beecb27582de9ecbf3754495e796bc34c1e22504 100644 (file)
@@ -83,7 +83,7 @@ SafepointEntry SafepointTable::FindEntry(Address pc) const {
 }
 
 
-void SafepointTable::PrintEntry(unsigned index) const {
+void SafepointTable::PrintEntry(unsigned index, FILE* out) const {
   disasm::NameConverter converter;
   SafepointEntry entry = GetEntry(index);
   uint8_t* bits = entry.bits();
@@ -93,25 +93,25 @@ void SafepointTable::PrintEntry(unsigned index) const {
     ASSERT(IsAligned(kNumSafepointRegisters, kBitsPerByte));
     const int first = kNumSafepointRegisters >> kBitsPerByteLog2;
     int last = entry_size_ - 1;
-    for (int i = first; i < last; i++) PrintBits(bits[i], kBitsPerByte);
+    for (int i = first; i < last; i++) PrintBits(out, bits[i], kBitsPerByte);
     int last_bits = code_->stack_slots() - ((last - first) * kBitsPerByte);
-    PrintBits(bits[last], last_bits);
+    PrintBits(out, bits[last], last_bits);
 
     // Print the registers (if any).
     if (!entry.HasRegisters()) return;
     for (int j = 0; j < kNumSafepointRegisters; j++) {
       if (entry.HasRegisterAt(j)) {
-        PrintF(" | %s", converter.NameOfCPURegister(j));
+        PrintF(out, " | %s", converter.NameOfCPURegister(j));
       }
     }
   }
 }
 
 
-void SafepointTable::PrintBits(uint8_t byte, int digits) {
+void SafepointTable::PrintBits(FILE* out, uint8_t byte, int digits) {
   ASSERT(digits >= 0 && digits <= kBitsPerByte);
   for (int i = 0; i < digits; i++) {
-    PrintF("%c", ((byte & (1 << i)) == 0) ? '0' : '1');
+    PrintF(out, "%c", ((byte & (1 << i)) == 0) ? '0' : '1');
   }
 }
 
index fc8bf7a411a8831193a5a155fc79d52d6c11e451..ea35253ff8458f0b7e8040f2cecf50bf5ad6b84d 100644 (file)
@@ -126,7 +126,7 @@ class SafepointTable BASE_EMBEDDED {
   // Returns the entry for the given pc.
   SafepointEntry FindEntry(Address pc) const;
 
-  void PrintEntry(unsigned index) const;
+  void PrintEntry(unsigned index, FILE* out = stdout) const;
 
  private:
   static const uint8_t kNoRegisters = 0xFF;
@@ -149,7 +149,7 @@ class SafepointTable BASE_EMBEDDED {
     return GetPcOffsetLocation(index) + kPcSize;
   }
 
-  static void PrintBits(uint8_t byte, int digits);
+  static void PrintBits(FILE* out, uint8_t byte, int digits);
 
   DisallowHeapAllocation no_allocation_;
   Code* code_;
index 8ab4e262c823cfcf9f49770701d6ff73dc7906cb..1bc4b1314e79cbff3a4616181ed3f236c5095557 100644 (file)
@@ -1096,7 +1096,10 @@ Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
   masm_.GetCode(&desc);
   Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
 #ifdef ENABLE_DISASSEMBLER
-  if (FLAG_print_code_stubs) code->Disassemble(name);
+  if (FLAG_print_code_stubs) {
+    CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
+    code->Disassemble(name, trace_scope.file());
+  }
 #endif
   return code;
 }