-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmemory.h
122 lines (96 loc) · 3.19 KB
/
memory.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
#ifndef clox_memory_h
#define clox_memory_h
#include <stdio.h>
#include "common.h"
#include "object.h"
#include "value.h"
#ifdef __cplusplus
extern "C" {
#endif
#define GC_GEN_MIN 0
#define GC_GEN_YOUNG_MAX 1
#define GC_GEN_OLD_MIN 2
#define GC_GEN_OLD 3
#define GC_GEN_MAX 4
// NOTE: zeroes the memory
#define ALLOCATE(type, count)\
/*fprintf(stderr, "Allocating %d %s\n", (int)count, xstr(type)) > 0 ? \*/\
(type*)reallocate(NULL, 0, sizeof(type) * (count)) /*: NULL */
#define FREE(type, pointer) \
reallocate(pointer, sizeof(type), 0)
#define FREE_SIZE(oldSize, pointer) \
reallocate(pointer, oldSize, 0)
#define GROW_CAPACITY(capacity) \
((capacity) < 8 ? 8 : (capacity) * 2)
#define GROW_ARRAY(previous, type, oldCount, count) \
(type*)reallocate(previous, sizeof(type) * (oldCount), \
sizeof(type) * (count))
#define FREE_ARRAY(type, pointer, oldCount) \
reallocate(pointer, sizeof(type) * (oldCount), 0)
#define GC_HEAP_GROW_FACTOR 2
#define xfree free
#define xmalloc malloc
#define xcalloc calloc
struct sGCProfile {
struct timeval totalGCYoungTime;
struct timeval totalGCFullTime;
unsigned long runsYoung;
unsigned long runsFull;
};
extern struct sGCProfile GCProf;
extern int activeFinalizers;
struct sGCStats {
// all in bytes
size_t totalAllocated;
size_t heapSize;
size_t heapUsed;
size_t heapUsedWaste;
unsigned long demographics[OBJ_T_LAST];
unsigned long generations[GC_GEN_MAX+1];
};
extern struct sGCStats GCStats;
void *reallocate(void *previous, size_t oldSize, size_t newSize);
void nil_mem(Value *mem, size_t num);
void grayObject(Obj *obj); // non-recursively mark object as live
void grayValue(Value val); // non-recursively mark object in value as live
void collectGarbage(void); // do 1 mark+sweep
void collectYoungGarbage(void); // collect young objects
void freeObject(Obj *obj);
void blackenObject(Obj *obj); // recursively mark object's references
void freeObjects(void); // free all vm.objects. Used at end of VM lifecycle
#define GC_PROMOTE(obj, gen) GCPromote((Obj*)obj, gen)
#define GC_PROMOTE_ONCE(obj) GCPromoteOnce((Obj*)obj)
#define GC_OLD(obj) GCPromote((Obj*)obj, GC_GEN_MAX)
void GCPromote(Obj *obj, unsigned short gen);
void GCPromoteOnce(Obj *obj);
void pushRememberSet(Obj *obj);
#define IS_OLD_VAL(value) (AS_OBJ(value)->GCGen > GC_GEN_MIN)
#define IS_YOUNG_VAL(value) (AS_OBJ(value)->GCGen == GC_GEN_MIN)
#define IS_OLD_OBJ(obj) ((obj)->GCGen > GC_GEN_MIN)
#define IS_YOUNG_OBJ(obj) ((obj)->GCGen == GC_GEN_MIN)
static inline void objWrite(Value owner, Value pointed) {
bool hasFinalizer = false;
if (IS_OBJ(pointed) && IS_YOUNG_VAL(pointed)) {
if (hasFinalizer) {
OBJ_SET_HAS_FINALIZER(AS_OBJ(pointed));
}
pushRememberSet(AS_OBJ(pointed));
}
}
#define OBJ_WRITE(owner, pointed) objWrite(owner, pointed)
extern bool inYoungGC;
extern bool inFullGC;
extern bool inFinalFree;
bool isInGC(void);
bool turnGCOff(void);
bool turnGCOn(void);
void setGCOnOff(bool turnOn);
void hideFromGC(Obj *obj);
void unhideFromGC(Obj *obj);
void printGCProfile(void);
void addHeap(void);
Obj *getNewObject(ObjType type, size_t sz, int flags);
#ifdef __cplusplus
}
#endif
#endif