hoshi-lang dev
Yet another programming language
Loading...
Searching...
No Matches
memory.cpp
Go to the documentation of this file.
1//
2// Created by XIaokang00010 on 2025/7/29.
3//
4
5#include <cstdio>
6#include <cstdlib>
7#include <cstring>
8
9#include <mimalloc/include/mimalloc.h>
10
12#include "memory.h"
13#include "runtime/rtti/rtti.h"
14
15#if defined(ELYSIA_RUNTIME_HPERF_ENABLE)
16#include <runtime/hperf/hperf.h>
17#endif
18
19#if defined(ELYSIA_RUNTIME_BUILD_TYPE_DEBUG) && defined(ELYSIA_RUNTIME_ENABLE_BUILTIN_MEMORY_LEAK_DETECTOR)
20extern "C" AllocatedMemoryList *allocated_memory_list = nullptr;
21
22void runtime_debug_print_current_allocated_memory() {
23 for (AllocatedMemoryList *node = allocated_memory_list; node; node = node->next) {
24 printf("[Elysia/DEBUG] | Memory of %s at %p, size: %ld bytes. target refcount: %lld.\n",
25 rtti_table[((YoiObject *)node->memory)->type_id].type_name,
26 node->memory,
27 node->size,
28 ((YoiObject *)node->memory)->gc_refcount);
29 }
30}
31#endif
32
33#if defined(ELYSIA_RUNTIME_ENABLE_BUILTIN_MEMORY_LEAK_DETECTOR)
34int64_t runtime_object_allocated = 0;
35#endif
36
37extern "C" void *runtime_object_alloc_report(size_t size, void *object) {
38 #if defined (ELYSIA_RUNTIME_HPERF_ENABLE)
39 hperf_report_mem_alloc(object, size);
40 #endif
41 #if defined(ELYSIA_RUNTIME_BUILD_TYPE_DEBUG) && defined(ELYSIA_RUNTIME_ENABLE_BUILTIN_MEMORY_LEAK_DETECTOR)
42 printf("[Elysia/DEBUG] Allocating %zu bytes memory at %p. Current object count: %lld.\n", size, object, runtime_object_allocated);
43 runtime_object_allocated ++;
44 #endif
45 #if defined(ELYSIA_RUNTIME_BUILD_TYPE_DEBUG) && defined(ELYSIA_RUNTIME_ENABLE_BUILTIN_MEMORY_LEAK_DETECTOR)
46 if (allocated_memory_list == nullptr) {
47 allocated_memory_list = static_cast<AllocatedMemoryList *>(malloc(sizeof(AllocatedMemoryList)));
48 allocated_memory_list->memory = object;
49 allocated_memory_list->size = size;
50 allocated_memory_list->prev = nullptr;
51 allocated_memory_list->next = nullptr;
52 } else {
53 auto *new_node = static_cast<AllocatedMemoryList *>(malloc(sizeof(AllocatedMemoryList)));
54 new_node->memory = object;
55 new_node->size = size;
56 new_node->prev = nullptr;
57 new_node->next = allocated_memory_list;
58 allocated_memory_list->prev = new_node;
59 allocated_memory_list = new_node;
60 }
61 #endif
62 return object;
63}
64
65extern "C" void runtime_finalize_object_report(YoiObject *object) {
66 #if defined(ELYSIA_RUNTIME_HPERF_ENABLE)
68 #endif
69 #if defined(ELYSIA_RUNTIME_BUILD_TYPE_DEBUG) && defined(ELYSIA_RUNTIME_ENABLE_BUILTIN_MEMORY_LEAK_DETECTOR)
70 printf("[Elysia/DEBUG] Finalizing %s object at %p. Current object count: %lld.\n", rtti_table[object->type_id].type_name, object, runtime_object_allocated);
71 runtime_object_allocated --;
72
73 for (AllocatedMemoryList *node = allocated_memory_list; node!= nullptr; node = node->next) {
74 if (node->memory && node->memory == object) {
75 if (node->prev != nullptr) {
76 node->prev->next = node->next;
77 } else {
78 allocated_memory_list = node->next;
79 }
80 if (node->next != nullptr) {
81 node->next->prev = node->prev;
82 }
83 free(node);
84 }
85 }
86 runtime_debug_print_current_allocated_memory();
87 #endif
88}
89
92 void *ptr = object;
93 mi_free(ptr);
94}
95
96void *runtime_object_alloc(unsigned long size) {
97 void *ptr = mi_calloc(size, 1);
99 return ptr;
100}
101
103 auto raw = reinterpret_cast<int64_t>(&array->data);
105 obj->gc_refcount = 1;
106 obj->type_id = 0;
107 obj->value = raw;
108
109 if (--array->gc_refcount == 0)
111 return obj;
112}
113
114#ifdef _WIN32
115 #include <windows.h>
116#elif defined(__linux__) || defined(__APPLE__)
117 #include <sys/mman.h>
118 #include <unistd.h>
119#endif
120
121#ifndef ELYSIA_DISABLE_MEMORY_EXECUTABLE_MAPPING_FEATURE
122
123void *runtime_exec_permit_alloc(unsigned long size) {
124 #ifdef _WIN32
125 return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
126 #elif defined(__linux__) || defined(__APPLE__)
127 // Align to 16 bytes for safe cross-platform JIT structure (metadata + alignment padding)
128 size_t header_size = 16;
129 size_t real_size = size + header_size;
130
131 int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
132 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
133
134 #if defined(__APPLE__) && defined(__aarch64__)
135 flags |= MAP_JIT;
136 #endif
137
138 void *ptr = mmap(NULL, real_size, prot, flags, -1, 0);
139
140 if (ptr == MAP_FAILED) {
141 return nullptr;
142 }
143
144 // Store the allocated size at the beginning
145 *reinterpret_cast<size_t*>(ptr) = real_size;
146
147 // Return pointer offset by header_size
148 return static_cast<char*>(ptr) + header_size;
149 #else
150 return nullptr;
151 #endif
152}
153
155 if (!ptr) return;
156
157 #ifdef _WIN32
158 VirtualFree(ptr, 0, MEM_RELEASE);
159 #elif defined(__linux__) || defined(__APPLE__)
160 size_t header_size = 16;
161 char *real_ptr = static_cast<char*>(ptr) - header_size;
162 size_t real_size = *reinterpret_cast<size_t*>(real_ptr);
163
164 munmap(real_ptr, real_size);
165 #endif
166}
167
168#endif
void hperf_report_mem_free(void *ptr)
Definition hperf.cpp:107
void hperf_report_mem_alloc(void *ptr, size_t size)
Definition hperf.cpp:95
YoiIntegerObject * runtime_get_string_array_data_pointer(YoiObjectArray *array)
Definition memory.cpp:102
void * runtime_object_alloc(unsigned long size)
Definition memory.cpp:96
void runtime_finalize_object_report(YoiObject *object)
Definition memory.cpp:65
void runtime_exec_permit_free(void *ptr)
Definition memory.cpp:154
void runtime_finalize_object(YoiObject *object)
Definition memory.cpp:90
void * runtime_exec_permit_alloc(unsigned long size)
Definition memory.cpp:123
void * runtime_object_alloc_report(size_t size, void *object)
Definition memory.cpp:37
YoiTypeInfo rtti_table[]
Definition rtti.h:56
unsigned long size
Definition memory.h:71
AllocatedMemoryList * prev
Definition memory.h:68
AllocatedMemoryList * next
Definition memory.h:69
unsigned long long gc_refcount
Definition memory.h:26
unsigned long long gc_refcount
Definition memory.h:19
void * data
Definition memory.h:22
unsigned long long type_id
Definition memory.h:15
const char * type_name
Definition rtti.h:38