increased stack size; added array.copy; change arena allocator
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 22 Dec 2020 16:27:42 +0000 (10:27 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 22 Dec 2020 16:27:42 +0000 (10:27 -0600)
core/alloc/arena.onyx
core/array.onyx
onyx
src/onyxwasm.c
tests/general1

index 051e705ce0b475f7bd175e186e0a98081079f100..93ac331755e546d77482c723c1bbc3cd5a8ec279 100644 (file)
@@ -1,45 +1,72 @@
 package core.alloc.arena
 
-// This allocator is great for when you need to do bunch of
-// allocations is a small amount of time. Much like the Ring
-// allocator, it simply bumps up a pointer as you allocate
-// memory. Unlike the Ring allocator, it does not wrap around,
-// meaning you can run of out of memory, so make sure the buffer
-// provided has enough space for what you are going to do.
+// This allocator is mostly used for making many fixed-size
+// allocation (i.e. allocations that will not need to change
+// in size, such as game entities or position structs). The
+// power of this allocator over the heap allocator for this
+// purpose is that it is much faster, since the logic is
+// simpler. Another power of this allocator over something
+// such as a dynamic array is that the dynamic array could
+// relocate and cause any pointers to the data inside to
+// become invalidated; this is definitely not behaviour you
+// want. This arena allocator can grow as large as needed,
+// while guaranteeing that the memory inside of it will
+// never move.
 
 ArenaState :: struct {
-    base_ptr : rawptr;
-    size     : u32;
-    curr_ptr : rawptr;
+    backing_allocator : Allocator;
+
+    first_arena   : ^Arena;
+    current_arena : ^Arena;
+    
+    size       : u32;
+    arena_size : u32;
 }
 
+Arena :: struct { next : ^Arena; }
+
 #private_file
 arena_alloc_proc :: proc (data: rawptr, aa: AllocationAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {
-    ss := cast(^ArenaState) data;
+    alloc_arena := cast(^ArenaState) data;
 
     if aa == AllocationAction.Alloc {
-        retval := null;
-        rem := ss.size - cast(u32) ss.curr_ptr + cast(u32) ss.base_ptr;
-
-        if size <= rem {
-            retval = ss.curr_ptr;
-            ss.curr_ptr = cast(rawptr) (cast(u32) ss.curr_ptr + size);
-        } else {
-            // Not enough space for the allocation
-            retval = null;
+        // NOTE: An allocation of this size does not fit into a single arena.
+        if size > alloc_arena.arena_size - sizeof rawptr {
+            return null;
+        }
+
+        if alloc_arena.size + size >= alloc_arena.arena_size {
+            new_arena := cast(^Arena) raw_alloc(alloc_arena.backing_allocator, alloc_arena.arena_size);
+            if new_arena == null do return null;
+
+            alloc_arena.size = sizeof rawptr;
+
+            new_arena.next = null;
+            alloc_arena.current_arena.next = new_arena;
+            alloc_arena.current_arena = new_arena;
         }
 
+        retval := cast(rawptr) (cast(^u8) alloc_arena.current_arena + alloc_arena.size);
+        alloc_arena.size += size;
+
         return retval;
     }
 
     return null;
 }
 
-make :: proc (buffer: rawptr, length: u32) -> ArenaState {
+// NOTE: `arena_size` must be at least 4
+make :: proc (backing: Allocator, arena_size: u32) -> ArenaState {
+    initial_arena := cast(^Arena) raw_alloc(backing, arena_size);
+    initial_arena.next = null;
+
     return ArenaState.{
-        base_ptr = buffer,
-        curr_ptr = buffer,
-        size     = length,
+        backing_allocator = backing,
+        first_arena       = initial_arena,
+        current_arena     = initial_arena,
+
+        size              = sizeof rawptr,
+        arena_size        = arena_size,
     };
 }
 
@@ -50,6 +77,16 @@ make_allocator :: proc (rs: ^ArenaState) -> Allocator {
     };
 }
 
-reset :: proc (arena: ^ArenaState) {
-    arena.curr_ptr = arena.base_ptr;
-}
\ No newline at end of file
+free :: proc (arena: ^ArenaState) {
+    walker := arena.first_arena;
+    trailer := walker;
+    while walker != null {
+        walker = walker.next;
+        raw_free(arena.backing_allocator, trailer);
+        trailer = walker;
+    }
+
+    arena.first_arena   = null;
+    arena.current_arena = null;
+    arena.size          = 0;
+}
index 16508474e98b5acc2241996f51dcc7deeddf2f0e..0cd4978ce7c2a3d5cf03b171c977dfb76a24a6a7 100644 (file)
@@ -17,6 +17,24 @@ free :: proc (arr: ^[..] $T) {
     arr.data = null;
 }
 
+copy :: proc (arr: ^[..] $T) -> [..] T {
+    new_arr : [..] T;
+    init(^new_arr, arr.count);
+    new_arr.count = arr.count;
+
+    for i: 0 .. arr.count do new_arr.data[i] = arr.data[i];
+    return new_arr;
+}
+
+copy_range :: proc (arr: ^[..] $T, r: range) -> [..] T {
+    new_arr : [..] T;
+    init(^new_arr, r.high - r.low);
+    new_arr.count = r.high - r.low;
+
+    for i: r do new_arr.data[i] = arr.data[i];
+    return new_arr;
+}
+
 clear :: proc (arr: ^[..] $T) {
     arr.count = 0;
 }
diff --git a/onyx b/onyx
index f45df9c9b494527408c6ab1da2d9c4538321941d..4aec08301c0788ed0ef587d5d841aef10c7bf695 100755 (executable)
Binary files a/onyx and b/onyx differ
index a8773361a0227147f9d02da4b19247d710fb1585..000e8f27e0e9ddf6b19ed6a13f3d3ae4cec7cc4f 100644 (file)
@@ -3222,7 +3222,7 @@ void emit_entity(Entity* ent) {
             *module->stack_top_ptr += 16 - (*module->stack_top_ptr % 16);
         }
 
-        builtin_heap_start.value.i = *module->stack_top_ptr + (1 << 16);
+        builtin_heap_start.value.i = *module->stack_top_ptr + (1 << 20);
         if (builtin_heap_start.value.i % 16 != 0) {
             builtin_heap_start.value.i += 16 - (builtin_heap_start.value.i % 16);
         }
index f3a8fd367ef699eae3f542ca2a8553016b66b716..557de1eed58ad27703213fedb1dbc3ad677435e4 100644 (file)
@@ -21,7 +21,7 @@ Evens from 6 to 34:
 Array details:
        Size: 0
        Capacity: 4
-       Data ptr: 0x11A68
+       Data ptr: 0x101A68
        Size of elements: 4
        Alignment of elements: 4
 
@@ -29,7 +29,7 @@ Array details:
 Array details:
        Size: 0
        Capacity: 4
-       Data ptr: 0x11A88
+       Data ptr: 0x101A88
        Size of elements: 8
        Alignment of elements: 8
 
@@ -37,7 +37,7 @@ Array details:
 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12 17 1 6 11 16 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12 17 1 6 11 16 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12 17 1 6 11 16 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12 17 1 6 11 16 0 5 10 15 20 4 9 14 19 3 8 13 18 2 7 12
 A has 22? false
 Vec3(0, 0, 0) Vec3(1, 1, 1) Vec3(2, 4, 8) Vec3(3, 9, 27) Vec3(4, 16, 64) Vec3(5, 25, 125) Vec3(6, 36, 216) Vec3(7, 49, 343) Vec3(8, 64, 512) Vec3(9, 81, 729) Vec3(10, 100, 1000) Vec3(11, 121, 1331) Vec3(12, 144, 1728) Vec3(13, 169, 2197) Vec3(14, 196, 2744) Vec3(15, 225, 3375) Vec3(16, 256, 4096) Vec3(17, 289, 4913) Vec3(18, 324, 5832) Vec3(19, 361, 6859) Vec3(20, 400, 8000) Vec3(21, 441, 9261) Vec3(22, 484, 10648) Vec3(23, 529, 12167) Vec3(24, 576, 13824) Vec3(25, 625, 15625) Vec3(26, 676, 17576) Vec3(27, 729, 19683) Vec3(28, 784, 21952) Vec3(29, 841, 24389) Vec3(30, 900, 27000) Vec3(31, 961, 29791) Vec3(32, 1024, 32768) Vec3(33, 1089, 35937) Vec3(34, 1156, 39304) Vec3(35, 1225, 42875) Vec3(36, 1296, 46656) Vec3(37, 1369, 50653) Vec3(38, 1444, 54872) Vec3(39, 1521, 59319) Vec3(40, 1600, 64000) Vec3(41, 1681, 68921) Vec3(42, 1764, 74088) Vec3(43, 1849, 79507) Vec3(44, 1936, 85184) Vec3(45, 2025, 91125) Vec3(46, 2116, 97336) Vec3(47, 2209, 103823) Vec3(48, 2304, 110592) Vec3(49, 2401, 117649) Vec3(50, 2500, 125000) Vec3(51, 2601, 132651) Vec3(52, 2704, 140608) Vec3(53, 2809, 148877) Vec3(54, 2916, 157464) Vec3(55, 3025, 166375) Vec3(56, 3136, 175616) Vec3(57, 3249, 185193) Vec3(58, 3364, 195112) Vec3(59, 3481, 205379) Vec3(60, 3600, 216000) Vec3(61, 3721, 226981) Vec3(62, 3844, 238328) Vec3(63, 3969, 250047) Vec3(64, 4096, 262144) Vec3(65, 4225, 274625) Vec3(66, 4356, 287496) Vec3(67, 4489, 300763) Vec3(68, 4624, 314432) Vec3(69, 4761, 328509) Vec3(70, 4900, 343000) Vec3(71, 5041, 357911) Vec3(72, 5184, 373248) Vec3(73, 5329, 389017) Vec3(74, 5476, 405224) Vec3(75, 5625, 421875) Vec3(76, 5776, 438976) Vec3(77, 5929, 456533) Vec3(78, 6084, 474552) Vec3(79, 6241, 493039) Vec3(80, 6400, 512000) Vec3(81, 6561, 531441) Vec3(82, 6724, 551368) Vec3(83, 6889, 571787) Vec3(84, 7056, 592704) Vec3(85, 7225, 614125) Vec3(86, 7396, 636056) Vec3(87, 7569, 658503) Vec3(88, 7744, 681472) Vec3(89, 7921, 704969) Vec3(90, 8100, 729000) Vec3(91, 8281, 753571) Vec3(92, 8464, 778688) Vec3(93, 8649, 804357) Vec3(94, 8836, 830584) Vec3(95, 9025, 857375) Vec3(96, 9216, 884736) Vec3(97, 9409, 912673) Vec3(98, 9604, 941192) Vec3(99, 9801, 970299) 
-0x12D18 0x12D24 0x12D30 0x12D3C 0x12D48 0x12D54 0x12D60 0x12D6C 0x12D78 0x12D84 0x12D90 0x12D9C 0x12DA8 0x12DB4 0x12DC0 0x12DCC 0x12DD8 0x12DE4 0x12DF0 0x12DFC 0x12E08 0x12E14 0x12E20 0x12E2C 0x12E38 0x12E44 0x12E50 0x12E5C 0x12E68 0x12E74 0x12E80 0x12E8C 0x12E98 0x12EA4 0x12EB0 0x12EBC 0x12EC8 0x12ED4 0x12EE0 0x12EEC 0x12EF8 0x12F04 0x12F10 0x12F1C 0x12F28 0x12F34 0x12F40 0x12F4C 0x12F58 0x12F64 0x12F70 0x12F7C 0x12F88 0x12F94 0x12FA0 0x12FAC 0x12FB8 0x12FC4 0x12FD0 0x12FDC 0x12FE8 0x12FF4 0x13000 0x1300C 0x13018 0x13024 0x13030 0x1303C 0x13048 0x13054 0x13060 0x1306C 0x13078 0x13084 0x13090 0x1309C 0x130A8 0x130B4 0x130C0 0x130CC 0x130D8 0x130E4 0x130F0 0x130FC 0x13108 0x13114 0x13120 0x1312C 0x13138 0x13144 0x13150 0x1315C 0x13168 0x13174 0x13180 0x1318C 0x13198 0x131A4 0x131B0 0x131BC 
+0x102D18 0x102D24 0x102D30 0x102D3C 0x102D48 0x102D54 0x102D60 0x102D6C 0x102D78 0x102D84 0x102D90 0x102D9C 0x102DA8 0x102DB4 0x102DC0 0x102DCC 0x102DD8 0x102DE4 0x102DF0 0x102DFC 0x102E08 0x102E14 0x102E20 0x102E2C 0x102E38 0x102E44 0x102E50 0x102E5C 0x102E68 0x102E74 0x102E80 0x102E8C 0x102E98 0x102EA4 0x102EB0 0x102EBC 0x102EC8 0x102ED4 0x102EE0 0x102EEC 0x102EF8 0x102F04 0x102F10 0x102F1C 0x102F28 0x102F34 0x102F40 0x102F4C 0x102F58 0x102F64 0x102F70 0x102F7C 0x102F88 0x102F94 0x102FA0 0x102FAC 0x102FB8 0x102FC4 0x102FD0 0x102FDC 0x102FE8 0x102FF4 0x103000 0x10300C 0x103018 0x103024 0x103030 0x10303C 0x103048 0x103054 0x103060 0x10306C 0x103078 0x103084 0x103090 0x10309C 0x1030A8 0x1030B4 0x1030C0 0x1030CC 0x1030D8 0x1030E4 0x1030F0 0x1030FC 0x103108 0x103114 0x103120 0x10312C 0x103138 0x103144 0x103150 0x10315C 0x103168 0x103174 0x103180 0x10318C 0x103198 0x1031A4 0x1031B0 0x1031BC 
 1886 1890 1894 1898 1902 1906 1910 1914 1918 1922 1926 1930 
 20 20 20 20 20 19 19 19 19 19 18 18 18 18 18 17 17 17 17 16 16 16 16 15 15 15 15 15 14 14 14 14 14 13 13 13 13 13 12 12 12 12 12 11 11 11 11 10 10 10 10 10 9 9 9 9 9 8 8 8 8 8 7 7 7 7 7 6 6 6 6 5 5 5 5 5 4 4 4 4 4 3 3 3 3 3 2 2 2 2 2 1 1 1 1 0 0 0 0 0
 297 294 291 288 285 282 279 276 273 270 267 264 261 258 255 252 249 246 243 240 237 234 231 228 225 222 219 216 213 210 207 204 201 198 195 192 189 186 183 180 177 174 171 168 165 162 159 156 153 150 147 144 141 138 135 132 129 126 123 120 117 114 111 108 105 102 99 96 93 90 87 84 81 78 75 72 69 66 63 60 57 54 51 48 45 42 39 36 33 30 27 24 21 18 15 12 9 6 3 0
@@ -46,7 +46,7 @@ After adding...
 Array details:
        Size: 100
        Capacity: 128
-       Data ptr: 0x126F8
+       Data ptr: 0x1026F8
        Size of elements: 4
        Alignment of elements: 4
 
@@ -54,7 +54,7 @@ Array details:
 Array details:
        Size: 100
        Capacity: 128
-       Data ptr: 0x12908
+       Data ptr: 0x102908
        Size of elements: 8
        Alignment of elements: 8
 
@@ -62,7 +62,7 @@ Array A sum: 999
 
 Has ^a[20]? true
 Has null? false
-Value at ^a[50]: 0x12A98 == 0x12A98
+Value at ^a[50]: 0x102A98 == 0x102A98
 Deleteing ^a[20]
 Has ^a[20]? false
 Clearing SOA...