Lisp_Objects and Environments are now bucket allocated

This commit is contained in:
Felix Brendel
2019-10-21 22:39:06 +02:00
parent 4002652d05
commit 0a7f05a20d
13 changed files with 4412 additions and 645 deletions
+1 -1
Submodule 3rd/ftb updated: 6b3c2e157e...a20539587c
+3831
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -375,17 +375,17 @@ by the key =from= and ends with the number defined in =to=."
(when (< from to) (when (< from to)
(pair from (range :from (+ 1 from) :to to)))) (pair from (range :from (+ 1 from) :to to))))
(define (range-while (:from 0) to) (define (range-while (:from 0) :to)
:doc "Returns a sequence of numbers starting with the number defined :doc "Returns a sequence of numbers starting with the number defined
by the key 'from' and ends with the number defined in 'to'." by the key 'from' and ends with the number defined in 'to'."
(define result (list (copy from))) (define result (list (copy from)))
(define head result) (define head result)
(mutate from (increment from)) (set! from (increment from))
(while (< from to) (while (< from to)
(begin (begin
(mutate head (pair (first head) (pair (copy from) nil))) (mutate head (pair (first head) (pair (copy from) nil)))
(define head (rest head)) (define head (rest head))
(mutate from (increment from)))) (set! from (increment from))))
result) result)
(define (map fun seq) (define (map fun seq)
+2 -1
View File
@@ -1,4 +1,4 @@
TIMEFORMAT=%3lR TIMEFORMAT=%3lU
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
pushd $SCRIPTPATH > /dev/null pushd $SCRIPTPATH > /dev/null
@@ -26,6 +26,7 @@ time clang++ -D_DEBUG -D_PROFILING -D_DONT_BREAK_ON_ERRORS \
# src/main.cpp -g -o ./bin/slime --std=c++17 \ # src/main.cpp -g -o ./bin/slime --std=c++17 \
# -I3rd/ || exit 1 # -I3rd/ || exit 1
echo "" echo ""
pushd ./bin > /dev/null pushd ./bin > /dev/null
time ./slime --run-tests time ./slime --run-tests
+1 -1
View File
@@ -3,7 +3,7 @@
*/ */
#define __create_error(keyword, ...) \ #define __create_error(keyword, ...) \
create_error( \ create_error( \
__func__, __FILE__, __LINE__, \ __FUNCTION__, __FILE__, __LINE__, \
Memory::get_or_create_lisp_object_keyword(keyword), \ Memory::get_or_create_lisp_object_keyword(keyword), \
__VA_ARGS__) __VA_ARGS__)
+1 -1
View File
@@ -8,7 +8,7 @@
for (int i = 0; i < 30-strlen(__FILE__);++i) \ for (int i = 0; i < 30-strlen(__FILE__);++i) \
printf(" "); \ printf(" "); \
printf("%s (%d) ", __FILE__, __LINE__); \ printf("%s (%d) ", __FILE__, __LINE__); \
printf("-> %s\n", __func__); \ printf("-> %s\n",__FUNCTION__); \
} \ } \
} while(0) } while(0)
+2 -2
View File
@@ -486,7 +486,7 @@ proc is_truthy(Lisp_Object* expression) -> bool {
} }
proc interprete_file (char* file_name) -> Lisp_Object* { proc interprete_file (char* file_name) -> Lisp_Object* {
try Memory::init(4096 * 256, 1024, 4096 * 256); try Memory::init(4096 * 256);
Environment* root_env = get_root_environment(); Environment* root_env = get_root_environment();
Environment* user_env; Environment* user_env;
try user_env = Memory::create_child_environment(root_env); try user_env = Memory::create_child_environment(root_env);
@@ -506,7 +506,7 @@ proc interprete_file (char* file_name) -> Lisp_Object* {
} }
proc interprete_stdin() -> void { proc interprete_stdin() -> void {
try_void Memory::init(4096 * 256, 1024, 4096 * 256); try_void Memory::init(4096 * 256* 100);
Environment* root_env = get_root_environment(); Environment* root_env = get_root_environment();
Environment* user_env = Memory::create_child_environment(root_env); Environment* user_env = Memory::create_child_environment(root_env);
push_environment(user_env); push_environment(user_env);
+1 -1
View File
@@ -35,7 +35,7 @@ namespace Memory {
Lisp_Object* create_lisp_object_cfunction(bool is_special); Lisp_Object* create_lisp_object_cfunction(bool is_special);
Lisp_Object* get_or_create_lisp_object_keyword(const char* identifier); Lisp_Object* get_or_create_lisp_object_keyword(const char* identifier);
inline Lisp_Object_Type get_type(Lisp_Object* node); inline Lisp_Object_Type get_type(Lisp_Object* node);
void init(int, int, int); void init(int);
char* get_c_str(String*); char* get_c_str(String*);
void free_everything(); void free_everything();
String* create_string(const char*); String* create_string(const char*);
+1
View File
@@ -21,6 +21,7 @@
#include "ftb/types.hpp" #include "ftb/types.hpp"
#include "ftb/arraylist.hpp" #include "ftb/arraylist.hpp"
#include "ftb/bucket_allocator.hpp"
#include "ftb/macros.hpp" #include "ftb/macros.hpp"
#include "ftb/profiler.hpp" #include "ftb/profiler.hpp"
+37 -103
View File
@@ -9,18 +9,12 @@ namespace Memory {
// ------------------ // ------------------
// lisp_objects // lisp_objects
// ------------------ // ------------------
int object_memory_size; Bucket_Allocator<Lisp_Object, 1024> object_memory;
Array_List<int> free_spots_in_object_memory;
Lisp_Object* object_memory;
int next_index_in_object_memory = 0;
// ------------------ // ------------------
// environments // environments
// ------------------ // ------------------
int environment_memory_size; Bucket_Allocator<Environment, 1024> environment_memory;
Array_List<Environment*> free_spots_in_environment_memory;
Environment* environment_memory;
int next_index_in_environment_memory = 0;
// ------------------ // ------------------
// strings // strings
@@ -40,19 +34,19 @@ namespace Memory {
Lisp_Object* t = nullptr; Lisp_Object* t = nullptr;
proc print_status() { proc print_status() {
printf("Memory Status:\n" // printf("Memory Status:\n"
" - %f%% of the object_memory is used\n" // " - %f%% of the object_memory is used\n"
" - %d of %d total Lisp_Objects are in use\n" // " - %d of %d total Lisp_Objects are in use\n"
" - %d holes in used memory (fragmentation)\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, // (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, // next_index_in_object_memory - free_spots_in_object_memory.next_index, object_memory_size,
free_spots_in_object_memory.next_index); // free_spots_in_object_memory.next_index);
printf("Memory Status:\n" // printf("Memory Status:\n"
" - %f%% of the string_memory is used\n" // " - %f%% of the string_memory is used\n"
" - %d holes in used memory (fragmentation)\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, // (1.0*(size_t)next_free_spot_in_string_memory - (size_t)string_memory)/string_memory_size,
free_spots_in_string_memory.next_index); // free_spots_in_string_memory.next_index);
} }
inline proc get_c_str(String* str) -> char* { inline proc get_c_str(String* str) -> char* {
@@ -140,24 +134,7 @@ namespace Memory {
// } // }
proc create_lisp_object() -> Lisp_Object* { proc create_lisp_object() -> Lisp_Object* {
int index; Lisp_Object* object = object_memory.allocate();
// 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;
object->flags = 0; object->flags = 0;
object->sourceCodeLocation = nullptr; object->sourceCodeLocation = nullptr;
object->userType = nullptr; object->userType = nullptr;
@@ -166,28 +143,16 @@ namespace Memory {
} }
proc free_everything() -> void { proc free_everything() -> void {
// free(global_symbol_table);
// free(global_keyword_table);
free(object_memory);
free(environment_memory);
free(string_memory); free(string_memory);
} }
proc init(int oms, int ems, int sms) -> void { proc init(int sms) -> void {
char* exe_path = get_exe_dir(); char* exe_path = get_exe_dir();
defer {free(exe_path);}; defer {free(exe_path);};
add_to_load_path(exe_path); add_to_load_path(exe_path);
add_to_load_path("../bin/"); 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; 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 = (String*)malloc(string_memory_size * sizeof(char)); string_memory = (String*)malloc(string_memory_size * sizeof(char));
next_free_spot_in_string_memory = string_memory; next_free_spot_in_string_memory = string_memory;
@@ -209,8 +174,6 @@ namespace Memory {
} }
proc reset() -> void { 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; free_spots_in_string_memory.next_index = 0;
@@ -219,11 +182,19 @@ namespace Memory {
try_void Parser::standard_in = create_string("stdin"); try_void Parser::standard_in = create_string("stdin");
// because t and nil are always there we start the index at 2 object_memory.reset();
next_index_in_object_memory = 2; environment_memory.reset();
next_index_in_environment_memory = 0;
next_free_spot_in_string_memory = string_memory; 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; Globals::Current_Execution::envi_stack.next_index = 0;
Environment* env; Environment* env;
try_void env = create_built_ins_environment(); try_void env = create_built_ins_environment();
@@ -271,21 +242,12 @@ namespace Memory {
} }
proc allocate_vector(int size) -> Lisp_Object* { proc allocate_vector(int size) -> Lisp_Object* {
// NOTE(Felix): Vectors are now only allocated at the back of Lisp_Object* ret = object_memory.allocate(size);
// the memory, we don't check the free list at all right now if (!ret) {
create_out_of_memory_error("The vector is too big to fit in a memory bucket.");
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()");
return nullptr; return nullptr;
} }
return ret;
int start = next_index_in_object_memory;
next_index_in_object_memory += size;
return object_memory+start;
} }
proc create_lisp_object_vector(int length, Lisp_Object* element_list) -> Lisp_Object* { 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* { proc create_child_environment(Environment* parent) -> Environment* {
Environment* env; Environment* env = environment_memory.allocate();
// 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];
}
// inject a new array list;
if (env->parents.data) if (env->parents.data)
free(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) if (parent)
env->parents.append(parent); env->parents.append(parent);
::new((&env->hm)) Hash_Map<void*, Lisp_Object*>; ::new(&env->hm) Hash_Map<void*, Lisp_Object*>;
return env; return env;
} }
@@ -461,18 +407,6 @@ namespace Memory {
try load_built_ins_into_environment(); 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")); built_in_load(Memory::create_string("pre.slime"));
return ret; return ret;
+1 -1
View File
@@ -606,7 +606,7 @@ proc run_all_tests() -> bool {
bool result = true; bool result = true;
try Memory::init(200000, 102400, 409600); try Memory::init(409600);
Environment* root_env = get_root_environment(); Environment* root_env = get_root_environment();
Environment* user_env = Memory::create_child_environment(root_env); Environment* user_env = Memory::create_child_environment(root_env);
push_environment(user_env); push_environment(user_env);
+529 -529
View File
File diff suppressed because it is too large Load Diff