Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(932)

Unified Diff: src/profiler/sampling-heap-profiler.cc

Issue 1615173002: Revert of [profiler] Implement POC Sampling Heap Profiler (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/profiler/sampling-heap-profiler.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/profiler/sampling-heap-profiler.cc
diff --git a/src/profiler/sampling-heap-profiler.cc b/src/profiler/sampling-heap-profiler.cc
deleted file mode 100644
index c26b70357eeac06f8aa8066c9ca856ad71539229..0000000000000000000000000000000000000000
--- a/src/profiler/sampling-heap-profiler.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2015 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/profiler/sampling-heap-profiler.h"
-
-#include <stdint.h>
-#include <memory>
-#include "src/api.h"
-#include "src/base/utils/random-number-generator.h"
-#include "src/frames-inl.h"
-#include "src/heap/heap.h"
-#include "src/isolate.h"
-#include "src/profiler/strings-storage.h"
-
-namespace v8 {
-namespace internal {
-
-SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names,
- uint64_t rate, int stack_depth)
- : InlineAllocationObserver(GetNextSampleInterval(
- heap->isolate()->random_number_generator(), rate)),
- isolate_(heap->isolate()),
- heap_(heap),
- random_(isolate_->random_number_generator()),
- names_(names),
- samples_(),
- rate_(rate),
- stack_depth_(stack_depth) {
- heap->new_space()->AddInlineAllocationObserver(this);
-}
-
-
-SamplingHeapProfiler::~SamplingHeapProfiler() {
- heap_->new_space()->RemoveInlineAllocationObserver(this);
-
- // Clear samples and drop all the weak references we are keeping.
- std::set<SampledAllocation*>::iterator it;
- for (it = samples_.begin(); it != samples_.end(); ++it) {
- delete *it;
- }
- std::set<SampledAllocation*> empty;
- samples_.swap(empty);
-}
-
-void SamplingHeapProfiler::Step(int bytes_allocated, Address soon_object,
- size_t size) {
- DCHECK(heap_->gc_state() == Heap::NOT_IN_GC);
- DCHECK(soon_object);
- SampleObject(soon_object, size);
-}
-
-
-void SamplingHeapProfiler::SampleObject(Address soon_object, size_t size) {
- DisallowHeapAllocation no_allocation;
-
- HandleScope scope(isolate_);
- HeapObject* heap_object = HeapObject::FromAddress(soon_object);
- Handle<Object> obj(heap_object, isolate_);
-
- // Mark the new block as FreeSpace to make sure the heap is iterable while we
- // are taking the sample.
- heap()->CreateFillerObjectAt(soon_object, static_cast<int>(size));
-
- Local<v8::Value> loc = v8::Utils::ToLocal(obj);
-
- SampledAllocation* sample =
- new SampledAllocation(this, isolate_, loc, size, stack_depth_);
- samples_.insert(sample);
-}
-
-
-// We sample with a Poisson process, with constant average sampling interval.
-// This follows the exponential probability distribution with parameter
-// λ = 1/rate where rate is the average number of bytes between samples.
-//
-// Let u be a uniformly distributed random number between 0 and 1, then
-// next_sample = (- ln u) / λ
-intptr_t SamplingHeapProfiler::GetNextSampleInterval(
- base::RandomNumberGenerator* random, uint64_t rate) {
- double u = random->NextDouble();
- double next = (-std::log(u)) * rate;
- return next < kPointerSize
- ? kPointerSize
- : (next > INT_MAX ? INT_MAX : static_cast<intptr_t>(next));
-}
-
-
-void SamplingHeapProfiler::SampledAllocation::OnWeakCallback(
- const WeakCallbackInfo<SampledAllocation>& data) {
- SampledAllocation* sample = data.GetParameter();
- sample->sampling_heap_profiler_->samples_.erase(sample);
- delete sample;
-}
-
-
-SamplingHeapProfiler::FunctionInfo::FunctionInfo(SharedFunctionInfo* shared,
- StringsStorage* names)
- : name_(names->GetFunctionName(shared->DebugName())),
- script_name_(""),
- script_id_(v8::UnboundScript::kNoScriptId),
- start_position_(shared->start_position()) {
- if (shared->script()->IsScript()) {
- Script* script = Script::cast(shared->script());
- script_id_ = script->id();
- if (script->name()->IsName()) {
- Name* name = Name::cast(script->name());
- script_name_ = names->GetName(name);
- }
- }
-}
-
-
-SamplingHeapProfiler::SampledAllocation::SampledAllocation(
- SamplingHeapProfiler* sampling_heap_profiler, Isolate* isolate,
- Local<Value> local, size_t size, int max_frames)
- : sampling_heap_profiler_(sampling_heap_profiler),
- global_(reinterpret_cast<v8::Isolate*>(isolate), local),
- size_(size) {
- global_.SetWeak(this, OnWeakCallback, WeakCallbackType::kParameter);
-
- StackTraceFrameIterator it(isolate);
- int frames_captured = 0;
- while (!it.done() && frames_captured < max_frames) {
- JavaScriptFrame* frame = it.frame();
- SharedFunctionInfo* shared = frame->function()->shared();
- stack_.push_back(new FunctionInfo(shared, sampling_heap_profiler->names()));
-
- frames_captured++;
- it.Advance();
- }
-
- if (frames_captured == 0) {
- const char* name = nullptr;
- switch (isolate->current_vm_state()) {
- case GC:
- name = "(GC)";
- break;
- case COMPILER:
- name = "(COMPILER)";
- break;
- case OTHER:
- name = "(V8 API)";
- break;
- case EXTERNAL:
- name = "(EXTERNAL)";
- break;
- case IDLE:
- name = "(IDLE)";
- break;
- case JS:
- name = "(JS)";
- break;
- }
- stack_.push_back(new FunctionInfo(name));
- }
-}
-
-
-SamplingHeapProfiler::Node* SamplingHeapProfiler::AllocateNode(
- AllocationProfile* profile, const std::map<int, Script*>& scripts,
- FunctionInfo* function_info) {
- DCHECK(function_info->get_name());
- DCHECK(function_info->get_script_name());
-
- int line = v8::AllocationProfile::kNoLineNumberInfo;
- int column = v8::AllocationProfile::kNoColumnNumberInfo;
-
- if (function_info->get_script_id() != v8::UnboundScript::kNoScriptId) {
- // Cannot use std::map<T>::at because it is not available on android.
- auto non_const_scripts = const_cast<std::map<int, Script*>&>(scripts);
- Handle<Script> script(non_const_scripts[function_info->get_script_id()]);
-
- line =
- 1 + Script::GetLineNumber(script, function_info->get_start_position());
- column = 1 + Script::GetColumnNumber(script,
- function_info->get_start_position());
- }
-
- profile->nodes().push_back(
- Node({ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String(
- function_info->get_name())),
- ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String(
- function_info->get_script_name())),
- function_info->get_script_id(), function_info->get_start_position(),
- line, column, std::vector<Node*>(),
- std::vector<v8::AllocationProfile::Allocation>()}));
-
- return &profile->nodes().back();
-}
-
-
-SamplingHeapProfiler::Node* SamplingHeapProfiler::FindOrAddChildNode(
- AllocationProfile* profile, const std::map<int, Script*>& scripts,
- Node* parent, FunctionInfo* function_info) {
- for (Node* child : parent->children) {
- if (child->script_id == function_info->get_script_id() &&
- child->start_position == function_info->get_start_position())
- return child;
- }
- Node* child = AllocateNode(profile, scripts, function_info);
- parent->children.push_back(child);
- return child;
-}
-
-
-SamplingHeapProfiler::Node* SamplingHeapProfiler::AddStack(
- AllocationProfile* profile, const std::map<int, Script*>& scripts,
- const std::vector<FunctionInfo*>& stack) {
- Node* node = profile->GetRootNode();
-
- // We need to process the stack in reverse order as the top of the stack is
- // the first element in the list.
- for (auto it = stack.rbegin(); it != stack.rend(); ++it) {
- FunctionInfo* function_info = *it;
- node = FindOrAddChildNode(profile, scripts, node, function_info);
- }
- return node;
-}
-
-
-v8::AllocationProfile* SamplingHeapProfiler::GetAllocationProfile() {
- // To resolve positions to line/column numbers, we will need to look up
- // scripts. Build a map to allow fast mapping from script id to script.
- std::map<int, Script*> scripts;
- {
- Script::Iterator iterator(isolate_);
- Script* script;
- while ((script = iterator.Next())) {
- scripts[script->id()] = script;
- }
- }
-
- auto profile = new v8::internal::AllocationProfile();
-
- // Create the root node.
- FunctionInfo function_info("(root)");
- AllocateNode(profile, scripts, &function_info);
-
- for (SampledAllocation* allocation : samples_) {
- Node* node = AddStack(profile, scripts, allocation->get_stack());
- node->allocations.push_back({allocation->get_size(), 1});
- }
-
- return profile;
-}
-
-
-} // namespace internal
-} // namespace v8
« no previous file with comments | « src/profiler/sampling-heap-profiler.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698