-
Notifications
You must be signed in to change notification settings - Fork 0
/
GCRegion.h
150 lines (105 loc) · 4.04 KB
/
GCRegion.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
#ifndef CPPGCPTR_GCREGION_H
#define CPPGCPTR_GCREGION_H
#include <iostream>
#include <cstdlib>
#include <vector>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <unordered_map>
#include <functional>
#include <cstring>
#include <stdexcept>
#include "GCWorker.h"
#include "GCBitMap.h"
#include "GCRegionalHashMap.h"
#include "GCPhase.h"
#include "GCStatus.h"
#include "GCParameter.h"
#include "PhaseEnum.h"
#include "IAllocatable.h"
#include "IMemoryAllocator.h"
class GCWorker;
class IMemoryAllocator;
class GCBitMap;
enum class RegionEnum {
SMALL, MEDIUM, LARGE, TINY
};
class RegionEnumUtil {
public:
static short toShort(RegionEnum regionEnum);
static RegionEnum toRegionEnum(short e);
};
class GCRegion : public IAllocatable {
friend class MemoryAllocatorTest;
public:
static const size_t TINY_OBJECT_THRESHOLD;
static const size_t TINY_REGION_SIZE;
static const size_t SMALL_OBJECT_THRESHOLD;
static const size_t SMALL_REGION_SIZE;
static const size_t MEDIUM_OBJECT_THRESHOLD;
static const size_t MEDIUM_REGION_SIZE;
static constexpr bool use_regional_hashmap = GCParameter::useRegionalHashmap;
static constexpr bool enable_destructor = GCParameter::enableDestructorSupport;
static constexpr bool enable_move_constructor = GCParameter::enableMoveConstructor;
private:
void* startAddress;
size_t total_size;
std::atomic<size_t> allocated_offset;
std::atomic<size_t> live_size;
RegionEnum regionType;
MarkStateBit largeRegionMarkState; // only used in large region
std::unique_ptr<GCBitMap> bitmap; // bitmap
std::unique_ptr<GCRegionalHashMap> regionalHashMap; // regional hash map
std::unordered_map<void*, std::pair<void*, std::shared_ptr<GCRegion>>> forwarding_table;
std::shared_mutex forwarding_table_mutex;
std::unique_ptr<std::unordered_map<void*, std::function<void(void*)>>> destructor_map;
std::shared_mutex destructor_map_mtx;
std::unique_ptr<std::unordered_map<void*, std::function<void(void*, void*)>>> move_constructor_map;
std::shared_mutex move_constructor_map_mtx;
std::recursive_mutex relocation_mutex;
IMemoryAllocator* memoryAllocator;
std::atomic<bool> evacuated;
std::atomic<int> use_count; // 用于PtrGuard计数用,PtrGuard存在期间禁止重定位
std::mutex zero_count_mutex;
std::condition_variable zero_count_condition;
protected:
float getFragmentRatio() const;
float getFreeRatio() const;
void callDestructor(void*);
void callMoveConstructor(void*, void*);
public:
struct GCRegionHash {
size_t operator()(const GCRegion& p) const;
};
GCRegion(RegionEnum regionType, void* startAddress, size_t total_size, IMemoryAllocator* memoryAllocator);
GCRegion(const GCRegion&) = delete;
GCRegion(GCRegion&&) noexcept;
size_t getTotalSize() const { return total_size; }
void* getStartAddr() const { return startAddress; }
RegionEnum getRegionType() const { return regionType; }
void* allocate(size_t size) override;
void free(void* addr, size_t size) override;
void mark(void* object_addr, size_t object_size);
bool marked(void* object_addr);
void clearUnmarked();
bool canFree() const;
void free();
bool needEvacuate() const;
bool isEvacuated() const { return evacuated.load(); }
void setEvacuated() { evacuated.store(true); }
bool isFreed() const { return startAddress == nullptr && evacuated; }
void resetLiveSize() { live_size = 0; }
void triggerRelocation();
void relocateObject(void*, size_t);
std::pair<void*, std::shared_ptr<GCRegion>> queryForwardingTable(void*);
bool inside_region(void*, size_t = 0) const;
void reclaim();
void registerDestructor(void*, const std::function<void(void*)>&);
void registerMoveConstructor(void*, const std::function<void(void*, void*)>&);
void inc_use_count();
void dec_use_count();
bool zero_use_count() const { return use_count == 0; }
};
#endif //CPPGCPTR_GCREGION_H