CpuProfiler: move InlinedFunctionInfo class from HGraphBuilder to CompilationInfo.

A function could be deoptimized due to a deopt in the inlined code.
The inlined function might be defined in another script. So we need to
track the information about the inlined functions (scriptId and offset).
We already have the tracking code which is behind FLAG_hydrogen_track_position.
So as the first step we need to make the info accessible by CPU profiler.
In the follow-up patches I'll add the code which will enable position
tracking and push the info into CodeEntry entries.

BUG=452067
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#26680}
This commit is contained in:
loislo 2015-02-17 01:44:44 -08:00 committed by Commit bot
parent 839efa2e26
commit e60ec273cc
5 changed files with 101 additions and 82 deletions

View File

@ -147,6 +147,14 @@ void CompilationInfo::Initialize(Isolate* isolate,
opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count();
no_frame_ranges_ = isolate->cpu_profiler()->is_profiling()
? new List<OffsetRange>(2) : NULL;
if (FLAG_hydrogen_track_positions) {
inlined_function_infos_ = new List<InlinedFunctionInfo>(5);
inlining_id_to_function_id_ = new List<int>(5);
} else {
inlined_function_infos_ = NULL;
inlining_id_to_function_id_ = NULL;
}
for (int i = 0; i < DependentCode::kGroupCount; i++) {
dependencies_[i] = NULL;
}
@ -193,6 +201,8 @@ CompilationInfo::~CompilationInfo() {
}
delete deferred_handles_;
delete no_frame_ranges_;
delete inlined_function_infos_;
delete inlining_id_to_function_id_;
if (ast_value_factory_owned_) delete ast_value_factory_;
#ifdef DEBUG
// Check that no dependent maps have been added or added dependent maps have
@ -313,6 +323,62 @@ bool CompilationInfo::is_simple_parameter_list() {
}
int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
int raw_position) {
if (!FLAG_hydrogen_track_positions) {
return 0;
}
DCHECK(inlined_function_infos_);
DCHECK(inlining_id_to_function_id_);
int id = 0;
for (; id < inlined_function_infos_->length(); id++) {
if (inlined_function_infos_->at(id).shared().is_identical_to(shared)) {
break;
}
}
if (id == inlined_function_infos_->length()) {
inlined_function_infos_->Add(InlinedFunctionInfo(shared));
if (!shared->script()->IsUndefined()) {
Handle<Script> script(Script::cast(shared->script()));
if (!script->source()->IsUndefined()) {
CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
OFStream os(tracing_scope.file());
os << "--- FUNCTION SOURCE (" << shared->DebugName()->ToCString().get()
<< ") id{" << optimization_id() << "," << id << "} ---\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";
}
}
}
int inline_id = inlining_id_to_function_id_->length();
inlining_id_to_function_id_->Add(id);
if (inline_id != 0) {
CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
OFStream os(tracing_scope.file());
HSourcePosition position = HSourcePosition::FromRaw(raw_position);
os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{"
<< optimization_id() << "," << id << "} AS " << inline_id << " AT "
<< position << std::endl;
}
return inline_id;
}
class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder {
public:
explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info)

View File

@ -30,6 +30,20 @@ struct OffsetRange {
};
class InlinedFunctionInfo {
public:
explicit InlinedFunctionInfo(Handle<SharedFunctionInfo> shared)
: shared_(shared), start_position_(shared->start_position()) {}
Handle<SharedFunctionInfo> shared() const { return shared_; }
int start_position() const { return start_position_; }
private:
Handle<SharedFunctionInfo> shared_;
int start_position_;
};
class ScriptData {
public:
ScriptData(const byte* data, int length);
@ -383,6 +397,14 @@ class CompilationInfo {
return result;
}
List<InlinedFunctionInfo>* inlined_function_infos() {
return inlined_function_infos_;
}
List<int>* inlining_id_to_function_id() {
return inlining_id_to_function_id_;
}
int TraceInlinedFunction(Handle<SharedFunctionInfo> shared, int raw_position);
Handle<Foreign> object_wrapper() {
if (object_wrapper_.is_null()) {
object_wrapper_ =
@ -526,6 +548,8 @@ class CompilationInfo {
int prologue_offset_;
List<OffsetRange>* no_frame_ranges_;
List<InlinedFunctionInfo>* inlined_function_infos_;
List<int>* inlining_id_to_function_id_;
// A copy of shared_info()->opt_count() to avoid handle deref
// during graph optimization.

View File

@ -426,6 +426,9 @@ class HSourcePosition {
static HSourcePosition Unknown() {
return HSourcePosition(RelocInfo::kNoPosition);
}
static HSourcePosition FromRaw(int raw_value) {
return HSourcePosition(raw_value);
}
bool IsUnknown() const { return value_ == RelocInfo::kNoPosition; }

View File

@ -3450,17 +3450,15 @@ HGraph::HGraph(CompilationInfo* info)
type_change_checksum_(0),
maximum_environment_size_(0),
no_side_effects_scope_count_(0),
disallow_adding_new_values_(false),
inlined_functions_(FLAG_hydrogen_track_positions ? 5 : 0, info->zone()),
inlining_id_to_function_id_(FLAG_hydrogen_track_positions ? 5 : 0,
info->zone()) {
disallow_adding_new_values_(false) {
if (info->IsStub()) {
CallInterfaceDescriptor descriptor =
info->code_stub()->GetCallInterfaceDescriptor();
start_environment_ = new (zone_)
HEnvironment(zone_, descriptor.GetEnvironmentParameterCount());
} else {
TraceInlinedFunction(info->shared_info(), HSourcePosition::Unknown());
info->TraceInlinedFunction(info->shared_info(),
HSourcePosition::Unknown().raw());
start_environment_ =
new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
}
@ -3488,68 +3486,14 @@ void HGraph::FinalizeUniqueness() {
}
int HGraph::TraceInlinedFunction(
Handle<SharedFunctionInfo> shared,
HSourcePosition position) {
if (!FLAG_hydrogen_track_positions) {
return 0;
}
int id = 0;
for (; id < inlined_functions_.length(); id++) {
if (inlined_functions_[id].shared().is_identical_to(shared)) {
break;
}
}
if (id == inlined_functions_.length()) {
inlined_functions_.Add(InlinedFunctionInfo(shared), zone());
if (!shared->script()->IsUndefined()) {
Handle<Script> script(Script::cast(shared->script()));
if (!script->source()->IsUndefined()) {
CodeTracer::Scope tracing_scopex(isolate()->GetCodeTracer());
OFStream os(tracing_scopex.file());
os << "--- FUNCTION SOURCE (" << shared->DebugName()->ToCString().get()
<< ") id{" << info()->optimization_id() << "," << id << "} ---\n";
{
DisallowHeapAllocation no_allocation;
int start = shared->start_position();
int len = shared->end_position() - start + 1;
String::SubStringRange source(String::cast(script->source()), start,
len);
for (const auto& c : source) {
os << AsReversiblyEscapedUC16(c);
}
}
os << "\n--- END ---\n";
}
}
}
int inline_id = inlining_id_to_function_id_.length();
inlining_id_to_function_id_.Add(id, zone());
if (inline_id != 0) {
CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
OFStream os(tracing_scope.file());
os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{"
<< info()->optimization_id() << "," << id << "} AS " << inline_id
<< " AT " << position << std::endl;
}
return inline_id;
}
int HGraph::SourcePositionToScriptPosition(HSourcePosition pos) {
if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) {
return pos.raw();
}
const int id = inlining_id_to_function_id_[pos.inlining_id()];
return inlined_functions_[id].start_position() + pos.position();
const int id = info()->inlining_id_to_function_id()->at(pos.inlining_id());
return info()->inlined_function_infos()->at(id).start_position() +
pos.position();
}
@ -7987,7 +7931,8 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
DCHECK(target_shared->has_deoptimization_support());
AstTyper::Run(&target_info);
int function_id = graph()->TraceInlinedFunction(target_shared, position);
int function_id =
top_info()->TraceInlinedFunction(target_shared, position.raw());
// 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
@ -9221,8 +9166,6 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
if (function->IsConstant() &&
HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
// Push the function under the receiver.

View File

@ -510,23 +510,6 @@ class HGraph FINAL : public ZoneObject {
int no_side_effects_scope_count_;
bool disallow_adding_new_values_;
class InlinedFunctionInfo {
public:
explicit InlinedFunctionInfo(Handle<SharedFunctionInfo> shared)
: shared_(shared), start_position_(shared->start_position()) {
}
Handle<SharedFunctionInfo> shared() const { return shared_; }
int start_position() const { return start_position_; }
private:
Handle<SharedFunctionInfo> shared_;
int start_position_;
};
ZoneList<InlinedFunctionInfo> inlined_functions_;
ZoneList<int> inlining_id_to_function_id_;
DISALLOW_COPY_AND_ASSIGN(HGraph);
};