Commit b2024c53 authored by loislo@chromium.org's avatar loislo@chromium.org

Push heap stats as HeapStatsUpdate struct instead of raw array of uint32_t values.

We are pushing stats data as a raw array of uint32_t values at the moment.
It makes tricky the process of updating the API between v8 and WebKit.

BUG=none
TEST=HeapSnapshotObjectsStats

Review URL: https://chromiumcodereview.appspot.com/10110001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11355 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 78e4e76c
......@@ -446,9 +446,8 @@ class V8EXPORT HeapProfiler {
* time interval entry contains information on the current heap objects
* population size. The method also updates aggregated statistics and
* reports updates for all previous time intervals via the OutputStream
* object. Updates on each time interval are provided as a triplet. It has
* time interval index, updated heap objects count and updated heap objects
* size.
* object. Updates on each time interval are provided as a stream of the
* HeapStatsUpdate structure instances.
*
* StartHeapObjectsTracking must be called before the first call to this
* method.
......@@ -559,6 +558,19 @@ class V8EXPORT RetainedObjectInfo { // NOLINT
};
/**
* A struct for exporting HeapStats data from V8, using "push" model.
* See HeapProfiler::PushHeapObjectsStats.
*/
struct HeapStatsUpdate {
HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
: index(index), count(count), size(size) { }
uint32_t index; // Index of the time interval that was changed.
uint32_t count; // New value of count field for the interval with this index.
uint32_t size; // New value of size field for the interval with this index.
};
} // namespace v8
......
......@@ -3741,14 +3741,19 @@ class V8EXPORT Locker {
};
/**
* A struct for exporting HeapStats data from V8, using "push" model.
*/
struct HeapStatsUpdate;
/**
* An interface for exporting data from V8, using "push" model.
*/
class V8EXPORT OutputStream { // NOLINT
public:
enum OutputEncoding {
kAscii = 0, // 7-bit ASCII.
kUint32 = 1
kAscii = 0 // 7-bit ASCII.
};
enum WriteResult {
kContinue = 0,
......@@ -3772,9 +3777,7 @@ class V8EXPORT OutputStream { // NOLINT
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
// TODO(loislo): Make this pure virtual when WebKit's V8 bindings
// have been updated.
virtual WriteResult WriteUint32Chunk(uint32_t* data, int count) {
virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) {
return kAbort;
};
};
......
......@@ -1403,7 +1403,7 @@ void HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) {
UpdateHeapObjectsMap();
time_intervals_.Add(TimeInterval(next_id_));
int prefered_chunk_size = stream->GetChunkSize();
List<uint32_t> stats_buffer;
List<v8::HeapStatsUpdate> stats_buffer;
ASSERT(!entries_.is_empty());
EntryInfo* entry_info = &entries_.first();
EntryInfo* end_entry_info = &entries_.last() + 1;
......@@ -1422,11 +1422,12 @@ void HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) {
static_cast<uint32_t>(entry_info - start_entry_info);
if (time_interval.count != entries_count ||
time_interval.size != entries_size) {
stats_buffer.Add(time_interval_index);
stats_buffer.Add(time_interval.count = entries_count);
stats_buffer.Add(time_interval.size = entries_size);
stats_buffer.Add(v8::HeapStatsUpdate(
time_interval_index,
time_interval.count = entries_count,
time_interval.size = entries_size));
if (stats_buffer.length() >= prefered_chunk_size) {
OutputStream::WriteResult result = stream->WriteUint32Chunk(
OutputStream::WriteResult result = stream->WriteHeapStatsChunk(
&stats_buffer.first(), stats_buffer.length());
if (result == OutputStream::kAbort) return;
stats_buffer.Clear();
......@@ -1435,8 +1436,8 @@ void HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) {
}
ASSERT(entry_info == end_entry_info);
if (!stats_buffer.is_empty()) {
OutputStream::WriteResult result =
stream->WriteUint32Chunk(&stats_buffer.first(), stats_buffer.length());
OutputStream::WriteResult result = stream->WriteHeapStatsChunk(
&stats_buffer.first(), stats_buffer.length());
if (result == OutputStream::kAbort) return;
}
stream->EndOfStream();
......
......@@ -741,7 +741,7 @@ class HeapObjectsMap {
struct TimeInterval {
explicit TimeInterval(SnapshotObjectId id) : id(id), size(0), count(0) { }
SnapshotObjectId id;
unsigned int size;
uint32_t size;
uint32_t count;
};
......
......@@ -692,7 +692,7 @@ class TestStatsStream : public v8::OutputStream {
public:
TestStatsStream()
: eos_signaled_(0),
numbers_written_(0),
updates_written_(0),
entries_count_(0),
entries_size_(0),
intervals_count_(0),
......@@ -700,7 +700,7 @@ class TestStatsStream : public v8::OutputStream {
TestStatsStream(const TestStatsStream& stream)
: v8::OutputStream(stream),
eos_signaled_(stream.eos_signaled_),
numbers_written_(stream.numbers_written_),
updates_written_(stream.updates_written_),
entries_count_(stream.entries_count_),
entries_size_(stream.entries_size_),
intervals_count_(stream.intervals_count_),
......@@ -711,22 +711,23 @@ class TestStatsStream : public v8::OutputStream {
ASSERT(false);
return kAbort;
}
virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int numbers_written) {
virtual WriteResult WriteHeapStatsChunk(v8::HeapStatsUpdate* buffer,
int updates_written) {
++intervals_count_;
ASSERT(numbers_written);
numbers_written_ += numbers_written;
ASSERT(updates_written);
updates_written_ += updates_written;
entries_count_ = 0;
if (first_interval_index_ == -1 && numbers_written != 0)
first_interval_index_ = buffer[0];
for (int i = 0; i < numbers_written; i += 3) {
entries_count_ += buffer[i+1];
entries_size_ += buffer[i+2];
if (first_interval_index_ == -1 && updates_written != 0)
first_interval_index_ = buffer[0].index;
for (int i = 0; i < updates_written; ++i) {
entries_count_ += buffer[i].count;
entries_size_ += buffer[i].size;
}
return kContinue;
}
int eos_signaled() { return eos_signaled_; }
int numbers_written() { return numbers_written_; }
int updates_written() { return updates_written_; }
uint32_t entries_count() const { return entries_count_; }
uint32_t entries_size() const { return entries_size_; }
int intervals_count() const { return intervals_count_; }
......@@ -734,7 +735,7 @@ class TestStatsStream : public v8::OutputStream {
private:
int eos_signaled_;
int numbers_written_;
int updates_written_;
uint32_t entries_count_;
uint32_t entries_size_;
int intervals_count_;
......@@ -766,13 +767,13 @@ TEST(HeapSnapshotObjectsStats) {
// Single chunk of data expected in update. Initial data.
TestStatsStream stats_update = GetHeapStatsUpdate();
CHECK_EQ(1, stats_update.intervals_count());
CHECK_EQ(3, stats_update.numbers_written());
CHECK_EQ(1, stats_update.updates_written());
CHECK_LT(0, stats_update.entries_size());
CHECK_EQ(0, stats_update.first_interval_index());
}
// No data expected in update because nothing has happened.
CHECK_EQ(0, GetHeapStatsUpdate().numbers_written());
CHECK_EQ(0, GetHeapStatsUpdate().updates_written());
{
v8::HandleScope inner_scope_1;
v8_str("string1");
......@@ -780,14 +781,14 @@ TEST(HeapSnapshotObjectsStats) {
// Single chunk of data with one new entry expected in update.
TestStatsStream stats_update = GetHeapStatsUpdate();
CHECK_EQ(1, stats_update.intervals_count());
CHECK_EQ(3, stats_update.numbers_written());
CHECK_EQ(1, stats_update.updates_written());
CHECK_LT(0, stats_update.entries_size());
CHECK_EQ(1, stats_update.entries_count());
CHECK_EQ(2, stats_update.first_interval_index());
}
// No data expected in update because nothing happened.
CHECK_EQ(0, GetHeapStatsUpdate().numbers_written());
CHECK_EQ(0, GetHeapStatsUpdate().updates_written());
{
v8::HandleScope inner_scope_2;
......@@ -803,7 +804,7 @@ TEST(HeapSnapshotObjectsStats) {
// Single chunk of data with three new entries expected in update.
TestStatsStream stats_update = GetHeapStatsUpdate();
CHECK_EQ(1, stats_update.intervals_count());
CHECK_EQ(3, stats_update.numbers_written());
CHECK_EQ(1, stats_update.updates_written());
CHECK_LT(0, entries_size = stats_update.entries_size());
CHECK_EQ(3, stats_update.entries_count());
CHECK_EQ(4, stats_update.first_interval_index());
......@@ -814,7 +815,7 @@ TEST(HeapSnapshotObjectsStats) {
// Single chunk of data with two left entries expected in update.
TestStatsStream stats_update = GetHeapStatsUpdate();
CHECK_EQ(1, stats_update.intervals_count());
CHECK_EQ(3, stats_update.numbers_written());
CHECK_EQ(1, stats_update.updates_written());
CHECK_GT(entries_size, stats_update.entries_size());
CHECK_EQ(1, stats_update.entries_count());
// Two strings from forth interval were released.
......@@ -826,7 +827,7 @@ TEST(HeapSnapshotObjectsStats) {
// Single chunk of data with 0 left entries expected in update.
TestStatsStream stats_update = GetHeapStatsUpdate();
CHECK_EQ(1, stats_update.intervals_count());
CHECK_EQ(3, stats_update.numbers_written());
CHECK_EQ(1, stats_update.updates_written());
CHECK_EQ(0, stats_update.entries_size());
CHECK_EQ(0, stats_update.entries_count());
// The last string from forth interval was released.
......@@ -837,7 +838,7 @@ TEST(HeapSnapshotObjectsStats) {
// Single chunk of data with 0 left entries expected in update.
TestStatsStream stats_update = GetHeapStatsUpdate();
CHECK_EQ(1, stats_update.intervals_count());
CHECK_EQ(3, stats_update.numbers_written());
CHECK_EQ(1, stats_update.updates_written());
CHECK_EQ(0, stats_update.entries_size());
CHECK_EQ(0, stats_update.entries_count());
// The only string from the second interval was released.
......@@ -854,7 +855,7 @@ TEST(HeapSnapshotObjectsStats) {
// Single chunk of data with 2 entries expected in update.
TestStatsStream stats_update = GetHeapStatsUpdate();
CHECK_EQ(1, stats_update.intervals_count());
CHECK_EQ(3, stats_update.numbers_written());
CHECK_EQ(1, stats_update.updates_written());
CHECK_LT(0, entries_size = stats_update.entries_size());
// They are the array and its buffer.
CHECK_EQ(2, stats_update.entries_count());
......@@ -870,7 +871,7 @@ TEST(HeapSnapshotObjectsStats) {
CHECK_EQ(1, stats_update.intervals_count());
// The first interval was changed because old buffer was collected.
// The second interval was changed because new buffer was allocated.
CHECK_EQ(6, stats_update.numbers_written());
CHECK_EQ(2, stats_update.updates_written());
CHECK_LT(entries_size, stats_update.entries_size());
CHECK_EQ(2, stats_update.entries_count());
CHECK_EQ(8, stats_update.first_interval_index());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment