Skip to content

Commit ee8fdf9

Browse files
committed
Use AtomIndex for atomshashtable and for searching module functions
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent 1196c17 commit ee8fdf9

File tree

6 files changed

+60
-77
lines changed

6 files changed

+60
-77
lines changed

src/libAtomVM/atomshashtable.c

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,10 @@
4141
struct HNode
4242
{
4343
struct HNode *next;
44-
AtomString key;
44+
AtomIndex key;
4545
unsigned long value;
4646
};
4747

48-
static unsigned long sdbm_hash(const unsigned char *str, int len)
49-
{
50-
unsigned long hash = 0;
51-
int c;
52-
53-
for (int i = 0; i < len; i++) {
54-
c = *str++;
55-
hash = c + (hash << 6) + (hash << 16) - hash;
56-
}
57-
58-
return hash;
59-
}
60-
6148
struct AtomsHashTable *atomshashtable_new()
6249
{
6350
struct AtomsHashTable *htable = malloc(sizeof(struct AtomsHashTable));
@@ -80,18 +67,15 @@ struct AtomsHashTable *atomshashtable_new()
8067
return htable;
8168
}
8269

83-
int atomshashtable_insert(struct AtomsHashTable *hash_table, AtomString string, unsigned long value)
70+
int atomshashtable_insert(struct AtomsHashTable *hash_table, AtomIndex key, unsigned long value)
8471
{
85-
int alen = atom_string_len(string);
86-
87-
unsigned long hash = sdbm_hash(string, alen);
8872
SMP_WRLOCK(hash_table);
89-
long index = hash % hash_table->capacity;
73+
long index = key % hash_table->capacity;
9074

9175
struct HNode *node = hash_table->buckets[index];
9276
if (node) {
9377
while (1) {
94-
if (atom_are_equals(string, node->key)) {
78+
if (key == node->key) {
9579
node->value = value;
9680
SMP_UNLOCK(hash_table);
9781
return 1;
@@ -111,7 +95,7 @@ int atomshashtable_insert(struct AtomsHashTable *hash_table, AtomString string,
11195
return 0;
11296
}
11397
new_node->next = NULL;
114-
new_node->key = string;
98+
new_node->key = key;
11599
new_node->value = value;
116100

117101
if (node) {
@@ -125,15 +109,14 @@ int atomshashtable_insert(struct AtomsHashTable *hash_table, AtomString string,
125109
return 1;
126110
}
127111

128-
unsigned long atomshashtable_get_value(const struct AtomsHashTable *hash_table, const AtomString string, unsigned long default_value)
112+
unsigned long atomshashtable_get_value(const struct AtomsHashTable *hash_table, AtomIndex key, unsigned long default_value)
129113
{
130-
unsigned long hash = sdbm_hash(string, atom_string_len(string));
131114
SMP_RDLOCK(hash_table);
132-
long index = hash % hash_table->capacity;
115+
long index = key % hash_table->capacity;
133116

134117
const struct HNode *node = hash_table->buckets[index];
135118
while (node) {
136-
if (atom_are_equals(string, node->key)) {
119+
if (key == node->key) {
137120
unsigned long result = node->value;
138121
SMP_UNLOCK(hash_table);
139122
return result;
@@ -146,15 +129,14 @@ unsigned long atomshashtable_get_value(const struct AtomsHashTable *hash_table,
146129
return default_value;
147130
}
148131

149-
int atomshashtable_has_key(const struct AtomsHashTable *hash_table, const AtomString string)
132+
int atomshashtable_has_key(const struct AtomsHashTable *hash_table, AtomIndex key)
150133
{
151-
unsigned long hash = sdbm_hash(string, atom_string_len(string));
152134
SMP_RDLOCK(hash_table);
153-
long index = hash % hash_table->capacity;
135+
long index = key % hash_table->capacity;
154136

155137
const struct HNode *node = hash_table->buckets[index];
156138
while (node) {
157-
if (atom_are_equals(string, node->key)) {
139+
if (key == node->key) {
158140
SMP_UNLOCK(hash_table);
159141
return 1;
160142
}

src/libAtomVM/atomshashtable.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ struct AtomsHashTable
4545
};
4646

4747
struct AtomsHashTable *atomshashtable_new();
48-
int atomshashtable_insert(struct AtomsHashTable *hash_table, AtomString string, unsigned long value);
49-
unsigned long atomshashtable_get_value(const struct AtomsHashTable *hash_table, AtomString string, unsigned long default_value);
50-
int atomshashtable_has_key(const struct AtomsHashTable *hash_table, AtomString string);
48+
int atomshashtable_insert(struct AtomsHashTable *hash_table, AtomIndex atom_index, unsigned long value);
49+
unsigned long atomshashtable_get_value(const struct AtomsHashTable *hash_table, AtomIndex atom_index, unsigned long default_value);
50+
int atomshashtable_has_key(const struct AtomsHashTable *hash_table, AtomIndex atom_index);
5151

5252
#define TO_ATOMSHASHTABLE_VALUE(value) ((unsigned long) (value))
5353

src/libAtomVM/globalcontext.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ term globalcontext_get_registered_name_process(GlobalContext *glb, int local_pro
568568
return term_invalid_term();
569569
}
570570

571-
bool globalcontext_is_atom_index_equal_to_atom_string(GlobalContext *glb, int atom_index_a, AtomString atom_string_b)
571+
bool globalcontext_is_atom_index_equal_to_atom_string(GlobalContext *glb, AtomIndex atom_index_a, AtomString atom_string_b)
572572
{
573573
AtomString atom_string_a;
574574
atom_string_a = atom_table_get_atom_string(glb->atom_table, atom_index_a);
@@ -590,7 +590,7 @@ AtomString globalcontext_atomstring_from_term(GlobalContext *glb, term t)
590590

591591
term globalcontext_existing_term_from_atom_string(GlobalContext *glb, AtomString atom_string)
592592
{
593-
long atom_index = atom_table_get_index(glb->atom_table, atom_string);
593+
AtomIndex atom_index = atom_table_get_index(glb->atom_table, atom_string);
594594
if (UNLIKELY(atom_index == ATOM_TABLE_NOT_FOUND)) {
595595
return term_invalid_term();
596596
}
@@ -599,9 +599,9 @@ term globalcontext_existing_term_from_atom_string(GlobalContext *glb, AtomString
599599

600600
int globalcontext_insert_module(GlobalContext *global, Module *module)
601601
{
602+
term module_name = module_get_name(module);
602603
SMP_RWLOCK_WRLOCK(global->modules_lock);
603-
AtomString module_name_atom = module_get_atom_string_by_id(module, 1, global);
604-
if (!atomshashtable_insert(global->modules_table, module_name_atom, TO_ATOMSHASHTABLE_VALUE(module))) {
604+
if (!atomshashtable_insert(global->modules_table, term_to_atom_index(module_name), TO_ATOMSHASHTABLE_VALUE(module))) {
605605
SMP_RWLOCK_UNLOCK(global->modules_lock);
606606
return -1;
607607
}
@@ -657,7 +657,7 @@ Module *globalcontext_load_module_from_avm(GlobalContext *global, const char *mo
657657
return new_module;
658658
}
659659

660-
Module *globalcontext_get_module(GlobalContext *global, AtomString module_name_atom)
660+
Module *globalcontext_get_module(GlobalContext *global, AtomIndex module_name_atom)
661661
{
662662
Module *found_module = (Module *) atomshashtable_get_value(global->modules_table, module_name_atom, (unsigned long) NULL);
663663

src/libAtomVM/globalcontext.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ static inline int globalcontext_insert_atom(GlobalContext *glb, AtomString atom_
384384
* @param atom_string_b an atom string, which is the atom length followed by atom characters.
385385
* @returns true if they both refer to the same atom, otherwise false.
386386
*/
387-
bool globalcontext_is_atom_index_equal_to_atom_string(GlobalContext *glb, int atom_index_a, AtomString atom_string_b);
387+
bool globalcontext_is_atom_index_equal_to_atom_string(GlobalContext *glb, AtomIndex atom_index_a, AtomString atom_string_b);
388388

389389
/**
390390
* @brief Compares a term with an AtomString.
@@ -401,7 +401,7 @@ static inline bool globalcontext_is_term_equal_to_atom_string(GlobalContext *glo
401401
return false;
402402
}
403403

404-
int atom_index_a = term_to_atom_index(atom_a);
404+
AtomIndex atom_index_a = term_to_atom_index(atom_a);
405405
return globalcontext_is_atom_index_equal_to_atom_string(global, atom_index_a, atom_string_b);
406406
}
407407

@@ -476,7 +476,7 @@ Module *globalcontext_get_module_by_index(GlobalContext *global, int index);
476476
* @param module_name_atom the module name.
477477
* @returns a pointer to a Module struct.
478478
*/
479-
Module *globalcontext_get_module(GlobalContext *global, AtomString module_name_atom);
479+
Module *globalcontext_get_module(GlobalContext *global, AtomIndex module_name_atom);
480480

481481
/**
482482
* @brief Load a given module from registered AVM packs

src/libAtomVM/opcodesswitch.h

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,8 +1177,8 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
11771177
if (term_is_atom(index_or_function)) { \
11781178
term module = boxed_value[1]; \
11791179
fun_arity = term_to_int(boxed_value[3]); \
1180-
AtomString module_name = globalcontext_atomstring_from_term(glb, module); \
1181-
AtomString function_name = globalcontext_atomstring_from_term(glb, index_or_function); \
1180+
AtomIndex module_name = term_to_atom_index(module); \
1181+
AtomIndex function_name = term_to_atom_index(index_or_function); \
11821182
term return_value; \
11831183
if (maybe_call_native(ctx, module_name, function_name, fun_arity, &return_value)) { \
11841184
PROCESS_MAYBE_TRAP_RETURN_VALUE(return_value); \
@@ -1195,7 +1195,7 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
11951195
SET_ERROR(UNDEF_ATOM); \
11961196
HANDLE_ERROR(); \
11971197
} \
1198-
label = module_search_exported_function(fun_module, function_name, fun_arity, glb); \
1198+
label = module_search_exported_function(fun_module, function_name, fun_arity); \
11991199
if (UNLIKELY(label == 0)) { \
12001200
SET_ERROR(UNDEF_ATOM); \
12011201
HANDLE_ERROR(); \
@@ -1603,10 +1603,12 @@ term make_fun(Context *ctx, const Module *mod, int fun_index, term argv[])
16031603
return ((term) boxed_func) | TERM_BOXED_VALUE_TAG;
16041604
}
16051605

1606-
static bool maybe_call_native(Context *ctx, AtomString module_name, AtomString function_name, int arity,
1606+
static bool maybe_call_native(Context *ctx, AtomIndex module_name, AtomIndex function_name, int arity,
16071607
term *return_value)
16081608
{
1609-
const struct ExportedFunction *exported_bif = bif_registry_get_handler(module_name, function_name, arity);
1609+
char mfa[MAX_MFA_NAME_LEN];
1610+
atom_table_write_mfa(ctx->global->atom_table, mfa, sizeof(mfa), module_name, function_name, arity);
1611+
const struct ExportedFunction *exported_bif = bif_registry_get_handler(mfa);
16101612
if (exported_bif) {
16111613
if (exported_bif->type == GCBIFFunctionType) {
16121614
const struct GCBif *gcbif = EXPORTED_FUNCTION_TO_GCBIF(exported_bif);
@@ -1643,7 +1645,7 @@ static bool maybe_call_native(Context *ctx, AtomString module_name, AtomString f
16431645
}
16441646
}
16451647

1646-
struct Nif *nif = (struct Nif *) nifs_get(module_name, function_name, arity);
1648+
struct Nif *nif = (struct Nif *) nifs_get(mfa);
16471649
if (nif) {
16481650
*return_value = nif->nif_ptr(ctx, arity, ctx->x);
16491651
return true;
@@ -1778,14 +1780,13 @@ static bool maybe_call_native(Context *ctx, AtomString module_name, AtomString f
17781780
#ifdef IMPL_EXECUTE_LOOP
17791781
TRACE("-- Executing code\n");
17801782

1781-
int function_len = strlen(function_name);
1782-
uint8_t *tmp_atom_name = malloc(function_len + 1);
1783-
tmp_atom_name[0] = function_len;
1784-
memcpy(tmp_atom_name + 1, function_name, function_len);
1785-
1786-
int label = module_search_exported_function(mod, tmp_atom_name, arity, ctx->global);
1787-
free(tmp_atom_name);
1783+
AtomIndex function_name_index = atom_table_get_index_from_cstring(ctx->global->atom_table, function_name);
1784+
if (UNLIKELY(function_name_index == ATOM_TABLE_NOT_FOUND)) {
1785+
fprintf(stderr, "No %s/%i function found.\n", function_name, arity);
1786+
return 0;
1787+
}
17881788

1789+
int label = module_search_exported_function(mod, function_name_index, arity);
17891790
if (UNLIKELY(!label)) {
17901791
fprintf(stderr, "No %s/%i function found.\n", function_name, arity);
17911792
return 0;
@@ -5322,8 +5323,8 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
53225323
RAISE_ERROR(BADARG_ATOM);
53235324
}
53245325

5325-
AtomString module_name = globalcontext_atomstring_from_term(glb, module);
5326-
AtomString function_name = globalcontext_atomstring_from_term(glb, function);
5326+
AtomIndex module_name = term_to_atom_index(module);
5327+
AtomIndex function_name = term_to_atom_index(function);
53275328

53285329
TRACE_APPLY(ctx, "apply", module_name, function_name, arity);
53295330

@@ -5339,7 +5340,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
53395340
SET_ERROR(UNDEF_ATOM);
53405341
HANDLE_ERROR();
53415342
}
5342-
int target_label = module_search_exported_function(target_module, function_name, arity, glb);
5343+
int target_label = module_search_exported_function(target_module, function_name, arity);
53435344
if (target_label == 0) {
53445345
pc = orig_pc;
53455346
SET_ERROR(UNDEF_ATOM);
@@ -5380,8 +5381,8 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
53805381
RAISE_ERROR(BADARG_ATOM);
53815382
}
53825383

5383-
AtomString module_name = globalcontext_atomstring_from_term(glb, module);
5384-
AtomString function_name = globalcontext_atomstring_from_term(glb, function);
5384+
AtomIndex module_name = term_to_atom_index(module);
5385+
AtomIndex function_name = term_to_atom_index(function);
53855386

53865387
TRACE_APPLY(ctx, "apply_last", module_name, function_name, arity);
53875388

@@ -5397,7 +5398,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
53975398
SET_ERROR(UNDEF_ATOM);
53985399
HANDLE_ERROR();
53995400
}
5400-
int target_label = module_search_exported_function(target_module, function_name, arity, glb);
5401+
int target_label = module_search_exported_function(target_module, function_name, arity);
54015402
if (target_label == 0) {
54025403
SET_ERROR(UNDEF_ATOM);
54035404
HANDLE_ERROR();

tests/test-structs.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -162,24 +162,24 @@ static const char *const fibonacci_atom = "\x9" "fibonacci";
162162

163163
void test_atomshashtable()
164164
{
165-
char atom_hello[] = {5, 'h', 'e', 'l', 'l', 'o'};
166-
char atom_ciao[] = {4, 'c', 'i', 'a', 'o'};
167-
char atom_a[] = {1, 'a'};
168-
char atom_b[] = {1, 'b'};
169-
char atom_c[] = {1, 'c'};
170-
char atom_d[] = {1, 'd'};
171-
char atom_e[] = {1, 'e'};
172-
char atom_f[] = {1, 'f'};
173-
char atom_0[] = {1, '0'};
174-
char atom_1[] = {1, '1'};
175-
char atom_2[] = {1, '2'};
176-
char atom_3[] = {1, '3'};
177-
char atom_4[] = {1, '4'};
178-
char atom_5[] = {1, '5'};
179-
char atom_6[] = {1, '6'};
180-
char atom_7[] = {1, '7'};
181-
char atom_8[] = {1, '8'};
182-
char atom_9[] = {1, '9'};
165+
AtomIndex atom_hello = 42;
166+
AtomIndex atom_ciao = 43;
167+
AtomIndex atom_a = 65;
168+
AtomIndex atom_b = 66;
169+
AtomIndex atom_c = 67;
170+
AtomIndex atom_d = 68;
171+
AtomIndex atom_e = 69;
172+
AtomIndex atom_f = 70;
173+
AtomIndex atom_0 = 48;
174+
AtomIndex atom_1 = 49;
175+
AtomIndex atom_2 = 50;
176+
AtomIndex atom_3 = 51;
177+
AtomIndex atom_4 = 52;
178+
AtomIndex atom_5 = 53;
179+
AtomIndex atom_6 = 54;
180+
AtomIndex atom_7 = 55;
181+
AtomIndex atom_8 = 56;
182+
AtomIndex atom_9 = 57;
183183

184184
struct AtomsHashTable *htable = atomshashtable_new();
185185

0 commit comments

Comments
 (0)