Commit 686d8c86 authored by vegorov's avatar vegorov Committed by Commit bot

Move TraceInlinedFunction from Hydrogen graph builder to internal::CodeGenerator.

This allows to share source dumping infrastructure between CS and TF and opens a possibility for external tools like IRHydra to perform deoptimization to source mapping for TF generated code based on --trace-deopt --print-opt-code --code-comments output.

This CL also restores an old TraceInlinedFunction behavior which was lost during source positions refactoring - originally TraceInlinedFunction dumped source code only once per-SFI to avoid large traces whenever some helper function is inlined multiple times.

This CL also adds --print-opt-source flag that would in the future replace obsolete --hydrogen-track-positions.

BUG=

Review-Url: https://codereview.chromium.org/2575703003
Cr-Commit-Position: refs/heads/master@{#41758}
parent 3238b337
...@@ -137,8 +137,100 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm, ...@@ -137,8 +137,100 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
return code; 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) { void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
if (FLAG_print_opt_source && info->IsOptimizing()) {
DumpParticipatingSource(info);
}
#ifdef ENABLE_DISASSEMBLER #ifdef ENABLE_DISASSEMBLER
AllowDeferredHandleDereference allow_deference_for_print_code; AllowDeferredHandleDereference allow_deference_for_print_code;
Isolate* isolate = info->isolate(); Isolate* isolate = info->isolate();
......
...@@ -497,6 +497,9 @@ void GraphC1Visualizer::PrintSchedule(const char* phase, ...@@ -497,6 +497,9 @@ void GraphC1Visualizer::PrintSchedule(const char* phase,
if (positions != nullptr) { if (positions != nullptr) {
SourcePosition position = positions->GetSourcePosition(node); SourcePosition position = positions->GetSourcePosition(node);
if (position.IsKnown()) { if (position.IsKnown()) {
if (position.isInlined()) {
os_ << "inlining(" << position.InliningId() << "),";
}
os_ << " pos:" << position.ScriptOffset(); os_ << " pos:" << position.ScriptOffset();
} }
} }
......
...@@ -1362,10 +1362,6 @@ HGraph* HGraphBuilder::CreateGraph() { ...@@ -1362,10 +1362,6 @@ HGraph* HGraphBuilder::CreateGraph() {
DCHECK(!FLAG_minimal); DCHECK(!FLAG_minimal);
graph_ = new (zone()) HGraph(info_, descriptor_); graph_ = new (zone()) HGraph(info_, descriptor_);
if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_);
if (!info_->IsStub() && is_tracking_positions()) {
TraceInlinedFunction(info_->shared_info(), SourcePosition::Unknown(),
SourcePosition::kNotInlined);
}
CompilationPhase phase("H_Block building", info_); CompilationPhase phase("H_Block building", info_);
set_current_block(graph()->entry_block()); set_current_block(graph()->entry_block());
if (!BuildGraph()) return NULL; if (!BuildGraph()) return NULL;
...@@ -1373,57 +1369,6 @@ HGraph* HGraphBuilder::CreateGraph() { ...@@ -1373,57 +1369,6 @@ HGraph* HGraphBuilder::CreateGraph() {
return graph_; return graph_;
} }
void HGraphBuilder::TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
SourcePosition position,
int inlining_id) {
DCHECK(is_tracking_positions());
if (!shared->script()->IsUndefined(isolate())) {
Handle<Script> script(Script::cast(shared->script()), isolate());
if (FLAG_hydrogen_track_positions &&
!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() << "," << inlining_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";
}
}
if (FLAG_hydrogen_track_positions &&
inlining_id != SourcePosition::kNotInlined) {
CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
OFStream os(tracing_scope.file());
os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{"
<< info_->optimization_id() << "," << inlining_id << "} AS "
<< inlining_id << " AT ";
if (position.IsKnown()) {
os << "<" << position.InliningId() << ":" << position.ScriptOffset()
<< ">";
} else {
os << "<?>";
}
os << std::endl;
}
}
HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
DCHECK(current_block() != NULL); DCHECK(current_block() != NULL);
...@@ -8171,10 +8116,6 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, ...@@ -8171,10 +8116,6 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
&bounds_) &bounds_)
.Run(); .Run();
if (is_tracking_positions()) {
TraceInlinedFunction(target_shared, source_position(), inlining_id);
}
// Save the pending call context. Set up new one for the inlined function. // Save the pending call context. Set up new one for the inlined function.
// The function state is new-allocated because we need to delete it // The function state is new-allocated because we need to delete it
// in two different places. // in two different places.
......
...@@ -463,12 +463,6 @@ class HGraph final : public ZoneObject { ...@@ -463,12 +463,6 @@ class HGraph final : public ZoneObject {
void DecrementInNoSideEffectsScope() { no_side_effects_scope_count_--; } void DecrementInNoSideEffectsScope() { no_side_effects_scope_count_--; }
bool IsInsideNoSideEffectsScope() { return no_side_effects_scope_count_ > 0; } bool IsInsideNoSideEffectsScope() { return no_side_effects_scope_count_ > 0; }
// If we are tracking source positions then this function assigns a unique
// identifier to each inlining and dumps function source if it was inlined
// for the first time during the current optimization.
int TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
SourcePosition position);
private: private:
HConstant* ReinsertConstantIfNecessary(HConstant* constant); HConstant* ReinsertConstantIfNecessary(HConstant* constant);
HConstant* GetConstant(SetOncePointer<HConstant>* pointer, HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
...@@ -1853,9 +1847,6 @@ class HGraphBuilder { ...@@ -1853,9 +1847,6 @@ class HGraphBuilder {
bool is_tracking_positions() { return track_positions_; } bool is_tracking_positions() { return track_positions_; }
void TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
SourcePosition position, int inlining_id);
HValue* BuildAllocateEmptyArrayBuffer(HValue* byte_length); HValue* BuildAllocateEmptyArrayBuffer(HValue* byte_length);
template <typename ViewClass> template <typename ViewClass>
void BuildArrayBufferViewInitialization(HValue* obj, void BuildArrayBufferViewInitialization(HValue* obj,
......
...@@ -1119,6 +1119,10 @@ DEFINE_STRING(redirect_code_traces_to, NULL, ...@@ -1119,6 +1119,10 @@ DEFINE_STRING(redirect_code_traces_to, NULL,
DEFINE_BOOL(hydrogen_track_positions, false, DEFINE_BOOL(hydrogen_track_positions, false,
"track source code positions when building IR") "track source code positions when building IR")
DEFINE_BOOL(print_opt_source, false,
"print source code of optimized and inlined functions")
DEFINE_IMPLICATION(hydrogen_track_positions, print_opt_source)
// //
// Disassembler only flags // Disassembler only flags
// //
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment