| Index: src/profiler/sampling-heap-profiler.cc
|
| diff --git a/src/profiler/sampling-heap-profiler.cc b/src/profiler/sampling-heap-profiler.cc
|
| index 0e68338230fd311a0719d4d0a18278950a75173b..e65279ab8f9c1b2d85cbd5c633a4f0574038b21c 100644
|
| --- a/src/profiler/sampling-heap-profiler.cc
|
| +++ b/src/profiler/sampling-heap-profiler.cc
|
| @@ -16,23 +16,52 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| +// 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 SamplingAllocationObserver::GetNextSampleInterval(uint64_t rate) {
|
| + if (FLAG_sampling_heap_profiler_suppress_randomness) {
|
| + return 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));
|
| +}
|
| +
|
| SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names,
|
| uint64_t rate, int stack_depth)
|
| - : InlineAllocationObserver(GetNextSampleInterval(
|
| - heap->isolate()->random_number_generator(), rate)),
|
| - isolate_(heap->isolate()),
|
| + : isolate_(heap->isolate()),
|
| heap_(heap),
|
| - random_(isolate_->random_number_generator()),
|
| + new_space_observer_(new SamplingAllocationObserver(
|
| + heap_, rate, rate, this, heap->isolate()->random_number_generator())),
|
| + other_spaces_observer_(new SamplingAllocationObserver(
|
| + heap_, rate, rate, this, heap->isolate()->random_number_generator())),
|
| names_(names),
|
| samples_(),
|
| - rate_(rate),
|
| stack_depth_(stack_depth) {
|
| - heap->new_space()->AddInlineAllocationObserver(this);
|
| + heap->new_space()->AddAllocationObserver(new_space_observer_.get());
|
| + AllSpaces spaces(heap);
|
| + for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
|
| + if (space != heap->new_space()) {
|
| + space->AddAllocationObserver(other_spaces_observer_.get());
|
| + }
|
| + }
|
| }
|
|
|
|
|
| SamplingHeapProfiler::~SamplingHeapProfiler() {
|
| - heap_->new_space()->RemoveInlineAllocationObserver(this);
|
| + heap_->new_space()->RemoveAllocationObserver(new_space_observer_.get());
|
| + AllSpaces spaces(heap_);
|
| + for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
|
| + if (space != heap_->new_space()) {
|
| + space->RemoveAllocationObserver(other_spaces_observer_.get());
|
| + }
|
| + }
|
|
|
| // Clear samples and drop all the weak references we are keeping.
|
| std::set<SampledAllocation*>::iterator it;
|
| @@ -43,13 +72,6 @@ SamplingHeapProfiler::~SamplingHeapProfiler() {
|
| 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;
|
| @@ -70,25 +92,6 @@ void SamplingHeapProfiler::SampleObject(Address soon_object, size_t size) {
|
| }
|
|
|
|
|
| -// 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) {
|
| - if (FLAG_sampling_heap_profiler_suppress_randomness) {
|
| - return 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();
|
| @@ -159,8 +162,7 @@ SamplingHeapProfiler::SampledAllocation::SampledAllocation(
|
| }
|
| }
|
|
|
| -
|
| -SamplingHeapProfiler::Node* SamplingHeapProfiler::AllocateNode(
|
| +v8::AllocationProfile::Node* SamplingHeapProfiler::AllocateNode(
|
| AllocationProfile* profile, const std::map<int, Script*>& scripts,
|
| FunctionInfo* function_info) {
|
| DCHECK(function_info->get_name());
|
| @@ -180,37 +182,36 @@ SamplingHeapProfiler::Node* SamplingHeapProfiler::AllocateNode(
|
| 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>()}));
|
| + profile->nodes().push_back(v8::AllocationProfile::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<v8::AllocationProfile::Node*>(),
|
| + std::vector<v8::AllocationProfile::Allocation>()}));
|
|
|
| return &profile->nodes().back();
|
| }
|
|
|
| -
|
| -SamplingHeapProfiler::Node* SamplingHeapProfiler::FindOrAddChildNode(
|
| +v8::AllocationProfile::Node* SamplingHeapProfiler::FindOrAddChildNode(
|
| AllocationProfile* profile, const std::map<int, Script*>& scripts,
|
| - Node* parent, FunctionInfo* function_info) {
|
| - for (Node* child : parent->children) {
|
| + v8::AllocationProfile::Node* parent, FunctionInfo* function_info) {
|
| + for (v8::AllocationProfile::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);
|
| + v8::AllocationProfile::Node* child =
|
| + AllocateNode(profile, scripts, function_info);
|
| parent->children.push_back(child);
|
| return child;
|
| }
|
|
|
| -
|
| -SamplingHeapProfiler::Node* SamplingHeapProfiler::AddStack(
|
| +v8::AllocationProfile::Node* SamplingHeapProfiler::AddStack(
|
| AllocationProfile* profile, const std::map<int, Script*>& scripts,
|
| const std::vector<FunctionInfo*>& stack) {
|
| - Node* node = profile->GetRootNode();
|
| + v8::AllocationProfile::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.
|
| @@ -241,7 +242,8 @@ v8::AllocationProfile* SamplingHeapProfiler::GetAllocationProfile() {
|
| AllocateNode(profile, scripts, &function_info);
|
|
|
| for (SampledAllocation* allocation : samples_) {
|
| - Node* node = AddStack(profile, scripts, allocation->get_stack());
|
| + v8::AllocationProfile::Node* node =
|
| + AddStack(profile, scripts, allocation->get_stack());
|
| node->allocations.push_back({allocation->get_size(), 1});
|
| }
|
|
|
|
|