v8/src/compiler/pipeline-statistics.cc
Jakob Kummerow 6e887c9396 Use a std::shared_ptr for CompilationStats
This fixes a flaky crash when running with --turbo-stats or
--turbo-stats-wasm.
With dynamic tiering, it can happen that a compilation job is started
shortly before the program/test/benchmark terminates and the main thread
goes through its teardown sequence. When such a late job finishes, it
still wants to report its statistics, which currently crashes due to
UAF if the CompilationStats object, which is owned by the main thread,
has already been deleted.

Change-Id: Ie25a97299fdf40ece8f286487063feadcfa2eea9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3645410
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80560}
2022-05-16 15:24:26 +00:00

114 lines
3.7 KiB
C++

// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/pipeline-statistics.h"
#include <memory>
#include "src/codegen/optimized-compilation-info.h"
#include "src/compiler/zone-stats.h"
#include "src/objects/shared-function-info.h"
#include "src/objects/string.h"
namespace v8 {
namespace internal {
namespace compiler {
constexpr char PipelineStatistics::kTraceCategory[];
void PipelineStatistics::CommonStats::Begin(
PipelineStatistics* pipeline_stats) {
DCHECK(!scope_);
scope_.reset(new ZoneStats::StatsScope(pipeline_stats->zone_stats_));
timer_.Start();
outer_zone_initial_size_ = pipeline_stats->OuterZoneSize();
allocated_bytes_at_start_ =
outer_zone_initial_size_ -
pipeline_stats->total_stats_.outer_zone_initial_size_ +
pipeline_stats->zone_stats_->GetCurrentAllocatedBytes();
}
void PipelineStatistics::CommonStats::End(
PipelineStatistics* pipeline_stats,
CompilationStatistics::BasicStats* diff) {
DCHECK(scope_);
diff->function_name_ = pipeline_stats->function_name_;
diff->delta_ = timer_.Elapsed();
size_t outer_zone_diff =
pipeline_stats->OuterZoneSize() - outer_zone_initial_size_;
diff->max_allocated_bytes_ = outer_zone_diff + scope_->GetMaxAllocatedBytes();
diff->absolute_max_allocated_bytes_ =
diff->max_allocated_bytes_ + allocated_bytes_at_start_;
diff->total_allocated_bytes_ =
outer_zone_diff + scope_->GetTotalAllocatedBytes();
scope_.reset();
timer_.Stop();
}
PipelineStatistics::PipelineStatistics(
OptimizedCompilationInfo* info,
std::shared_ptr<CompilationStatistics> compilation_stats,
ZoneStats* zone_stats)
: outer_zone_(info->zone()),
zone_stats_(zone_stats),
compilation_stats_(compilation_stats),
code_kind_(info->code_kind()),
phase_kind_name_(nullptr),
phase_name_(nullptr) {
if (info->has_shared_info()) {
function_name_.assign(info->shared_info()->DebugNameCStr().get());
}
total_stats_.Begin(this);
}
PipelineStatistics::~PipelineStatistics() {
if (InPhaseKind()) EndPhaseKind();
CompilationStatistics::BasicStats diff;
total_stats_.End(this, &diff);
compilation_stats_->RecordTotalStats(diff);
}
void PipelineStatistics::BeginPhaseKind(const char* phase_kind_name) {
DCHECK(!InPhase());
if (InPhaseKind()) EndPhaseKind();
TRACE_EVENT_BEGIN1(kTraceCategory, phase_kind_name, "kind",
CodeKindToString(code_kind_));
phase_kind_name_ = phase_kind_name;
phase_kind_stats_.Begin(this);
}
void PipelineStatistics::EndPhaseKind() {
DCHECK(!InPhase());
CompilationStatistics::BasicStats diff;
phase_kind_stats_.End(this, &diff);
compilation_stats_->RecordPhaseKindStats(phase_kind_name_, diff);
TRACE_EVENT_END2(kTraceCategory, phase_kind_name_, "kind",
CodeKindToString(code_kind_), "stats",
TRACE_STR_COPY(diff.AsJSON().c_str()));
}
void PipelineStatistics::BeginPhase(const char* phase_name) {
TRACE_EVENT_BEGIN1(kTraceCategory, phase_name, "kind",
CodeKindToString(code_kind_));
DCHECK(InPhaseKind());
phase_name_ = phase_name;
phase_stats_.Begin(this);
}
void PipelineStatistics::EndPhase() {
DCHECK(InPhaseKind());
CompilationStatistics::BasicStats diff;
phase_stats_.End(this, &diff);
compilation_stats_->RecordPhaseStats(phase_kind_name_, phase_name_, diff);
TRACE_EVENT_END2(kTraceCategory, phase_name_, "kind",
CodeKindToString(code_kind_), "stats",
TRACE_STR_COPY(diff.AsJSON().c_str()));
}
} // namespace compiler
} // namespace internal
} // namespace v8