forked from v8/v8
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathallocation-observer.h
More file actions
132 lines (104 loc) · 4.02 KB
/
allocation-observer.h
File metadata and controls
132 lines (104 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_ALLOCATION_OBSERVER_H_
#define V8_HEAP_ALLOCATION_OBSERVER_H_
#include <cstdint>
#include <unordered_set>
#include <vector>
#include "src/common/globals.h"
namespace v8 {
namespace internal {
class AllocationObserver;
class AllocationCounter {
public:
AllocationCounter()
: paused_(false),
current_counter_(0),
next_counter_(0),
step_in_progress_(false) {}
V8_EXPORT_PRIVATE void AddAllocationObserver(AllocationObserver* observer);
V8_EXPORT_PRIVATE void RemoveAllocationObserver(AllocationObserver* observer);
bool IsActive() { return !IsPaused() && observers_.size() > 0; }
void Pause() {
DCHECK(!paused_);
DCHECK(!step_in_progress_);
paused_ = true;
}
void Resume() {
DCHECK(paused_);
DCHECK(!step_in_progress_);
paused_ = false;
}
V8_EXPORT_PRIVATE void AdvanceAllocationObservers(size_t allocated);
V8_EXPORT_PRIVATE void InvokeAllocationObservers(Address soon_object,
size_t object_size,
size_t aligned_object_size);
size_t NextBytes() {
DCHECK(IsActive());
return next_counter_ - current_counter_;
}
bool IsStepInProgress() { return step_in_progress_; }
private:
bool IsPaused() { return paused_; }
struct AllocationObserverCounter {
AllocationObserverCounter(AllocationObserver* observer, size_t prev_counter,
size_t next_counter)
: observer_(observer),
prev_counter_(prev_counter),
next_counter_(next_counter) {}
AllocationObserver* observer_;
size_t prev_counter_;
size_t next_counter_;
};
std::vector<AllocationObserverCounter> observers_;
std::vector<AllocationObserverCounter> pending_added_;
std::unordered_set<AllocationObserver*> pending_removed_;
bool paused_;
size_t current_counter_;
size_t next_counter_;
bool step_in_progress_;
};
// -----------------------------------------------------------------------------
// Allows observation of allocations.
class AllocationObserver {
public:
explicit AllocationObserver(intptr_t step_size) : step_size_(step_size) {
DCHECK_LE(kTaggedSize, step_size);
}
virtual ~AllocationObserver() = default;
AllocationObserver(const AllocationObserver&) = delete;
AllocationObserver& operator=(const AllocationObserver&) = delete;
protected:
// Pure virtual method provided by the subclasses that gets called when at
// least step_size bytes have been allocated. soon_object is the address just
// allocated (but not yet initialized.) size is the size of the object as
// requested (i.e. w/o the alignment fillers). Some complexities to be aware
// of:
// 1) soon_object will be nullptr in cases where we end up observing an
// allocation that happens to be a filler space (e.g. page boundaries.)
// 2) size is the requested size at the time of allocation. Right-trimming
// may change the object size dynamically.
// 3) soon_object may actually be the first object in an allocation-folding
// group. In such a case size is the size of the group rather than the
// first object.
virtual void Step(int bytes_allocated, Address soon_object, size_t size) = 0;
// Subclasses can override this method to make step size dynamic.
virtual intptr_t GetNextStepSize() { return step_size_; }
private:
intptr_t step_size_;
friend class AllocationCounter;
};
class V8_EXPORT_PRIVATE V8_NODISCARD PauseAllocationObserversScope {
public:
explicit PauseAllocationObserversScope(Heap* heap);
~PauseAllocationObserversScope();
PauseAllocationObserversScope(const PauseAllocationObserversScope&) = delete;
PauseAllocationObserversScope& operator=(
const PauseAllocationObserversScope&) = delete;
private:
Heap* heap_;
};
} // namespace internal
} // namespace v8
#endif // V8_HEAP_ALLOCATION_OBSERVER_H_