diff options
Diffstat (limited to 'chromium/v8/src/diagnostics/basic-block-profiler.cc')
| -rw-r--r-- | chromium/v8/src/diagnostics/basic-block-profiler.cc | 142 |
1 files changed, 98 insertions, 44 deletions
diff --git a/chromium/v8/src/diagnostics/basic-block-profiler.cc b/chromium/v8/src/diagnostics/basic-block-profiler.cc index 262a5364b5e..f61292c3cdd 100644 --- a/chromium/v8/src/diagnostics/basic-block-profiler.cc +++ b/chromium/v8/src/diagnostics/basic-block-profiler.cc @@ -9,84 +9,138 @@ #include <sstream> #include "src/base/lazy-instance.h" +#include "src/heap/heap-inl.h" +#include "torque-generated/exported-class-definitions-tq-inl.h" namespace v8 { namespace internal { DEFINE_LAZY_LEAKY_OBJECT_GETTER(BasicBlockProfiler, BasicBlockProfiler::Get) -BasicBlockProfiler::Data::Data(size_t n_blocks) - : n_blocks_(n_blocks), - block_rpo_numbers_(n_blocks_), - counts_(n_blocks_, 0) {} +BasicBlockProfilerData::BasicBlockProfilerData(size_t n_blocks) + : block_rpo_numbers_(n_blocks), counts_(n_blocks, 0) {} -static void InsertIntoString(std::ostringstream* os, std::string* string) { - string->insert(0, os->str()); +void BasicBlockProfilerData::SetCode(const std::ostringstream& os) { + code_ = os.str(); } -static void InsertIntoString(const char* data, std::string* string) { - string->insert(0, data); +void BasicBlockProfilerData::SetFunctionName(std::unique_ptr<char[]> name) { + function_name_ = name.get(); } -void BasicBlockProfiler::Data::SetCode(std::ostringstream* os) { - InsertIntoString(os, &code_); +void BasicBlockProfilerData::SetSchedule(const std::ostringstream& os) { + schedule_ = os.str(); } -void BasicBlockProfiler::Data::SetFunctionName(std::unique_ptr<char[]> name) { - InsertIntoString(name.get(), &function_name_); +void BasicBlockProfilerData::SetBlockRpoNumber(size_t offset, + int32_t block_rpo) { + DCHECK(offset < n_blocks()); + block_rpo_numbers_[offset] = block_rpo; } -void BasicBlockProfiler::Data::SetSchedule(std::ostringstream* os) { - InsertIntoString(os, &schedule_); +void BasicBlockProfilerData::ResetCounts() { + for (size_t i = 0; i < n_blocks(); ++i) { + counts_[i] = 0; + } } -void BasicBlockProfiler::Data::SetBlockRpoNumber(size_t offset, - int32_t block_rpo) { - DCHECK(offset < n_blocks_); - block_rpo_numbers_[offset] = block_rpo; +BasicBlockProfilerData* BasicBlockProfiler::NewData(size_t n_blocks) { + base::MutexGuard lock(&data_list_mutex_); + auto data = std::make_unique<BasicBlockProfilerData>(n_blocks); + BasicBlockProfilerData* data_ptr = data.get(); + data_list_.push_back(std::move(data)); + return data_ptr; } -intptr_t BasicBlockProfiler::Data::GetCounterAddress(size_t offset) { - DCHECK(offset < n_blocks_); - return reinterpret_cast<intptr_t>(&(counts_[offset])); +namespace { +Handle<String> CopyStringToJSHeap(const std::string& source, Isolate* isolate) { + return isolate->factory()->NewStringFromAsciiChecked(source.c_str(), + AllocationType::kOld); } -void BasicBlockProfiler::Data::ResetCounts() { - for (size_t i = 0; i < n_blocks_; ++i) { - counts_[i] = 0; +// Size of entries in both block_rpo_numbers and counts. +constexpr int kBasicBlockSlotSize = kInt32Size; +} // namespace + +BasicBlockProfilerData::BasicBlockProfilerData( + Handle<OnHeapBasicBlockProfilerData> js_heap_data, Isolate* isolate) { + function_name_ = js_heap_data->name().ToCString().get(); + schedule_ = js_heap_data->schedule().ToCString().get(); + code_ = js_heap_data->code().ToCString().get(); + Handle<ByteArray> counts(js_heap_data->counts(), isolate); + for (int i = 0; i < counts->length() / kBasicBlockSlotSize; ++i) { + counts_.push_back(counts->get_uint32(i)); } + Handle<ByteArray> rpo_numbers(js_heap_data->block_rpo_numbers(), isolate); + for (int i = 0; i < rpo_numbers->length() / kBasicBlockSlotSize; ++i) { + block_rpo_numbers_.push_back(rpo_numbers->get_int(i)); + } + CHECK_EQ(block_rpo_numbers_.size(), counts_.size()); } -BasicBlockProfiler::Data* BasicBlockProfiler::NewData(size_t n_blocks) { - base::MutexGuard lock(&data_list_mutex_); - Data* data = new Data(n_blocks); - data_list_.push_back(data); - return data; +Handle<OnHeapBasicBlockProfilerData> BasicBlockProfilerData::CopyToJSHeap( + Isolate* isolate) { + int array_size_in_bytes = static_cast<int>(n_blocks() * kBasicBlockSlotSize); + CHECK(array_size_in_bytes >= 0 && + static_cast<size_t>(array_size_in_bytes) / kBasicBlockSlotSize == + n_blocks()); // Overflow + Handle<ByteArray> block_rpo_numbers = isolate->factory()->NewByteArray( + array_size_in_bytes, AllocationType::kOld); + for (int i = 0; i < static_cast<int>(n_blocks()); ++i) { + block_rpo_numbers->set_int(i, block_rpo_numbers_[i]); + } + Handle<ByteArray> counts = isolate->factory()->NewByteArray( + array_size_in_bytes, AllocationType::kOld); + for (int i = 0; i < static_cast<int>(n_blocks()); ++i) { + counts->set_uint32(i, counts_[i]); + } + Handle<String> name = CopyStringToJSHeap(function_name_, isolate); + Handle<String> schedule = CopyStringToJSHeap(schedule_, isolate); + Handle<String> code = CopyStringToJSHeap(code_, isolate); + + return isolate->factory()->NewOnHeapBasicBlockProfilerData( + block_rpo_numbers, counts, name, schedule, code, AllocationType::kOld); } -BasicBlockProfiler::~BasicBlockProfiler() { - for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) { - delete (*i); +void BasicBlockProfiler::ResetCounts(Isolate* isolate) { + for (const auto& data : data_list_) { + data->ResetCounts(); + } + HandleScope scope(isolate); + Handle<ArrayList> list(isolate->heap()->basic_block_profiling_data(), + isolate); + for (int i = 0; i < list->Length(); ++i) { + Handle<ByteArray> counts( + OnHeapBasicBlockProfilerData::cast(list->Get(i)).counts(), isolate); + for (int j = 0; j < counts->length() / kBasicBlockSlotSize; ++j) { + counts->set_uint32(j, 0); + } } } -void BasicBlockProfiler::ResetCounts() { - for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) { - (*i)->ResetCounts(); - } +bool BasicBlockProfiler::HasData(Isolate* isolate) { + return data_list_.size() > 0 || + isolate->heap()->basic_block_profiling_data().Length() > 0; } -std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler& p) { +void BasicBlockProfiler::Print(std::ostream& os, Isolate* isolate) { os << "---- Start Profiling Data ----" << std::endl; - using iterator = BasicBlockProfiler::DataList::const_iterator; - for (iterator i = p.data_list_.begin(); i != p.data_list_.end(); ++i) { - os << **i; + for (const auto& data : data_list_) { + os << *data; + } + HandleScope scope(isolate); + Handle<ArrayList> list(isolate->heap()->basic_block_profiling_data(), + isolate); + for (int i = 0; i < list->Length(); ++i) { + BasicBlockProfilerData data( + handle(OnHeapBasicBlockProfilerData::cast(list->Get(i)), isolate), + isolate); + os << data; } os << "---- End Profiling Data ----" << std::endl; - return os; } -std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler::Data& d) { +std::ostream& operator<<(std::ostream& os, const BasicBlockProfilerData& d) { int block_count_sum = std::accumulate(d.counts_.begin(), d.counts_.end(), 0); if (block_count_sum == 0) return os; const char* name = "unknown function"; @@ -100,8 +154,8 @@ std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler::Data& d) { } os << "block counts for " << name << ":" << std::endl; std::vector<std::pair<int32_t, uint32_t>> pairs; - pairs.reserve(d.n_blocks_); - for (size_t i = 0; i < d.n_blocks_; ++i) { + pairs.reserve(d.n_blocks()); + for (size_t i = 0; i < d.n_blocks(); ++i) { pairs.push_back(std::make_pair(d.block_rpo_numbers_[i], d.counts_[i])); } std::sort(pairs.begin(), pairs.end(), |
