-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory relocation #36
base: main
Are you sure you want to change the base?
Conversation
…o-runner-and-initialization
…o-runner-and-initialization
c09c7cd
to
89e966d
Compare
Start with nested for loops that iterate over segments and cells.
89e966d
to
2674e1b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides the individual comments, I left a few other missing NULL
checks in the output parameters of hash table and array accesses without comment, as it's generalized and I was spamming too much already.
void runner_get_segment_sizes(cairo_runner *runner, CC_Array *segment_sizes) { | ||
int num_segments = runner->vm.memory.num_segments; | ||
unsigned int *zero; | ||
for (int i = 0; i < num_segments; i++) { | ||
zero = malloc(sizeof(unsigned int)); | ||
*zero = 0; | ||
cc_array_add(segment_sizes, zero); | ||
} | ||
|
||
unsigned int *new_size; | ||
CC_HashTableIter memory_iter; | ||
cc_hashtable_iter_init(&memory_iter, runner->vm.memory.data); | ||
TableEntry *entry; | ||
while (cc_hashtable_iter_next(&memory_iter, &entry) != CC_ITER_END) { | ||
relocatable *ptr = entry->key; | ||
unsigned int *segment_size; | ||
assert(cc_array_get_at(segment_sizes, ptr->segment_index, (void **)&segment_size) == CC_OK); | ||
|
||
if (*segment_size < ptr->offset + 1) { | ||
new_size = malloc(sizeof(unsigned int)); | ||
*new_size = ptr->offset + 1; | ||
cc_array_replace_at(segment_sizes, new_size, ptr->segment_index, NULL); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few issues and suggestions with this function.
- Suggestion: store values instead of pointer, as it simplifies memory management and avoids any chance of leaks. The array doesn't dereference the pointers and the value fits in the pointer size, so you can convert the values to
uintptr_t
and thenvoid *
. Document it appropriately. - Issue: the call to
cc_array_replace_at
is leaking the old value. With suggestion 1 this automatically gets fixed. - Suggestion:
cc_array_get_at
already gives you the pointer to the value and doesn't remove it, so if you choose to keep the heap allocated values you can overwrite the value pointer by it instead, also fixing the leaks. - Issue: you're not checking for
NULL
forsegment_size
before dereferencing it. If it's the first inserted value then you hit undefined behavior. You should check forNULL
and store unconditionally in that case, since it's the first value you see for that segment.
// Fills relocation table with the first relocated address of each memory segment | ||
// Warning: Can fail if runner_initialize_main_entrypoint is not called before | ||
void runner_fill_relocation_table(cairo_runner *runner, CC_Array *segment_sizes) { | ||
int *first_addr = malloc(sizeof(int)); | ||
*first_addr = 1; | ||
cc_array_add(runner->relocation_table, first_addr); | ||
int *last_segment_size_added; | ||
assert(cc_array_get_at(runner->relocation_table, 0, (void **)&last_segment_size_added) == CC_OK); | ||
|
||
int relocation_table_size = runner->vm.memory.num_segments + 1; | ||
for (int i = 1; i < relocation_table_size; i++) { | ||
int segment_idx = i - 1; | ||
int *segment_size; | ||
assert(cc_array_get_at(segment_sizes, segment_idx, (void **)&segment_size) == CC_OK); | ||
int *address = malloc(sizeof(int)); | ||
*address = *last_segment_size_added + *segment_size; | ||
cc_array_add(runner->relocation_table, address); | ||
assert(cc_array_get_at(runner->relocation_table, i, (void **)&last_segment_size_added) == CC_OK); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another batch of suggestions:
- Suggestion: rather than warn about possible errors in a comment, it may be a good idea to return an error instead.
- Suggestion: use values instead of heap pointers, as mentioned in the other comment.
- Issue: not checking
segment_size
forNULL
. - Suggestion: no need to check insertion with
cc_array_get_at
, you can check the output ofcc_array_add
instead.
int runner_get_relocated_address(cairo_runner *runner, relocatable *relocatable) { | ||
int *address; | ||
assert(cc_array_get_at(runner->relocation_table, relocatable->segment_index, (void **)&address) == CC_OK); | ||
return *address + relocatable->offset; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: not checking address
for NULL
.
return *address + relocatable->offset; | ||
} | ||
|
||
void runner_get_relocated_value(cairo_runner *runner, maybe_relocatable *value, felt_t out) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're modifying out
, shouldn't it be a pointer so the caller sees the changes? Ignore this if felt_t
is already defined to be a pointer.
|
||
for (int i = 0; i < num_segment_sizes; i++) { | ||
int *segment_size; | ||
assert(cc_array_get_at(segment_sizes, i, (void **)&segment_size) == CC_OK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: not checking segment_size
for NULL
.
for (int j = 0; j < *segment_size; j++) { | ||
relocatable ptr = {i, j}; | ||
maybe_relocatable *cell; | ||
if (cc_hashtable_get(runner->vm.memory.data, &ptr, (void **)&cell) == CC_OK) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for cell
.
src/memory.c
Outdated
if (cell->is_some) { | ||
ResultMemory ok = {.is_error = false, .value = {.memory_value = cell->memory_value.value}}; | ||
maybe_relocatable *value = NULL; | ||
if (cc_hashtable_get(mem->data, &ptr, (void *)&value) == CC_OK) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
value
could be NULL
.
NOTE: To merge this, #26 has to be merged.