Chromium Code Reviews

Side by Side Diff: src/profiler/sampling-heap-profiler.cc

Issue 1706343002: Unsampling for the sampling heap profiler (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Comment describing poisson unsampling Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « src/profiler/sampling-heap-profiler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/profiler/sampling-heap-profiler.h" 5 #include "src/profiler/sampling-heap-profiler.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <memory> 8 #include <memory>
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/utils/random-number-generator.h" 10 #include "src/base/utils/random-number-generator.h"
(...skipping 15 matching lines...)
26 if (FLAG_sampling_heap_profiler_suppress_randomness) { 26 if (FLAG_sampling_heap_profiler_suppress_randomness) {
27 return static_cast<intptr_t>(rate); 27 return static_cast<intptr_t>(rate);
28 } 28 }
29 double u = random_->NextDouble(); 29 double u = random_->NextDouble();
30 double next = (-std::log(u)) * rate; 30 double next = (-std::log(u)) * rate;
31 return next < kPointerSize 31 return next < kPointerSize
32 ? kPointerSize 32 ? kPointerSize
33 : (next > INT_MAX ? INT_MAX : static_cast<intptr_t>(next)); 33 : (next > INT_MAX ? INT_MAX : static_cast<intptr_t>(next));
34 } 34 }
35 35
36 // Samples were collected according to a poisson process. Since we have not
37 // recorded all allocations, we must approximate the shape of the underlying
38 // space of allocations based on the samples we have collected. Given that
39 // we sample at rate R, the probability that an allocation of size S will be
40 // sampled is 1-exp(-S/R). This function uses the above probability to
41 // approximate the true number of allocations with size *size* given that
42 // *count* samples were observed.
43 v8::AllocationProfile::Allocation SamplingHeapProfiler::Unsample(
44 size_t size, unsigned int count) {
45 double scale = 1.0 / (1.0 - std::exp(-size / rate_));
46 return {size, static_cast<unsigned int>(count * scale + 0.5)};
ofrobots 2016/02/19 04:29:29 Where did the 0.5 come from?
mattloring 2016/02/19 04:31:07 Thought it would be more accurate to round than tr
ofrobots 2016/02/19 04:46:43 Ah. This deserves a comment in the code.
mattloring 2016/02/19 04:50:41 Done.
47 }
48
36 SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names, 49 SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names,
37 uint64_t rate, int stack_depth) 50 uint64_t rate, int stack_depth)
38 : isolate_(heap->isolate()), 51 : isolate_(heap->isolate()),
39 heap_(heap), 52 heap_(heap),
40 new_space_observer_(new SamplingAllocationObserver( 53 new_space_observer_(new SamplingAllocationObserver(
41 heap_, static_cast<intptr_t>(rate), rate, this, 54 heap_, static_cast<intptr_t>(rate), rate, this,
42 heap->isolate()->random_number_generator())), 55 heap->isolate()->random_number_generator())),
43 other_spaces_observer_(new SamplingAllocationObserver( 56 other_spaces_observer_(new SamplingAllocationObserver(
44 heap_, static_cast<intptr_t>(rate), rate, this, 57 heap_, static_cast<intptr_t>(rate), rate, this,
45 heap->isolate()->random_number_generator())), 58 heap->isolate()->random_number_generator())),
46 names_(names), 59 names_(names),
47 profile_root_("(root)", v8::UnboundScript::kNoScriptId, 0), 60 profile_root_("(root)", v8::UnboundScript::kNoScriptId, 0),
48 samples_(), 61 samples_(),
49 stack_depth_(stack_depth) { 62 stack_depth_(stack_depth),
63 rate_(rate) {
50 heap->new_space()->AddAllocationObserver(new_space_observer_.get()); 64 heap->new_space()->AddAllocationObserver(new_space_observer_.get());
51 AllSpaces spaces(heap); 65 AllSpaces spaces(heap);
52 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 66 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
53 if (space != heap->new_space()) { 67 if (space != heap->new_space()) {
54 space->AddAllocationObserver(other_spaces_observer_.get()); 68 space->AddAllocationObserver(other_spaces_observer_.get());
55 } 69 }
56 } 70 }
57 } 71 }
58 72
59 73
(...skipping 129 matching lines...)
189 if (script->name()->IsName()) { 203 if (script->name()->IsName()) {
190 Name* name = Name::cast(script->name()); 204 Name* name = Name::cast(script->name());
191 script_name = ToApiHandle<v8::String>( 205 script_name = ToApiHandle<v8::String>(
192 isolate_->factory()->InternalizeUtf8String(names_->GetName(name))); 206 isolate_->factory()->InternalizeUtf8String(names_->GetName(name)));
193 } 207 }
194 Handle<Script> script_handle(script); 208 Handle<Script> script_handle(script);
195 209
196 line = 1 + Script::GetLineNumber(script_handle, node->script_position_); 210 line = 1 + Script::GetLineNumber(script_handle, node->script_position_);
197 column = 1 + Script::GetColumnNumber(script_handle, node->script_position_); 211 column = 1 + Script::GetColumnNumber(script_handle, node->script_position_);
198 for (auto alloc : node->allocations_) { 212 for (auto alloc : node->allocations_) {
199 allocations.push_back({alloc.first, alloc.second}); 213 allocations.push_back(Unsample(alloc.first, alloc.second));
200 } 214 }
201 } 215 }
202 216
203 profile->nodes().push_back(v8::AllocationProfile::Node( 217 profile->nodes().push_back(v8::AllocationProfile::Node(
204 {ToApiHandle<v8::String>( 218 {ToApiHandle<v8::String>(
205 isolate_->factory()->InternalizeUtf8String(node->name_)), 219 isolate_->factory()->InternalizeUtf8String(node->name_)),
206 script_name, node->script_id_, node->script_position_, line, column, 220 script_name, node->script_id_, node->script_position_, line, column,
207 std::vector<v8::AllocationProfile::Node*>(), allocations})); 221 std::vector<v8::AllocationProfile::Node*>(), allocations}));
208 v8::AllocationProfile::Node* current = &profile->nodes().back(); 222 v8::AllocationProfile::Node* current = &profile->nodes().back();
209 for (auto child : node->children_) { 223 for (auto child : node->children_) {
(...skipping 18 matching lines...)
228 auto profile = new v8::internal::AllocationProfile(); 242 auto profile = new v8::internal::AllocationProfile();
229 243
230 TranslateAllocationNode(profile, &profile_root_, scripts); 244 TranslateAllocationNode(profile, &profile_root_, scripts);
231 245
232 return profile; 246 return profile;
233 } 247 }
234 248
235 249
236 } // namespace internal 250 } // namespace internal
237 } // namespace v8 251 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/sampling-heap-profiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine