-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalue.h
107 lines (85 loc) · 2.22 KB
/
value.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
#ifndef __VALUE_H__
#define __VALUE_H__
#include <list>
#include <stdint.h>
typedef uint64_t value_t;
typedef std::list<value_t> value_list_t;
extern const
uint8_t MARK_POLICY_NONE,
MARK_POLICY_FIRST,
MARK_POLICY_SECOND,
MARK_POLICY_BOTH,
GC_ALWAYS_MARKED,
GC_HAS_MARK,
GC_IS_IN_USE;
static inline
bool is_immediate(value_t value) {
return (value & 0x03) != 0;
}
#define GC_DATA_OFFSET 44
#define CLEAR_GC_DATA_MASK ~((uint64_t) 0xFF << GC_DATA_OFFSET)
// Header:
// abcd: a -> immutable, b c d -> reserved
// T(8): T -> type info
// GC(8): GC -> Garbage Collector Info
//
static inline
uint64_t make_header(bool immutable, uint8_t type, uint8_t mark_policy) {
uint64_t result = 0;
if (immutable) {
result |= 0x8000000000000000;
}
result |= ((uint64_t) type) << 52;
result |= ((uint64_t) (mark_policy|GC_IS_IN_USE)) << GC_DATA_OFFSET;
return result;
}
static inline
uint8_t header_get_type(uint64_t header) {
return (uint8_t) (header >> 52);
}
#include "storage.h"
#include "pointer.h"
static inline
uint64_t* get_header(value_t value) {
return &(((double_storage_t*) unwrap_pointer(value))->header);
}
static inline
uint8_t get_non_immediate_type(value_t value) {
// TODO: Adapt this for non-builtin types.
uint64_t* header = get_header(value);
return header_get_type(*header);
}
static inline
uint8_t get_gc_data(uint64_t header) {
return (uint8_t) (header >> GC_DATA_OFFSET);
}
static inline
void set_gc_data(uint64_t* header, uint8_t gc_data) {
*header &= CLEAR_GC_DATA_MASK;
*header |= (uint64_t) gc_data << GC_DATA_OFFSET;
}
static inline
void set_gc_mark(uint64_t* header) {
*header |= (uint64_t) GC_HAS_MARK << GC_DATA_OFFSET;
}
static inline
void clear_gc_mark(uint64_t* header) {
*header &= ~((uint64_t) GC_HAS_MARK << GC_DATA_OFFSET);
}
static inline
bool has_gc_mark(uint64_t header) {
return (get_gc_data(header) & (GC_HAS_MARK|GC_ALWAYS_MARKED)) != 0;
}
static inline
bool is_in_use(uint64_t header) {
return (get_gc_data(header) & GC_IS_IN_USE) != 0;
}
static inline
uint64_t must_mark_first(uint64_t header) {
return get_gc_data(header) & MARK_POLICY_FIRST;
}
static inline
uint64_t must_mark_second(uint64_t header) {
return get_gc_data(header) & MARK_POLICY_SECOND;
}
#endif