From affa6714bc90fd99d29cda092db007d626914af5 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Tue, 31 Oct 2023 11:29:29 -0400 Subject: [PATCH] [ruby/prism] Documentation for constant pool https://github.com/ruby/prism/commit/76af64eb21 --- prism/util/pm_constant_pool.c | 72 +++++++++++++------ prism/util/pm_constant_pool.h | 126 ++++++++++++++++++++++++++++------ 2 files changed, 155 insertions(+), 43 deletions(-) diff --git a/prism/util/pm_constant_pool.c b/prism/util/pm_constant_pool.c index 7d76f8370e..e06682eb48 100644 --- a/prism/util/pm_constant_pool.c +++ b/prism/util/pm_constant_pool.c @@ -1,6 +1,8 @@ #include "prism/util/pm_constant_pool.h" -// Initialize a list of constant ids. +/** + * Initialize a list of constant ids. + */ void pm_constant_id_list_init(pm_constant_id_list_t *list) { list->ids = NULL; @@ -8,8 +10,10 @@ pm_constant_id_list_init(pm_constant_id_list_t *list) { list->capacity = 0; } -// Append a constant id to a list of constant ids. Returns false if any -// potential reallocations fail. +/** + * Append a constant id to a list of constant ids. Returns false if any + * potential reallocations fail. + */ bool pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id) { if (list->size >= list->capacity) { @@ -22,7 +26,9 @@ pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id) { return true; } -// Checks if the current constant id list includes the given constant id. +/** + * Checks if the current constant id list includes the given constant id. + */ bool pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id) { for (size_t index = 0; index < list->size; index++) { @@ -31,13 +37,17 @@ pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id) { return false; } -// Get the memory size of a list of constant ids. +/** + * Get the memory size of a list of constant ids. + */ size_t pm_constant_id_list_memsize(pm_constant_id_list_t *list) { return sizeof(pm_constant_id_list_t) + (list->capacity * sizeof(pm_constant_id_t)); } -// Free the memory associated with a list of constant ids. +/** + * Free the memory associated with a list of constant ids. + */ void pm_constant_id_list_free(pm_constant_id_list_t *list) { if (list->ids != NULL) { @@ -45,8 +55,10 @@ pm_constant_id_list_free(pm_constant_id_list_t *list) { } } -// A relatively simple hash function (djb2) that is used to hash strings. We are -// optimizing here for simplicity and speed. +/** + * A relatively simple hash function (djb2) that is used to hash strings. We are + * optimizing here for simplicity and speed. + */ static inline uint32_t pm_constant_pool_hash(const uint8_t *start, size_t length) { // This is a prime number used as the initial value for the hash function. @@ -59,7 +71,9 @@ pm_constant_pool_hash(const uint8_t *start, size_t length) { return value; } -// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 +/** + * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + */ static uint32_t next_power_of_two(uint32_t v) { // Avoid underflow in subtraction on next line. @@ -84,7 +98,9 @@ is_power_of_two(uint32_t size) { } #endif -// Resize a constant pool to a given capacity. +/** + * Resize a constant pool to a given capacity. + */ static inline bool pm_constant_pool_resize(pm_constant_pool_t *pool) { assert(is_power_of_two(pool->capacity)); @@ -136,7 +152,9 @@ pm_constant_pool_resize(pm_constant_pool_t *pool) { return true; } -// Initialize a new constant pool with a given capacity. +/** + * Initialize a new constant pool with a given capacity. + */ bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) { const uint32_t maximum = (~((uint32_t) 0)); @@ -154,14 +172,18 @@ pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) { return true; } -// Return a pointer to the constant indicated by the given constant id. +/** + * Return a pointer to the constant indicated by the given constant id. + */ pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id) { assert(constant_id > 0 && constant_id <= pool->size); return &pool->constants[constant_id - 1]; } -// Insert a constant into a constant pool and return its index in the pool. +/** + * Insert a constant into a constant pool and return its index in the pool. + */ static inline pm_constant_id_t pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length, pm_constant_pool_bucket_type_t type) { if (pool->size >= (pool->capacity / 4 * 3)) { @@ -225,29 +247,37 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l return id; } -// Insert a constant into a constant pool. Returns the id of the constant, or 0 -// if any potential calls to resize fail. +/** + * Insert a constant into a constant pool. Returns the id of the constant, or 0 + * if any potential calls to resize fail. + */ pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length) { return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_DEFAULT); } -// Insert a constant into a constant pool from memory that is now owned by the -// constant pool. Returns the id of the constant, or 0 if any potential calls to -// resize fail. +/** + * Insert a constant into a constant pool from memory that is now owned by the + * constant pool. Returns the id of the constant, or 0 if any potential calls to + * resize fail. + */ pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length) { return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_OWNED); } -// Insert a constant into a constant pool from memory that is constant. Returns -// the id of the constant, or 0 if any potential calls to resize fail. +/** + * Insert a constant into a constant pool from memory that is constant. Returns + * the id of the constant, or 0 if any potential calls to resize fail. + */ pm_constant_id_t pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length) { return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_CONSTANT); } -// Free the memory associated with a constant pool. +/** + * Free the memory associated with a constant pool. + */ void pm_constant_pool_free(pm_constant_pool_t *pool) { // For each constant in the current constant pool, free the contents if the diff --git a/prism/util/pm_constant_pool.h b/prism/util/pm_constant_pool.h index 2a2804c8d1..19c3b619e1 100644 --- a/prism/util/pm_constant_pool.h +++ b/prism/util/pm_constant_pool.h @@ -22,73 +22,155 @@ typedef struct { size_t capacity; } pm_constant_id_list_t; -// Initialize a list of constant ids. +/** + * Initialize a list of constant ids. + * + * @param list The list to initialize. + */ void pm_constant_id_list_init(pm_constant_id_list_t *list); -// Append a constant id to a list of constant ids. Returns false if any -// potential reallocations fail. +/** + * Append a constant id to a list of constant ids. Returns false if any + * potential reallocations fail. + * + * @param list The list to append to. + * @param id The id to append. + * @return Whether the append succeeded. + */ bool pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id); -// Checks if the current constant id list includes the given constant id. -bool -pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id); +/** + * Checks if the current constant id list includes the given constant id. + * + * @param list The list to check. + * @param id The id to check for. + * @return Whether the list includes the given id. + */ +bool pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id); -// Get the memory size of a list of constant ids. +/** + * Get the memory size of a list of constant ids. + * + * @param list The list to get the memory size of. + * @return The memory size of the list. + */ size_t pm_constant_id_list_memsize(pm_constant_id_list_t *list); -// Free the memory associated with a list of constant ids. +/** + * Free the memory associated with a list of constant ids. + * + * @param list The list to free. + */ void pm_constant_id_list_free(pm_constant_id_list_t *list); -// Constant pool buckets can have a couple of different types. +/** + * The type of bucket in the constant pool hash map. This determines how the + * bucket should be freed. + */ typedef unsigned int pm_constant_pool_bucket_type_t; -// By default, each constant is a slice of the source. +/** By default, each constant is a slice of the source. */ static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_DEFAULT = 0; -// An owned constant is one for which memory has been allocated. +/** An owned constant is one for which memory has been allocated. */ static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_OWNED = 1; -// A constant constant is known at compile time. +/** A constant constant is known at compile time. */ static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_CONSTANT = 2; +/** A bucket in the hash map. */ typedef struct { + /** The incremental ID used for indexing back into the pool. */ unsigned int id: 30; + + /** The type of the bucket, which determines how to free it. */ pm_constant_pool_bucket_type_t type: 2; + + /** The hash of the bucket. */ uint32_t hash; } pm_constant_pool_bucket_t; +/** A constant in the pool which effectively stores a string. */ typedef struct { + /** A pointer to the start of the string. */ const uint8_t *start; + + /** The length of the string. */ size_t length; } pm_constant_t; +/** The overall constant pool, which stores constants found while parsing. */ typedef struct { + /** The buckets in the hash map. */ pm_constant_pool_bucket_t *buckets; + + /** The constants that are stored in the buckets. */ pm_constant_t *constants; + + /** The number of buckets in the hash map. */ uint32_t size; + + /** The number of buckets that have been allocated in the hash map. */ uint32_t capacity; } pm_constant_pool_t; -// Initialize a new constant pool with a given capacity. +/** + * Initialize a new constant pool with a given capacity. + * + * @param pool The pool to initialize. + * @param capacity The initial capacity of the pool. + * @return Whether the initialization succeeded. + */ bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity); -// Return a pointer to the constant indicated by the given constant id. +/** + * Return a pointer to the constant indicated by the given constant id. + * + * @param pool The pool to get the constant from. + * @param constant_id The id of the constant to get. + * @return A pointer to the constant. + */ pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id); -// Insert a constant into a constant pool that is a slice of a source string. -// Returns the id of the constant, or 0 if any potential calls to resize fail. +/** + * Insert a constant into a constant pool that is a slice of a source string. + * Returns the id of the constant, or 0 if any potential calls to resize fail. + * + * @param pool The pool to insert the constant into. + * @param start A pointer to the start of the constant. + * @param length The length of the constant. + * @return The id of the constant. + */ pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length); -// Insert a constant into a constant pool from memory that is now owned by the -// constant pool. Returns the id of the constant, or 0 if any potential calls to -// resize fail. +/** + * Insert a constant into a constant pool from memory that is now owned by the + * constant pool. Returns the id of the constant, or 0 if any potential calls to + * resize fail. + * + * @param pool The pool to insert the constant into. + * @param start A pointer to the start of the constant. + * @param length The length of the constant. + * @return The id of the constant. + */ pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length); -// Insert a constant into a constant pool from memory that is constant. Returns -// the id of the constant, or 0 if any potential calls to resize fail. +/** + * Insert a constant into a constant pool from memory that is constant. Returns + * the id of the constant, or 0 if any potential calls to resize fail. + * + * @param pool The pool to insert the constant into. + * @param start A pointer to the start of the constant. + * @param length The length of the constant. + * @return The id of the constant. + */ pm_constant_id_t pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length); -// Free the memory associated with a constant pool. +/** + * Free the memory associated with a constant pool. + * + * @param pool The pool to free. + */ void pm_constant_pool_free(pm_constant_pool_t *pool); #endif