Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.42 KB | None | 0 0
  1. include <stdlib.h>
  2. #include <stddef.h>
  3. #include <assert.h>
  4.  
  5. #include <webassembly.h>
  6.  
  7. typedef uint8_t u8;
  8. typedef uint32_t u32;
  9. typedef uint64_t u64;
  10. typedef int32_t i32;
  11. typedef int64_t i64;
  12. typedef float f32;
  13. typedef double f64;
  14.  
  15. // First pass at memory allocation. We work with arenas that pull memory
  16. // a page at a time. Right now just waste the ends of pages and don't allow
  17. // allocations greater than a page.
  18. //@OPTIMIZE: There's wasted memory between _heap_base to the end of the first page.
  19.  
  20. #define page_size 65536
  21.  
  22. extern void _grow();
  23.  
  24. void *allocate_page() {
  25. int page = __builtin_wasm_grow_memory(1);
  26. _grow(); // Updates the wrapper arrays so console_log works.
  27. return (uint8_t*)0 + (page * page_size);
  28. }
  29.  
  30. typedef struct PageFooter {
  31. struct PageFooter *prev;
  32. } PageFooter;
  33.  
  34. typedef struct {
  35. void *page;
  36. size_t used;
  37. } Arena;
  38.  
  39. static void* free_pages = NULL;
  40.  
  41. void *arena_push_size(Arena* arena, u32 size) {
  42. if (size > page_size - sizeof(PageFooter)) {
  43. console_error("size > maximum allocatable");
  44. }
  45. if (!arena->page || arena->used + size > page_size) {
  46. // Allocate a new page
  47. void *new_page = NULL;
  48. if (free_pages != NULL) {
  49. new_page = free_pages;
  50. free_pages = *(void**)new_page;
  51. } else {
  52. new_page = allocate_page();
  53. }
  54. PageFooter *footer = (PageFooter*)((u8*)new_page + (page_size - sizeof(PageFooter)));
  55. footer->prev = arena->page;
  56. arena->page = new_page;
  57. arena->used = 0;
  58. }
  59. if (size > (page_size - sizeof(PageFooter)) - arena->used) {
  60. console_error("No room for some reason!");
  61. }
  62. void *result = arena->page + arena->used;
  63. arena->used += size;
  64. return result;
  65. }
  66.  
  67. void arena_free(Arena* arena) {
  68. void *page = arena->page;
  69. while(page) {
  70. PageFooter *footer = (PageFooter*)((u8*)page + (page_size - sizeof(PageFooter)));
  71. *(void**)page = free_pages;
  72. free_pages = page;
  73. page = footer->prev;
  74. }
  75. arena->page = NULL;
  76. arena->used = 0;
  77. }
  78.  
  79. export void test() {
  80. console_log("Running Tests\n");
  81. Arena arena;
  82. Arena arena_two;
  83. console_log("Arena{base: %i, used: %i}", (int)arena.page, arena.used);
  84. void *mem = arena_push_size(&arena, 1024);
  85. console_log("push 1024: %i", (int)mem);
  86. console_log("Arena{base: %i, used: %i}", (int)arena.page, arena.used);
  87. mem = arena_push_size(&arena, 1024);
  88. console_log("push 1024: %i", (int)mem);
  89. console_log("Arena{base: %i, used: %i}", (int)arena.page, arena.used);
  90. console_log("free arena");
  91. arena_free(&arena);
  92. console_log("Arena{base: %i, used: %i}", (int)arena.page, arena.used);
  93. mem = arena_push_size(&arena, 1024);
  94. console_log("push 1024: %i", (int)mem);
  95. console_log("Arena{base: %i, used: %i}", (int)arena.page, arena.used);
  96. for (int i=0; i<12; i++) {
  97. mem = arena_push_size(&arena, page_size-100);
  98. console_log("push %i: %i", page_size-100, (int)mem);
  99. console_log("Arena{base: %i, used: %i}", (int)arena.page, arena.used);
  100. }
  101. console_log("Arena2{base: %i, used: %i}", (int)arena_two.page, arena_two.used);
  102. mem = arena_push_size(&arena_two, 1024);
  103. console_log("push 1024 to arena 2: %i", (int)mem);
  104. console_log("Arena2{base: %i, used: %i}", (int)arena_two.page, arena_two.used);
  105. console_log("free arena 1");
  106. arena_free(&arena);
  107. console_log("Arena{base: %i, used: %i}", (int)arena.page, arena.used);
  108. mem = arena_push_size(&arena_two, 65436);
  109. console_log("push 65436 to arena 2: %i", (int)mem);
  110. console_log("Arena2{base: %i, used: %i}", (int)arena_two.page, arena_two.used);
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement