-
Notifications
You must be signed in to change notification settings - Fork 0
/
GCWorker.h
165 lines (117 loc) · 4.6 KB
/
GCWorker.h
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#ifndef CPPGCPTR_GCWORKER_H
#define CPPGCPTR_GCWORKER_H
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>
#include <vector>
#include <memory>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <functional>
#include <condition_variable>
#include "GCPtrBase.h"
#include "GCMemoryAllocator.h"
#include "GCRootSet.h"
#include "GCUtil.h"
#include "GCParameter.h"
#include "ObjectInfo.h"
#include "GCStatus.h"
#include "PhaseEnum.h"
#include "CppExecutor/ThreadPoolExecutor.h"
#include "CppExecutor/ArrayBlockingQueue.h"
class GCMemoryAllocator;
class GCRegion;
class GCWorker {
private:
static std::unique_ptr<GCWorker> instance;
std::unordered_map<void*, GCStatus> object_map;
std::shared_mutex object_map_mutex;
std::unique_ptr<std::unordered_set<GCPtrBase*>[]> root_set;
std::unique_ptr<std::unordered_map<GCPtrBase*, bool>[]> root_map; // bool代表删除标记位
std::unique_ptr<std::shared_mutex[]> root_set_mutex;
std::vector<void*> root_ptr_snapshot;
std::vector<ObjectInfo> root_object_snapshot;
std::vector<std::vector<ObjectInfo>> root_object_snapshots;
std::unique_ptr<GCRootSet> gcRootSet;
std::mutex gcRootsetMtx;
std::vector<void*> satb_queue;
int poolCount;
std::vector<std::vector<ObjectInfo>> satb_queue_pool;
std::unique_ptr<std::mutex[]> satb_queue_pool_mutex;
std::mutex satb_queue_mutex;
std::unordered_set<void*> satb_set;
std::unique_ptr<std::set<GCPtrBase*>> gcPtrSet;
std::unique_ptr<std::shared_mutex> gcPtrSetMtx;
std::unordered_map<void*, std::function<void(void*)>> destructor_map;
std::mutex destructor_map_mutex;
std::mutex thread_mutex;
std::mutex finished_gc_mutex;
std::condition_variable condition;
std::condition_variable finished_gc_condition;
std::unique_ptr<std::thread> gc_thread;
std::unique_ptr<GCMemoryAllocator> memoryAllocator;
std::unique_ptr<ThreadPoolExecutor> threadPool;
int gcThreadCount;
bool enableConcurrentMark, enableParallelGC, enableMemoryAllocator, useInlineMarkstate,
enableRelocation, enableDestructorSupport;
volatile bool stop_, ready_;
void mark(void*);
void mark_v2(GCPtrBase*);
void mark_v2(const ObjectInfo&);
void mark_root(GCPtrBase* gcptr, int root_snapshots_index = -1);
void GCThreadLoop();
void callDestructor(void*, bool remove_after_call = false);
template<typename U>
void getParallelIndex(int tid, const std::vector<U>& vec, size_t& startIndex, size_t& endIndex) {
size_t snum = vec.size() / gcThreadCount;
startIndex = tid * snum;
if (tid == gcThreadCount - 1)
endIndex = vec.size();
else
endIndex = (tid + 1) * snum;
}
void startGC();
void beginMark();
void triggerSATBMark();
void beginSweep();
void selectRelocationSet();
void endGC();
int getPoolIdx() const {
if (poolCount == 1) return 0;
return GCUtil::getPoolIdx(poolCount);
}
public:
GCWorker();
GCWorker(bool concurrent, bool enableMemoryAllocator, bool enableDestructorSupport = true,
bool useInlineMarkState = true, bool useSecondaryMemoryManager = false,
bool enableRelocation = false, bool enableParallel = false);
GCWorker(const GCWorker&) = delete;
GCWorker(GCWorker&&) noexcept = delete;
GCWorker& operator=(const GCWorker&) = delete;
~GCWorker();
static GCWorker* getWorker();
void wakeUpGCThread();
void triggerGC();
std::pair<void*, std::shared_ptr<GCRegion>> allocate(size_t size);
void registerObject(void* object_addr, size_t object_size);
void addRoot(GCPtrBase*);
void removeRoot(GCPtrBase*);
void addSATB(void* object_addr);
void addSATB(const ObjectInfo&);
void addGCPtr(GCPtrBase*);
void removeGCPtr(GCPtrBase*);
void replaceGCPtr(GCPtrBase* original, GCPtrBase* replacement);
void registerDestructor(void* object_addr, const std::function<void(void*)>&, GCRegion* = nullptr);
std::pair<void*, std::shared_ptr<GCRegion>> getHealedPointer(void*, size_t, GCRegion*) const;
void printMap() const;
bool destructorEnabled() const { return enableDestructorSupport; }
bool memoryAllocatorEnabled() const { return enableMemoryAllocator; }
bool relocationEnabled() const { return enableRelocation; }
bool is_root(void* gcptr_addr);
bool inside_gcptr_set(GCPtrBase* gcptr_addr, bool include_root_set = false);
std::vector<GCPtrBase*> inside_gcptr_set(GCPtrBase* gcptr_addr, size_t object_size);
void freeGCReservedMemory();
};
#endif //CPPGCPTR_GCWORKER_H