|
|
|
@@ -9,18 +9,12 @@ namespace Memory { |
|
|
|
// ------------------ |
|
|
|
// lisp_objects |
|
|
|
// ------------------ |
|
|
|
int object_memory_size; |
|
|
|
Array_List<int> free_spots_in_object_memory; |
|
|
|
Lisp_Object* object_memory; |
|
|
|
int next_index_in_object_memory = 0; |
|
|
|
Bucket_Allocator<Lisp_Object, 1024> object_memory; |
|
|
|
|
|
|
|
// ------------------ |
|
|
|
// environments |
|
|
|
// ------------------ |
|
|
|
int environment_memory_size; |
|
|
|
Array_List<Environment*> free_spots_in_environment_memory; |
|
|
|
Environment* environment_memory; |
|
|
|
int next_index_in_environment_memory = 0; |
|
|
|
Bucket_Allocator<Environment, 1024> environment_memory; |
|
|
|
|
|
|
|
// ------------------ |
|
|
|
// strings |
|
|
|
@@ -40,19 +34,19 @@ namespace Memory { |
|
|
|
Lisp_Object* t = nullptr; |
|
|
|
|
|
|
|
proc print_status() { |
|
|
|
printf("Memory Status:\n" |
|
|
|
" - %f%% of the object_memory is used\n" |
|
|
|
" - %d of %d total Lisp_Objects are in use\n" |
|
|
|
" - %d holes in used memory (fragmentation)\n", |
|
|
|
(1.0*next_index_in_object_memory - free_spots_in_object_memory.next_index)/object_memory_size, |
|
|
|
next_index_in_object_memory - free_spots_in_object_memory.next_index, object_memory_size, |
|
|
|
free_spots_in_object_memory.next_index); |
|
|
|
// printf("Memory Status:\n" |
|
|
|
// " - %f%% of the object_memory is used\n" |
|
|
|
// " - %d of %d total Lisp_Objects are in use\n" |
|
|
|
// " - %d holes in used memory (fragmentation)\n", |
|
|
|
// (1.0*next_index_in_object_memory - free_spots_in_object_memory.next_index)/object_memory_size, |
|
|
|
// next_index_in_object_memory - free_spots_in_object_memory.next_index, object_memory_size, |
|
|
|
// free_spots_in_object_memory.next_index); |
|
|
|
|
|
|
|
printf("Memory Status:\n" |
|
|
|
" - %f%% of the string_memory is used\n" |
|
|
|
" - %d holes in used memory (fragmentation)\n", |
|
|
|
(1.0*(size_t)next_free_spot_in_string_memory - (size_t)string_memory)/string_memory_size, |
|
|
|
free_spots_in_string_memory.next_index); |
|
|
|
// printf("Memory Status:\n" |
|
|
|
// " - %f%% of the string_memory is used\n" |
|
|
|
// " - %d holes in used memory (fragmentation)\n", |
|
|
|
// (1.0*(size_t)next_free_spot_in_string_memory - (size_t)string_memory)/string_memory_size, |
|
|
|
// free_spots_in_string_memory.next_index); |
|
|
|
} |
|
|
|
|
|
|
|
inline proc get_c_str(String* str) -> char* { |
|
|
|
@@ -140,24 +134,7 @@ namespace Memory { |
|
|
|
// } |
|
|
|
|
|
|
|
proc create_lisp_object() -> Lisp_Object* { |
|
|
|
int index; |
|
|
|
// if we have no free spots then append at the end |
|
|
|
if (free_spots_in_object_memory.next_index == 0) { |
|
|
|
// if we still have space |
|
|
|
if (object_memory_size == next_index_in_object_memory) { |
|
|
|
create_out_of_memory_error( |
|
|
|
"There is not enough space in the lisp object " |
|
|
|
"memory to allocate additional lisp objects. " |
|
|
|
"Maybe try increasing the Memory size when " |
|
|
|
"calling Memory::init()"); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
index = next_index_in_object_memory++; |
|
|
|
} else { |
|
|
|
// else fill a free spot, and remove the free spot |
|
|
|
index = free_spots_in_object_memory.data[free_spots_in_object_memory.next_index--]; |
|
|
|
} |
|
|
|
Lisp_Object* object = object_memory+index; |
|
|
|
Lisp_Object* object = object_memory.allocate(); |
|
|
|
object->flags = 0; |
|
|
|
object->sourceCodeLocation = nullptr; |
|
|
|
object->userType = nullptr; |
|
|
|
@@ -166,28 +143,16 @@ namespace Memory { |
|
|
|
} |
|
|
|
|
|
|
|
proc free_everything() -> void { |
|
|
|
// free(global_symbol_table); |
|
|
|
// free(global_keyword_table); |
|
|
|
free(object_memory); |
|
|
|
free(environment_memory); |
|
|
|
free(string_memory); |
|
|
|
} |
|
|
|
|
|
|
|
proc init(int oms, int ems, int sms) -> void { |
|
|
|
proc init(int sms) -> void { |
|
|
|
char* exe_path = get_exe_dir(); |
|
|
|
defer {free(exe_path);}; |
|
|
|
add_to_load_path(exe_path); |
|
|
|
add_to_load_path("../bin/"); |
|
|
|
|
|
|
|
// global_symbol_table = create_String_hashmap(); |
|
|
|
// global_keyword_table = create_String_hashmap(); |
|
|
|
|
|
|
|
object_memory_size = oms; |
|
|
|
environment_memory_size = ems; |
|
|
|
string_memory_size = sms; |
|
|
|
|
|
|
|
object_memory = (Lisp_Object*)malloc(object_memory_size * sizeof(Lisp_Object)); |
|
|
|
environment_memory = (Environment*)calloc(environment_memory_size, sizeof(Environment)); |
|
|
|
string_memory_size = sms; |
|
|
|
string_memory = (String*)malloc(string_memory_size * sizeof(char)); |
|
|
|
|
|
|
|
next_free_spot_in_string_memory = string_memory; |
|
|
|
@@ -209,8 +174,6 @@ namespace Memory { |
|
|
|
} |
|
|
|
|
|
|
|
proc reset() -> void { |
|
|
|
free_spots_in_object_memory.next_index = 0; |
|
|
|
free_spots_in_environment_memory.next_index = 0; |
|
|
|
free_spots_in_string_memory.next_index = 0; |
|
|
|
|
|
|
|
|
|
|
|
@@ -219,11 +182,19 @@ namespace Memory { |
|
|
|
|
|
|
|
try_void Parser::standard_in = create_string("stdin"); |
|
|
|
|
|
|
|
// because t and nil are always there we start the index at 2 |
|
|
|
next_index_in_object_memory = 2; |
|
|
|
next_index_in_environment_memory = 0; |
|
|
|
object_memory.reset(); |
|
|
|
environment_memory.reset(); |
|
|
|
next_free_spot_in_string_memory = string_memory; |
|
|
|
|
|
|
|
|
|
|
|
// init nil |
|
|
|
try_void nil = create_lisp_object(); |
|
|
|
set_type(nil, Lisp_Object_Type::Nil); |
|
|
|
|
|
|
|
// init t |
|
|
|
try_void t = create_lisp_object(); |
|
|
|
set_type(t, Lisp_Object_Type::T); |
|
|
|
|
|
|
|
Globals::Current_Execution::envi_stack.next_index = 0; |
|
|
|
Environment* env; |
|
|
|
try_void env = create_built_ins_environment(); |
|
|
|
@@ -271,21 +242,12 @@ namespace Memory { |
|
|
|
} |
|
|
|
|
|
|
|
proc allocate_vector(int size) -> Lisp_Object* { |
|
|
|
// NOTE(Felix): Vectors are now only allocated at the back of |
|
|
|
// the memory, we don't check the free list at all right now |
|
|
|
|
|
|
|
if (object_memory_size - next_index_in_object_memory < size) { |
|
|
|
create_out_of_memory_error( |
|
|
|
"There is not enough space in the lisp object " |
|
|
|
"memory to allocate additional lisp objects. " |
|
|
|
"Maybe try increasing the Memory size when " |
|
|
|
"calling Memory::init()"); |
|
|
|
Lisp_Object* ret = object_memory.allocate(size); |
|
|
|
if (!ret) { |
|
|
|
create_out_of_memory_error("The vector is too big to fit in a memory bucket."); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
int start = next_index_in_object_memory; |
|
|
|
next_index_in_object_memory += size; |
|
|
|
return object_memory+start; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
proc create_lisp_object_vector(int length, Lisp_Object* element_list) -> Lisp_Object* { |
|
|
|
@@ -413,34 +375,18 @@ namespace Memory { |
|
|
|
|
|
|
|
proc create_child_environment(Environment* parent) -> Environment* { |
|
|
|
|
|
|
|
Environment* env; |
|
|
|
// if we have no free spots then append at the end |
|
|
|
if (free_spots_in_environment_memory.next_index == 0) { |
|
|
|
int index; |
|
|
|
// if we still have space |
|
|
|
if (environment_memory_size == next_index_in_environment_memory) { |
|
|
|
create_out_of_memory_error( |
|
|
|
"There is not enough space in the environment " |
|
|
|
"memory to allocate additional environments. " |
|
|
|
"Maybe try increasing the Memory size when " |
|
|
|
"calling Memory::init()"); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
index = next_index_in_environment_memory++; |
|
|
|
env = environment_memory+index; |
|
|
|
} else { |
|
|
|
// else fill a free spot, and remove the free spot |
|
|
|
env = free_spots_in_environment_memory.data[--free_spots_in_environment_memory.next_index]; |
|
|
|
} |
|
|
|
Environment* env = environment_memory.allocate(); |
|
|
|
|
|
|
|
// inject a new array list; |
|
|
|
if (env->parents.data) |
|
|
|
free(env->parents.data); |
|
|
|
::new((&env->parents)) Array_List<Environment*>; |
|
|
|
|
|
|
|
// inject a new array list; |
|
|
|
::new(&env->parents) Array_List<Environment*>; |
|
|
|
|
|
|
|
if (parent) |
|
|
|
env->parents.append(parent); |
|
|
|
|
|
|
|
::new((&env->hm)) Hash_Map<void*, Lisp_Object*>; |
|
|
|
::new(&env->hm) Hash_Map<void*, Lisp_Object*>; |
|
|
|
|
|
|
|
return env; |
|
|
|
} |
|
|
|
@@ -461,18 +407,6 @@ namespace Memory { |
|
|
|
|
|
|
|
try load_built_ins_into_environment(); |
|
|
|
|
|
|
|
// save the current working directory |
|
|
|
//char* cwd = get_cwd(); |
|
|
|
//defer { |
|
|
|
// change_cwd(cwd); |
|
|
|
// free(cwd); |
|
|
|
//}; |
|
|
|
|
|
|
|
//// get the direction of the exe |
|
|
|
//char* exe_path = get_exe_dir(); |
|
|
|
//change_cwd(exe_path); |
|
|
|
//free(exe_path); |
|
|
|
|
|
|
|
built_in_load(Memory::create_string("pre.slime")); |
|
|
|
|
|
|
|
return ret; |
|
|
|
|