the language's heap doesn't grow anymore during a collection. Instead the collection throws an error to the runtime

This commit is contained in:
Francesco Cozzuto
2022-04-15 16:21:10 +02:00
parent f8fdf7d0df
commit 9f825673c3
4 changed files with 35 additions and 23 deletions
-6
View File
@@ -1,6 +0,0 @@
a = [];
i = 0;
while(i<10000):{
a[i]= "ciao mondo mmododooddododododododododododdodododododd";
i = i+1;
}
-2
View File
@@ -1,2 +0,0 @@
fun f() return 1, 2;
print((a, b) = f(), '\n');
+15 -3
View File
@@ -243,9 +243,21 @@ fun parseAny(ctx) {
tests = [ tests = [
'', '1', '10', '',
'1.@10', '1.10', '"jeje"', '1',
'[]', '[1,2,3]', ' [ ] ', ' [ 1 , 2 , 3 ]', '{}', ' { } ', '{"hoy":4}', ' { "hoy" : 4 } ']; '10',
'1.@10',
'1.10',
'"jeje"',
'[]',
'[1,2,3]',
' [ ] ',
' [ 1 , 2 , 3 ]',
'{}',
' { } ',
'{"hoy":4}',
' { "hoy" : 4 } '
];
i = 0; i = 0;
while i < count(tests): { while i < count(tests): {
+20 -12
View File
@@ -38,18 +38,20 @@
** | The collection algorithm is move-and-compact. The allocator is a | ** | The collection algorithm is move-and-compact. The allocator is a |
** | bump-pointer allocator. When the base pool of memory is filled up, | ** | bump-pointer allocator. When the base pool of memory is filled up, |
** | further allocations are forwarded to the stdlib's malloc, but are kept | ** | further allocations are forwarded to the stdlib's malloc, but are kept |
** | track of by putting them in a linked list. When the parent system decides| ** | track of by putting them in a linked list. When the language's runtime |
** | to free up some memory, a new heap is allocated and the live objects are | ** | system decides to free up some memory, a new heap is allocated and the |
** | moved to it, then the old heap is freed. The references between live | ** | live objects are moved to it, then the old heap is freed. The references |
** | objects are updated when moving them.Some objects implement destructors | ** | between live objects are updated when moving them. Some objects implement|
** | that must be called when a new heap is allocated and they're not moved | ** | destructors that must be called when a new heap is allocated and they're |
** | to it. An auxiliary list of allocated objects with destructors is stored | ** | not moved to it. An auxiliary list of allocated objects with destructors |
** | alongside the heap. When the live objects are moved and the ones to be | ** | is stored alongside the heap. When the live objects are moved and the |
** | destroyed are left in the old one, the list of objects with destructors | ** | ones to be destroyed are left in the old one, the list of objects with |
** | is iterated over and the objects in it that weren't moved are destroied | ** | destructors is iterated over and the objects in it that weren't moved are|
** | and removed from the list. This approach becomes linearly slower with | ** | destroied and removed from the list. This approach becomes linearly |
** | the number of allocated objects with destructors, but it's assumed that | ** | slower with the number of allocated objects with destructors, but it's |
** | not many of them implement them. | ** | assumed that not many of them implement them. |
** | If during a collection the new memory pool is filled up, then an error is|
** | thrown to the parent system. |
** | | ** | |
** | HOW ARE POINTERS UPDATED? | ** | HOW ARE POINTERS UPDATED? |
** | Basically, when an object is moved from the old to the new heap, the | ** | Basically, when an object is moved from the old to the new heap, the |
@@ -291,6 +293,12 @@ void *Heap_RawMalloc(Heap *heap, int size, Error *err)
if(heap->used + size > heap->size) if(heap->used + size > heap->size)
{ {
if(heap->collecting)
{
Error_Report(err, 1, "Out of heap");
return NULL;
}
OflowAlloc *oflow = malloc(sizeof(OflowAlloc) + size); OflowAlloc *oflow = malloc(sizeof(OflowAlloc) + size);
if(oflow == 0) if(oflow == 0)