Lisp_Objects and Environments are now bucket allocated
This commit is contained in:
+1
-1
Submodule 3rd/ftb updated: 6b3c2e157e...a20539587c
+3831
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -750,7 +750,7 @@ proc load_built_ins_into_environment() -> void {
|
|||||||
};
|
};
|
||||||
define((hash-map-get hm key), "TODO") {
|
define((hash-map-get hm key), "TODO") {
|
||||||
fetch(hm, key);
|
fetch(hm, key);
|
||||||
try assert_type(hm, Lisp_Object_Type::HashMap);
|
try assert_type(hm, Lisp_Object_Type::HashMap);
|
||||||
|
|
||||||
Lisp_Object* ret = (Lisp_Object*)hm->value.hashMap.get_object(key);
|
Lisp_Object* ret = (Lisp_Object*)hm->value.hashMap.get_object(key);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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*);
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
+38
-104
@@ -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();
|
string_memory_size = sms;
|
||||||
// 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 = (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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user