Index: src/codegen.cc |
diff --git a/src/codegen.cc b/src/codegen.cc |
index afd8a6f592972da8bf5d9e150a4b7fa5566ae191..54350698af85a1cdf788a8f2dbda2225f75f856c 100644 |
--- a/src/codegen.cc |
+++ b/src/codegen.cc |
@@ -137,8 +137,100 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm, |
return code; |
} |
+// Print function's source if it was not printed before. |
+// Return a sequential id under which this function was printed. |
+static int PrintFunctionSource(CompilationInfo* info, |
+ std::vector<Handle<SharedFunctionInfo>>* printed, |
+ int inlining_id, |
+ Handle<SharedFunctionInfo> shared) { |
+ // Outermost function has source id -1 and inlined functions take |
+ // source ids starting from 0. |
+ int source_id = -1; |
+ if (inlining_id != SourcePosition::kNotInlined) { |
+ for (unsigned i = 0; i < printed->size(); i++) { |
+ if (printed->at(i).is_identical_to(shared)) { |
+ return i; |
+ } |
+ } |
+ source_id = static_cast<int>(printed->size()); |
+ printed->push_back(shared); |
+ } |
+ |
+ Isolate* isolate = info->isolate(); |
+ if (!shared->script()->IsUndefined(isolate)) { |
+ Handle<Script> script(Script::cast(shared->script()), isolate); |
+ |
+ if (!script->source()->IsUndefined(isolate)) { |
+ CodeTracer::Scope tracing_scope(isolate->GetCodeTracer()); |
+ Object* source_name = script->name(); |
+ OFStream os(tracing_scope.file()); |
+ os << "--- FUNCTION SOURCE ("; |
+ if (source_name->IsString()) { |
+ os << String::cast(source_name)->ToCString().get() << ":"; |
+ } |
+ os << shared->DebugName()->ToCString().get() << ") id{"; |
+ os << info->optimization_id() << "," << source_id << "} start{"; |
+ os << shared->start_position() << "} ---\n"; |
+ { |
+ DisallowHeapAllocation no_allocation; |
+ int start = shared->start_position(); |
+ int len = shared->end_position() - start; |
+ String::SubStringRange source(String::cast(script->source()), start, |
+ len); |
+ for (const auto& c : source) { |
+ os << AsReversiblyEscapedUC16(c); |
+ } |
+ } |
+ |
+ os << "\n--- END ---\n"; |
+ } |
+ } |
+ |
+ return source_id; |
+} |
+ |
+// Print information for the given inlining: which function was inlined and |
+// where the inlining occured. |
+static void PrintInlinedFunctionInfo( |
+ CompilationInfo* info, int source_id, int inlining_id, |
+ const CompilationInfo::InlinedFunctionHolder& h) { |
+ CodeTracer::Scope tracing_scope(info->isolate()->GetCodeTracer()); |
+ OFStream os(tracing_scope.file()); |
+ os << "INLINE (" << h.shared_info->DebugName()->ToCString().get() << ") id{" |
+ << info->optimization_id() << "," << source_id << "} AS " << inlining_id |
+ << " AT "; |
+ const SourcePosition position = h.position.position; |
+ if (position.IsKnown()) { |
+ os << "<" << position.InliningId() << ":" << position.ScriptOffset() << ">"; |
+ } else { |
+ os << "<?>"; |
+ } |
+ os << std::endl; |
+} |
+ |
+// Print the source of all functions that participated in this optimizing |
+// compilation. For inlined functions print source position of their inlining. |
+static void DumpParticipatingSource(CompilationInfo* info) { |
+ AllowDeferredHandleDereference allow_deference_for_print_code; |
+ |
+ std::vector<Handle<SharedFunctionInfo>> printed; |
+ printed.reserve(info->inlined_functions().size()); |
+ |
+ PrintFunctionSource(info, &printed, SourcePosition::kNotInlined, |
+ info->shared_info()); |
+ const auto& inlined = info->inlined_functions(); |
+ for (unsigned id = 0; id < inlined.size(); id++) { |
+ const int source_id = |
+ PrintFunctionSource(info, &printed, id, inlined[id].shared_info); |
+ PrintInlinedFunctionInfo(info, source_id, id, inlined[id]); |
+ } |
+} |
void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) { |
+ if (FLAG_print_opt_source && info->IsOptimizing()) { |
+ DumpParticipatingSource(info); |
+ } |
+ |
#ifdef ENABLE_DISASSEMBLER |
AllowDeferredHandleDereference allow_deference_for_print_code; |
Isolate* isolate = info->isolate(); |