-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAllocator.h
136 lines (108 loc) · 3.96 KB
/
Allocator.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
#pragma once
#include <vector>
#include "Object.h"
#include "Value.h"
#include "Utils.h"
#include "Logger.h"
namespace lwscript
{
struct CallFrame
{
ClosureObject *closure = nullptr;
uint8_t *ip = nullptr;
Value *slots = nullptr;
#ifdef LWSCRIPT_FUNCTION_CACHE_OPT
size_t argumentsHash;
#endif
};
class LWSCRIPT_API Allocator
{
public:
SINGLETON_DECL(Allocator)
void ResetStatus();
template <class T, typename... Args>
T *CreateObject(Args &&...params);
void PushStack(const Value &value);
Value PopStack();
Value PeekStack(int32_t distance);
void SetStackTop(Value *top);
Value *StackTop() const;
Value *Stack();
void MoveStackTop(int32_t offset);
void PushCallFrame(const CallFrame &callFrame);
CallFrame *PopCallFrame();
CallFrame *PeekCallFrame(int32_t distance);
bool IsCallFrameStackEmpty();
size_t CallFrameCount();
UpValueObject *CaptureUpValue(Value *location);
void ClosedUpValues(Value *end);
void SetValueFromStackTopOffset(int32_t offset, const Value &value);
Value *GetGlobalVariable(size_t idx);
void SetGlobalVariable(size_t idx, const Value &v);
private:
Allocator();
~Allocator();
template <class T>
void FreeObject(T *object);
void FreeObjects();
void GC();
void MarkRootObjects();
void MarkGrayObjects();
void Sweep();
Value mGlobalVariableList[GLOBAL_VARIABLE_MAX];
Value *mStackTop;
Value mValueStack[STACK_MAX];
CallFrame *mCallFrameTop;
CallFrame mCallFrameStack[STACK_MAX];
UpValueObject *mOpenUpValues;
friend struct Object;
Object *mObjectChain;
std::vector<Object *> mGrayObjects;
size_t mBytesAllocated;
size_t mNextGCByteSize;
};
template <class T, typename... Args>
inline T *Allocator::CreateObject(Args &&...params)
{
T *object = new T(std::forward<Args>(params)...);
size_t objBytes = sizeof(*object);
mBytesAllocated += objBytes;
#ifdef LWSCRIPT_GC_STRESS
GC();
#endif
if (mBytesAllocated > mNextGCByteSize)
GC();
object->next = mObjectChain;
object->marked = false;
mObjectChain = object;
#ifdef LWSCRIPT_GC_DEBUG
Logger::Info(TEXT("{} has been add to gc record chain {} for {}"), (void *)object, objBytes, object->kind);
#endif
return object;
}
template <class T>
inline void Allocator::FreeObject(T *object)
{
#ifdef LWSCRIPT_GC_DEBUG
Logger::Info(TEXT("delete object(0x{})"), (void *)object);
#endif
mBytesAllocated -= sizeof(object);
SAFE_DELETE(object);
}
#define GET_GLOBAL_VARIABLE(idx) (Allocator::GetInstance()->GetGlobalVariable(idx))
#define PUSH_STACK(v) (Allocator::GetInstance()->PushStack(v))
#define POP_STACK() (Allocator::GetInstance()->PopStack())
#define PEEK_STACK(dist) (Allocator::GetInstance()->PeekStack(dist))
#define STACK_TOP() (Allocator::GetInstance()->StackTop())
#define STACK() (Allocator::GetInstance()->Stack())
#define SET_STACK_TOP(v) (Allocator::GetInstance()->SetStackTop(v))
#define MOVE_STACK_TOP(idx) (Allocator::GetInstance()->MoveStackTop(idx))
#define SET_VALUE_FROM_STACK_TOP_OFFSET(offset, v) (Allocator::GetInstance()->SetValueFromStackTopOffset(offset, v))
#define PUSH_CALL_FRAME(v) (Allocator::GetInstance()->PushCallFrame(v))
#define POP_CALL_FRAME() (Allocator::GetInstance()->PopCallFrame())
#define PEEK_CALL_FRAME(dist) (Allocator::GetInstance()->PeekCallFrame(dist))
#define IS_CALL_FRAME_STACK_EMPTY() (Allocator::GetInstance()->IsCallFrameStackEmpty())
#define CALL_FRAME_COUNT() (Allocator::GetInstance()->CallFrameCount())
#define CAPTURE_UPVALUE(location) (Allocator::GetInstance()->CaptureUpValue(location))
#define CLOSED_UPVALUES(end) (Allocator::GetInstance()->ClosedUpValues(end))
}