Skip to content

Commit 390bdaa

Browse files
committed
Use the parser arena for the constant pool
1 parent dadeb7e commit 390bdaa

3 files changed

Lines changed: 31 additions & 86 deletions

File tree

include/prism/util/pm_constant_pool.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ typedef struct {
146146
* @param capacity The initial capacity of the pool.
147147
* @return Whether the initialization succeeded.
148148
*/
149-
bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity);
149+
void pm_constant_pool_init(pm_arena_t *arena, pm_constant_pool_t *pool, uint32_t capacity);
150150

151151
/**
152152
* Return a pointer to the constant indicated by the given constant id.
@@ -177,7 +177,7 @@ pm_constant_id_t pm_constant_pool_find(const pm_constant_pool_t *pool, const uin
177177
* @param length The length of the constant.
178178
* @return The id of the constant.
179179
*/
180-
pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
180+
pm_constant_id_t pm_constant_pool_insert_shared(pm_arena_t *arena, pm_constant_pool_t *pool, const uint8_t *start, size_t length);
181181

182182
/**
183183
* Insert a constant into a constant pool from memory that is now owned by the
@@ -189,7 +189,7 @@ pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const
189189
* @param length The length of the constant.
190190
* @return The id of the constant.
191191
*/
192-
pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, uint8_t *start, size_t length);
192+
pm_constant_id_t pm_constant_pool_insert_owned(pm_arena_t *arena, pm_constant_pool_t *pool, uint8_t *start, size_t length);
193193

194194
/**
195195
* Insert a constant into a constant pool from memory that is constant. Returns
@@ -200,13 +200,6 @@ pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, uint8_t
200200
* @param length The length of the constant.
201201
* @return The id of the constant.
202202
*/
203-
pm_constant_id_t pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
204-
205-
/**
206-
* Free the memory associated with a constant pool.
207-
*
208-
* @param pool The pool to free.
209-
*/
210-
void pm_constant_pool_free(pm_constant_pool_t *pool);
203+
pm_constant_id_t pm_constant_pool_insert_constant(pm_arena_t *arena, pm_constant_pool_t *pool, const uint8_t *start, size_t length);
211204

212205
#endif

src/prism.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,23 +1028,23 @@ pm_locals_order(PRISM_ATTRIBUTE_UNUSED pm_parser_t *parser, pm_locals_t *locals,
10281028
*/
10291029
static inline pm_constant_id_t
10301030
pm_parser_constant_id_raw(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
1031-
return pm_constant_pool_insert_shared(&parser->constant_pool, start, (size_t) (end - start));
1031+
return pm_constant_pool_insert_shared(&parser->metadata_arena, &parser->constant_pool, start, (size_t) (end - start));
10321032
}
10331033

10341034
/**
10351035
* Retrieve the constant pool id for the given string.
10361036
*/
10371037
static inline pm_constant_id_t
10381038
pm_parser_constant_id_owned(pm_parser_t *parser, uint8_t *start, size_t length) {
1039-
return pm_constant_pool_insert_owned(&parser->constant_pool, start, length);
1039+
return pm_constant_pool_insert_owned(&parser->metadata_arena, &parser->constant_pool, start, length);
10401040
}
10411041

10421042
/**
10431043
* Retrieve the constant pool id for the given static literal C string.
10441044
*/
10451045
static inline pm_constant_id_t
10461046
pm_parser_constant_id_constant(pm_parser_t *parser, const char *start, size_t length) {
1047-
return pm_constant_pool_insert_constant(&parser->constant_pool, (const uint8_t *) start, length);
1047+
return pm_constant_pool_insert_constant(&parser->metadata_arena, &parser->constant_pool, (const uint8_t *) start, length);
10481048
}
10491049

10501050
/**
@@ -2908,10 +2908,10 @@ pm_call_write_read_name_init(pm_parser_t *parser, pm_constant_id_t *read_name, p
29082908
if (write_constant->length > 0) {
29092909
size_t length = write_constant->length - 1;
29102910

2911-
void *memory = xmalloc(length);
2911+
uint8_t *memory = (uint8_t *) pm_arena_alloc(parser->arena, length, 1);
29122912
memcpy(memory, write_constant->start, length);
29132913

2914-
*read_name = pm_constant_pool_insert_owned(&parser->constant_pool, (uint8_t *) memory, length);
2914+
*read_name = pm_constant_pool_insert_owned(&parser->metadata_arena, &parser->constant_pool, memory, length);
29152915
} else {
29162916
// We can get here if the message was missing because of a syntax error.
29172917
*read_name = pm_parser_constant_id_constant(parser, "", 0);
@@ -12543,16 +12543,12 @@ parse_write_name(pm_parser_t *parser, pm_constant_id_t *name_field) {
1254312543
// append an =.
1254412544
pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, *name_field);
1254512545
size_t length = constant->length;
12546-
uint8_t *name = xcalloc(length + 1, sizeof(uint8_t));
12547-
if (name == NULL) return;
12546+
uint8_t *name = (uint8_t *) pm_arena_alloc(parser->arena, length + 1, 1);
1254812547

1254912548
memcpy(name, constant->start, length);
1255012549
name[length] = '=';
1255112550

12552-
// Now switch the name to the new string.
12553-
// This silences clang analyzer warning about leak of memory pointed by `name`.
12554-
// NOLINTNEXTLINE(clang-analyzer-*)
12555-
*name_field = pm_constant_pool_insert_owned(&parser->constant_pool, name, length + 1);
12551+
*name_field = pm_constant_pool_insert_owned(&parser->metadata_arena, &parser->constant_pool, name, length + 1);
1255612552
}
1255712553

1255812554
/**
@@ -21950,7 +21946,7 @@ pm_parser_init(pm_arena_t *arena, pm_parser_t *parser, const uint8_t *source, si
2195021946
// This ratio will need to change if we add more constants to the constant
2195121947
// pool for another node type.
2195221948
uint32_t constant_size = ((uint32_t) size) / 95;
21953-
pm_constant_pool_init(&parser->constant_pool, constant_size < 4 ? 4 : constant_size);
21949+
pm_constant_pool_init(&parser->metadata_arena, &parser->constant_pool, constant_size < 4 ? 4 : constant_size);
2195421950

2195521951
// Initialize the newline list. Similar to the constant pool, we're going to
2195621952
// guess at the number of newlines that we'll need based on the size of the
@@ -22150,7 +22146,6 @@ pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_ch
2215022146
PRISM_EXPORTED_FUNCTION void
2215122147
pm_parser_free(pm_parser_t *parser) {
2215222148
pm_string_free(&parser->filepath);
22153-
pm_constant_pool_free(&parser->constant_pool);
2215422149
pm_arena_free(&parser->metadata_arena);
2215522150

2215622151
while (parser->current_scope != NULL) {

src/util/pm_constant_pool.c

Lines changed: 19 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -115,21 +115,15 @@ is_power_of_two(uint32_t size) {
115115
/**
116116
* Resize a constant pool to a given capacity.
117117
*/
118-
static inline bool
119-
pm_constant_pool_resize(pm_constant_pool_t *pool) {
118+
static inline void
119+
pm_constant_pool_resize(pm_arena_t *arena, pm_constant_pool_t *pool) {
120120
assert(is_power_of_two(pool->capacity));
121121

122122
uint32_t next_capacity = pool->capacity * 2;
123-
if (next_capacity < pool->capacity) return false;
124-
125123
const uint32_t mask = next_capacity - 1;
126-
const size_t element_size = sizeof(pm_constant_pool_bucket_t) + sizeof(pm_constant_t);
127-
128-
void *next = xcalloc(next_capacity, element_size);
129-
if (next == NULL) return false;
130124

131-
pm_constant_pool_bucket_t *next_buckets = next;
132-
pm_constant_t *next_constants = (void *)(((char *) next) + next_capacity * sizeof(pm_constant_pool_bucket_t));
125+
pm_constant_pool_bucket_t *next_buckets = (pm_constant_pool_bucket_t *) pm_arena_zalloc(arena, next_capacity * sizeof(pm_constant_pool_bucket_t), PRISM_ALIGNOF(pm_constant_pool_bucket_t));
126+
pm_constant_t *next_constants = (pm_constant_t *) pm_arena_alloc(arena, next_capacity * sizeof(pm_constant_t), PRISM_ALIGNOF(pm_constant_t));
133127

134128
// For each bucket in the current constant pool, find the index in the
135129
// next constant pool, and insert it.
@@ -157,33 +151,22 @@ pm_constant_pool_resize(pm_constant_pool_t *pool) {
157151
// The constants are stable with respect to hash table resizes.
158152
memcpy(next_constants, pool->constants, pool->size * sizeof(pm_constant_t));
159153

160-
// pool->constants and pool->buckets are allocated out of the same chunk
161-
// of memory, with the buckets coming first.
162-
xfree_sized(pool->buckets, pool->capacity * element_size);
163154
pool->constants = next_constants;
164155
pool->buckets = next_buckets;
165156
pool->capacity = next_capacity;
166-
return true;
167157
}
168158

169159
/**
170160
* Initialize a new constant pool with a given capacity.
171161
*/
172-
bool
173-
pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) {
174-
const uint32_t maximum = (~((uint32_t) 0));
175-
if (capacity >= ((maximum / 2) + 1)) return false;
176-
162+
void
163+
pm_constant_pool_init(pm_arena_t *arena, pm_constant_pool_t *pool, uint32_t capacity) {
177164
capacity = next_power_of_two(capacity);
178-
const size_t element_size = sizeof(pm_constant_pool_bucket_t) + sizeof(pm_constant_t);
179-
void *memory = xcalloc(capacity, element_size);
180-
if (memory == NULL) return false;
181165

182-
pool->buckets = memory;
183-
pool->constants = (void *)(((char *)memory) + capacity * sizeof(pm_constant_pool_bucket_t));
166+
pool->buckets = (pm_constant_pool_bucket_t *) pm_arena_zalloc(arena, capacity * sizeof(pm_constant_pool_bucket_t), PRISM_ALIGNOF(pm_constant_pool_bucket_t));
167+
pool->constants = (pm_constant_t *) pm_arena_alloc(arena, capacity * sizeof(pm_constant_t), PRISM_ALIGNOF(pm_constant_t));
184168
pool->size = 0;
185169
pool->capacity = capacity;
186-
return true;
187170
}
188171

189172
/**
@@ -224,9 +207,9 @@ pm_constant_pool_find(const pm_constant_pool_t *pool, const uint8_t *start, size
224207
* Insert a constant into a constant pool and return its index in the pool.
225208
*/
226209
static inline pm_constant_id_t
227-
pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length, pm_constant_pool_bucket_type_t type) {
210+
pm_constant_pool_insert(pm_arena_t *arena, pm_constant_pool_t *pool, const uint8_t *start, size_t length, pm_constant_pool_bucket_type_t type) {
228211
if (pool->size >= (pool->capacity / 4 * 3)) {
229-
if (!pm_constant_pool_resize(pool)) return PM_CONSTANT_ID_UNSET;
212+
pm_constant_pool_resize(arena, pool);
230213
}
231214

232215
assert(is_power_of_two(pool->capacity));
@@ -246,17 +229,10 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
246229
// Since we have found a match, we need to check if this is
247230
// attempting to insert a shared or an owned constant. We want to
248231
// prefer shared constants since they don't require allocations.
249-
if (type == PM_CONSTANT_POOL_BUCKET_OWNED) {
250-
// If we're attempting to insert an owned constant and we have
251-
// an existing constant, then either way we don't want the given
252-
// memory. Either it's duplicated with the existing constant or
253-
// it's not necessary because we have a shared version.
254-
xfree_sized((void *) start, length);
255-
} else if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) {
232+
if (type != PM_CONSTANT_POOL_BUCKET_OWNED && bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) {
256233
// If we're attempting to insert a shared constant and the
257-
// existing constant is owned, then we can free the owned
258-
// constant and replace it with the shared constant.
259-
xfree_sized((void *) constant->start, constant->length);
234+
// existing constant is owned, then we can replace it with the
235+
// shared constant to prefer non-owned references.
260236
constant->start = start;
261237
bucket->type = (unsigned int) (type & 0x3);
262238
}
@@ -291,8 +267,8 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
291267
* PM_CONSTANT_ID_UNSET if any potential calls to resize fail.
292268
*/
293269
pm_constant_id_t
294-
pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
295-
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_DEFAULT);
270+
pm_constant_pool_insert_shared(pm_arena_t *arena, pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
271+
return pm_constant_pool_insert(arena, pool, start, length, PM_CONSTANT_POOL_BUCKET_DEFAULT);
296272
}
297273

298274
/**
@@ -301,8 +277,8 @@ pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, s
301277
* potential calls to resize fail.
302278
*/
303279
pm_constant_id_t
304-
pm_constant_pool_insert_owned(pm_constant_pool_t *pool, uint8_t *start, size_t length) {
305-
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_OWNED);
280+
pm_constant_pool_insert_owned(pm_arena_t *arena, pm_constant_pool_t *pool, uint8_t *start, size_t length) {
281+
return pm_constant_pool_insert(arena, pool, start, length, PM_CONSTANT_POOL_BUCKET_OWNED);
306282
}
307283

308284
/**
@@ -311,26 +287,7 @@ pm_constant_pool_insert_owned(pm_constant_pool_t *pool, uint8_t *start, size_t l
311287
* resize fail.
312288
*/
313289
pm_constant_id_t
314-
pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
315-
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_CONSTANT);
290+
pm_constant_pool_insert_constant(pm_arena_t *arena, pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
291+
return pm_constant_pool_insert(arena, pool, start, length, PM_CONSTANT_POOL_BUCKET_CONSTANT);
316292
}
317293

318-
/**
319-
* Free the memory associated with a constant pool.
320-
*/
321-
void
322-
pm_constant_pool_free(pm_constant_pool_t *pool) {
323-
// For each constant in the current constant pool, free the contents if the
324-
// contents are owned.
325-
for (uint32_t index = 0; index < pool->capacity; index++) {
326-
pm_constant_pool_bucket_t *bucket = &pool->buckets[index];
327-
328-
// If an id is set on this constant, then we know we have content here.
329-
if (bucket->id != PM_CONSTANT_ID_UNSET && bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) {
330-
pm_constant_t *constant = &pool->constants[bucket->id - 1];
331-
xfree_sized((void *) constant->start, constant->length);
332-
}
333-
}
334-
335-
xfree_sized(pool->buckets, pool->capacity * (sizeof(pm_constant_pool_bucket_t) + sizeof(pm_constant_t)));
336-
}

0 commit comments

Comments
 (0)