-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTinyGC.h
131 lines (99 loc) · 2.7 KB
/
TinyGC.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
//
// Created by v4kst1z.
//
//
// TinyGC.h: 标准系统包含文件的包含文件
// 或项目特定的包含文件。
#pragma once
#include <iostream>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#if defined(_WIN32)
#include <intrin.h>
#include <windows.h>
#include <winnt.h>
#include <cstddef>
#elif defined(__GLIBC__)
extern "C" void *__libc_stack_end;
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#endif
#include <vector>
#include "Common.h"
// Forward declarations
class Visitor;
class GarbageCollectedBase;
class TinyGC {
public:
static TinyGC &GetInstance() {
static TinyGC tg;
return tg;
}
~TinyGC();
enum class GCPhase {
kNone,
kMarking,
kSweeping,
};
void SetGCPhase(GCPhase);
void AttachCurrentThread();
void AttachMainThread();
void DetachMainThread();
void DetachCurrentThread();
void MarkSweepGC();
template <typename T, typename... Args>
T *MakeGarbageCollected(Args &&...args);
DISALLOW_COPY_AND_ASSIGN(TinyGC);
private:
class ThreadState {
public:
explicit ThreadState(bool main = false)
: stack_end_(nullptr),
main_thread_(main),
thread_id_(std::this_thread::get_id()) {
stack_start_ = GetStackStart(main_thread_);
}
void GetCurrentStackPosition();
void *GetStackStartAddr() { return stack_start_; }
void *GetStackEndAddr() { return stack_end_; }
std::thread::id GetThreadId() { return thread_id_; }
private:
void *GetStackStart(bool main);
void *GetStackEnd();
void *stack_start_;
void *stack_end_;
bool main_thread_;
std::thread::id thread_id_;
};
TinyGC();
void Mark();
void Sweep();
void CheckThreshold();
void SwitchTrace(GarbageCollectedBase *ptr);
std::unordered_set<GarbageCollectedBase *> objs_addr_;
std::unordered_map<std::thread::id, ThreadState *> thread_to_stack_;
std::mutex ts_mxt_;
std::mutex alloc_mxt_;
Visitor *visitor_;
GCPhase gc_phase_;
int bytes_allocated_;
int size_of_objects_;
int gc_count_threshold_;
int gc_bytes_threshold_;
};
template <typename T, typename... Args>
T *TinyGC::MakeGarbageCollected(Args &&...args) {
std::unique_lock<std::mutex> lck(alloc_mxt_);
CheckThreshold();
T *new_obj = ::new (malloc(sizeof(T))) T(std::forward<Args>(args)...);
LOG("Object is allocated at " << new_obj);
objs_addr_.insert(new_obj);
this->bytes_allocated_ += new_obj->GetObjSize();
this->size_of_objects_++;
return new_obj;
}
static TinyGC &tg = TinyGC::GetInstance();
#define MakeGarbageCollected tg.MakeGarbageCollected