v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
trace-buffer.cc
Go to the documentation of this file.
1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7namespace v8 {
8namespace platform {
9namespace tracing {
10
12 TraceWriter* trace_writer)
13 : max_chunks_(max_chunks) {
14 trace_writer_.reset(trace_writer);
15 chunks_.resize(max_chunks);
16}
17
20 if (is_empty_ || chunks_[chunk_index_]->IsFull()) {
22 is_empty_ = false;
23 auto& chunk = chunks_[chunk_index_];
24 if (chunk) {
25 chunk->Reset(current_chunk_seq_++);
26 } else {
27 chunk.reset(new TraceBufferChunk(current_chunk_seq_++));
28 }
29 }
30 auto& chunk = chunks_[chunk_index_];
31 size_t event_index;
32 TraceObject* trace_object = chunk->AddTraceEvent(&event_index);
33 *handle = MakeHandle(chunk_index_, chunk->seq(), event_index);
34 return trace_object;
35}
36
39 size_t chunk_index, event_index;
40 uint32_t chunk_seq;
41 ExtractHandle(handle, &chunk_index, &chunk_seq, &event_index);
42 if (chunk_index >= chunks_.size()) return nullptr;
43 auto& chunk = chunks_[chunk_index];
44 if (!chunk || chunk->seq() != chunk_seq) return nullptr;
45 return chunk->GetEventAt(event_index);
46}
47
50 // This flushes all the traces stored in the buffer.
51 if (!is_empty_) {
52 for (size_t i = NextChunkIndex(chunk_index_);; i = NextChunkIndex(i)) {
53 if (auto& chunk = chunks_[i]) {
54 for (size_t j = 0; j < chunk->size(); ++j) {
55 trace_writer_->AppendTraceEvent(chunk->GetEventAt(j));
56 }
57 }
58 if (i == chunk_index_) break;
59 }
60 }
61 trace_writer_->Flush();
62 // This resets the trace buffer.
63 is_empty_ = true;
64 return true;
65}
66
67uint64_t TraceBufferRingBuffer::MakeHandle(size_t chunk_index,
68 uint32_t chunk_seq,
69 size_t event_index) const {
70 return static_cast<uint64_t>(chunk_seq) * Capacity() +
71 chunk_index * TraceBufferChunk::kChunkSize + event_index;
72}
73
74void TraceBufferRingBuffer::ExtractHandle(uint64_t handle, size_t* chunk_index,
75 uint32_t* chunk_seq,
76 size_t* event_index) const {
77 *chunk_seq = static_cast<uint32_t>(handle / Capacity());
78 size_t indices = handle % Capacity();
79 *chunk_index = indices / TraceBufferChunk::kChunkSize;
80 *event_index = indices % TraceBufferChunk::kChunkSize;
81}
82
83size_t TraceBufferRingBuffer::NextChunkIndex(size_t index) const {
84 if (++index >= max_chunks_) index = 0;
85 return index;
86}
87
88TraceBufferChunk::TraceBufferChunk(uint32_t seq) : seq_(seq) {}
89
90void TraceBufferChunk::Reset(uint32_t new_seq) {
91 next_free_ = 0;
92 seq_ = new_seq;
93}
94
96 *event_index = next_free_++;
97 return &chunk_[*event_index];
98}
99
101 size_t max_chunks, TraceWriter* trace_writer) {
102 return new TraceBufferRingBuffer(max_chunks, trace_writer);
103}
104
105} // namespace tracing
106} // namespace platform
107} // namespace v8
TraceObject * AddTraceEvent(size_t *event_index)
TraceBufferRingBuffer(size_t max_chunks, TraceWriter *trace_writer)
TraceObject * GetEventByHandle(uint64_t handle) override
TraceObject * AddTraceEvent(uint64_t *handle) override
std::unique_ptr< TraceWriter > trace_writer_
std::vector< std::unique_ptr< TraceBufferChunk > > chunks_
uint64_t MakeHandle(size_t chunk_index, uint32_t chunk_seq, size_t event_index) const
size_t NextChunkIndex(size_t index) const
void ExtractHandle(uint64_t handle, size_t *chunk_index, uint32_t *chunk_seq, size_t *event_index) const
static TraceBuffer * CreateTraceBufferRingBuffer(size_t max_chunks, TraceWriter *trace_writer)
OptionalOpIndex index