| Index: src/profiler/heap-profiler.h
|
| diff --git a/src/profiler/heap-profiler.h b/src/profiler/heap-profiler.h
|
| index 9a04e83af4b0ca2f3725f8a10fcdabd322ba41b7..f43832c68cb05704744cfdc43810c50de9533f6e 100644
|
| --- a/src/profiler/heap-profiler.h
|
| +++ b/src/profiler/heap-profiler.h
|
| @@ -5,6 +5,7 @@
|
| #ifndef V8_PROFILER_HEAP_PROFILER_H_
|
| #define V8_PROFILER_HEAP_PROFILER_H_
|
|
|
| +#include "include/v8-util.h"
|
| #include "src/base/smart-pointers.h"
|
| #include "src/isolate.h"
|
| #include "src/list.h"
|
| @@ -16,6 +17,7 @@ namespace internal {
|
| class AllocationTracker;
|
| class HeapObjectsMap;
|
| class HeapSnapshot;
|
| +class SamplingHeapProfiler;
|
| class StringsStorage;
|
|
|
| class HeapProfiler {
|
| @@ -29,6 +31,10 @@ class HeapProfiler {
|
| v8::ActivityControl* control,
|
| v8::HeapProfiler::ObjectNameResolver* resolver);
|
|
|
| + bool StartSamplingHeapProfiler(uint64_t sample_interval, int stack_depth);
|
| + void StopSamplingHeapProfiler();
|
| + void GetHeapSample(OutputStream* stream);
|
| +
|
| void StartHeapObjectsTracking(bool track_allocations);
|
| void StopHeapObjectsTracking();
|
| AllocationTracker* allocation_tracker() const {
|
| @@ -79,6 +85,103 @@ class HeapProfiler {
|
| base::SmartPointer<AllocationTracker> allocation_tracker_;
|
| bool is_tracking_object_moves_;
|
| base::Mutex profiler_mutex_;
|
| + base::SmartPointer<SamplingHeapProfiler> sampling_heap_profiler_;
|
| +};
|
| +
|
| +template <int bytes>
|
| +struct MaxDecimalDigitsIn;
|
| +template <>
|
| +struct MaxDecimalDigitsIn<4> {
|
| + static const int kSigned = 11;
|
| + static const int kUnsigned = 10;
|
| +};
|
| +template <>
|
| +struct MaxDecimalDigitsIn<8> {
|
| + static const int kSigned = 20;
|
| + static const int kUnsigned = 20;
|
| +};
|
| +
|
| +class OutputStreamWriter {
|
| + public:
|
| + explicit OutputStreamWriter(v8::OutputStream* stream)
|
| + : stream_(stream),
|
| + chunk_size_(stream->GetChunkSize()),
|
| + chunk_(chunk_size_),
|
| + chunk_pos_(0),
|
| + aborted_(false) {
|
| + DCHECK(chunk_size_ > 0);
|
| + }
|
| + bool aborted() { return aborted_; }
|
| + void AddCharacter(char c) {
|
| + DCHECK(c != '\0');
|
| + DCHECK(chunk_pos_ < chunk_size_);
|
| + chunk_[chunk_pos_++] = c;
|
| + MaybeWriteChunk();
|
| + }
|
| + void AddString(const char* s) { AddSubstring(s, StrLength(s)); }
|
| + void AddSubstring(const char* s, int n) {
|
| + if (n <= 0) return;
|
| + DCHECK(static_cast<size_t>(n) <= strlen(s));
|
| + const char* s_end = s + n;
|
| + while (s < s_end) {
|
| + int s_chunk_size =
|
| + Min(chunk_size_ - chunk_pos_, static_cast<int>(s_end - s));
|
| + DCHECK(s_chunk_size > 0);
|
| + MemCopy(chunk_.start() + chunk_pos_, s, s_chunk_size);
|
| + s += s_chunk_size;
|
| + chunk_pos_ += s_chunk_size;
|
| + MaybeWriteChunk();
|
| + }
|
| + }
|
| + void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); }
|
| + void Finalize() {
|
| + if (aborted_) return;
|
| + DCHECK(chunk_pos_ < chunk_size_);
|
| + if (chunk_pos_ != 0) {
|
| + WriteChunk();
|
| + }
|
| + stream_->EndOfStream();
|
| + }
|
| +
|
| + private:
|
| + template <typename T>
|
| + void AddNumberImpl(T n, const char* format) {
|
| + // Buffer for the longest value plus trailing \0
|
| + static const int kMaxNumberSize =
|
| + MaxDecimalDigitsIn<sizeof(T)>::kUnsigned + 1;
|
| + if (chunk_size_ - chunk_pos_ >= kMaxNumberSize) {
|
| + int result =
|
| + SNPrintF(chunk_.SubVector(chunk_pos_, chunk_size_), format, n);
|
| + DCHECK(result != -1);
|
| + chunk_pos_ += result;
|
| + MaybeWriteChunk();
|
| + } else {
|
| + EmbeddedVector<char, kMaxNumberSize> buffer;
|
| + int result = SNPrintF(buffer, format, n);
|
| + USE(result);
|
| + DCHECK(result != -1);
|
| + AddString(buffer.start());
|
| + }
|
| + }
|
| + void MaybeWriteChunk() {
|
| + DCHECK(chunk_pos_ <= chunk_size_);
|
| + if (chunk_pos_ == chunk_size_) {
|
| + WriteChunk();
|
| + }
|
| + }
|
| + void WriteChunk() {
|
| + if (aborted_) return;
|
| + if (stream_->WriteAsciiChunk(chunk_.start(), chunk_pos_) ==
|
| + v8::OutputStream::kAbort)
|
| + aborted_ = true;
|
| + chunk_pos_ = 0;
|
| + }
|
| +
|
| + v8::OutputStream* stream_;
|
| + int chunk_size_;
|
| + ScopedVector<char> chunk_;
|
| + int chunk_pos_;
|
| + bool aborted_;
|
| };
|
|
|
| } // namespace internal
|
|
|