Skip to content

Commit

Permalink
Fix broken object modification in thread.
Browse files Browse the repository at this point in the history
  • Loading branch information
mcfriend99 committed Oct 31, 2024
1 parent e8835ba commit 5fad5de
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 22 deletions.
52 changes: 52 additions & 0 deletions benchmarks/bench-binary-tree-3.b
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import thread

var start = time()

var N = 21

def make_tree(depth) {
if depth <= 0 return [nil, nil]
depth -= 1
return [make_tree(depth), make_tree(depth)]
}

def check_tree(node) {
var left = node[0], right = node[1]
if !left return 1
return 1 + check_tree(left) + check_tree(right)
}

var min_depth = 4
var max_depth = max(min_depth + 2, N)
var stretch_depth = max_depth + 1

echo 'stretch tree of depth ${stretch_depth}\t check: ${check_tree(make_tree(stretch_depth))}'

var long_lived_tree = make_tree(max_depth)

var iterations = 2 ** max_depth

var thrds = []
var lines = []
iter var depth = min_depth; depth < stretch_depth; depth += 2 {
lines.append(nil)

thrds.append(thread.start(@(_, lines, i, iterations, depth){
var check = 0
for i in 1..(iterations + 1) {
check += check_tree(make_tree(depth))
}

lines[i] = '${iterations}\t trees of depth ${depth}\t check: ${check}'
}, [lines, lines.length() - 1, iterations, depth]))

iterations //= 4
}

iter var i = 0; i < thrds.length(); i++ {
thrds[i].await()
echo lines[i]
}

echo 'long lived tree of depth ${max_depth}\t check: ${check_tree(long_lived_tree)}'
echo 'Total time taken: ${time() - start}'
31 changes: 15 additions & 16 deletions benchmarks/bench-binary-tree.b
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,40 @@ class TreeNode {
self.right = right
}

check() {
count() {
if self.left == nil return 1
return 1 + self.left.check() + self.right.check()
return 1 + self.left.count() + self.right.count()
}
}

def bottomUpTree(depth) {
def tree_with(depth) {
if depth > 0 {
return TreeNode(bottomUpTree(depth - 1), bottomUpTree(depth - 1))
return TreeNode(tree_with(depth - 1), tree_with(depth - 1))
}
return TreeNode(nil, nil)
}

def main(n) {
var minDepth = 4
var maxDepth = max(minDepth + 2, n)
var stretchDepth = maxDepth + 1
var min_depth = 4
var max_depth = max(min_depth + 2, n)
var stretch_depth = max_depth + 1

echo 'stretch tree of depth ${stretchDepth}\t check: ${bottomUpTree(stretchDepth).check()}'
echo 'stretch tree of depth ${stretch_depth}\t check: ${tree_with(stretch_depth).count()}'

var longLivedTree = bottomUpTree(maxDepth)
var long_lived_tree = tree_with(max_depth)

iter var depth = minDepth; depth <= maxDepth; depth += 2 {
var check = 0
var iterations = 1 << (maxDepth - depth + minDepth)
iter var depth = min_depth; depth <= max_depth; depth += 2 {
var sum = 0
var iterations = 1 << (max_depth - depth + min_depth)

iter var i = 1; i <= iterations; i++ {
var tempTree = bottomUpTree(depth)
check += tempTree.check()
sum += tree_with(depth).count()
}

echo '${iterations}\t trees of depth ${depth}\t check: ${check}'
echo '${iterations}\t trees of depth ${depth}\t check: ${sum}'
}

echo 'long lived tree of depth ${maxDepth}\t check: ${longLivedTree.check()}'
echo 'long lived tree of depth ${max_depth}\t check: ${long_lived_tree.count()}'
}

var start = time()
Expand Down
4 changes: 3 additions & 1 deletion src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@
# define LIBRARY_FILE_EXTENSION ".so"
#endif

#define DEFAULT_GC_START (1024 * 1024)
//#define DEFAULT_GC_START (1024 * 1024)
#define DEFAULT_GC_START (1024 * 1024 * 10)
#define MINIMUM_GC_START (1024 * 1024)

#if defined(_WIN32) && !defined(errno)
# define errno (GetLastError())
Expand Down
8 changes: 5 additions & 3 deletions src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@
#define MAX_USING_CASES 256
#define MAX_FUNCTION_PARAMETERS 255
#define FRAMES_MAX 512
#define ERRORS_MAX 512
#define ERRORS_MAX 256
#define NUMBER_FORMAT "%.16g"
#define MAX_INTERPOLATION_NESTING 8
#define MAX_EXCEPTION_HANDLERS 16

#define TABLE_MAX_LOAD 0.75
// Maximum load factor of 12/14
// see: https://engineering.fb.com/2019/04/25/developer-tools/f14/
#define TABLE_MAX_LOAD 0.85714286
// #define TABLE_MAX_LOAD 0.85714286

#define GC_HEAP_GROWTH_FACTOR 1.25
// #define GC_HEAP_GROWTH_FACTOR 1.25
#define GC_HEAP_GROWTH_FACTOR 1.5

#define USE_NAN_BOXING 1
#define PCRE2_CODE_UNIT_WIDTH 8
Expand Down
6 changes: 5 additions & 1 deletion src/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ void blacken_object(b_vm *vm, b_obj *object) {
printf("\n");
#endif

// if(object->vm_id != vm->id) return;
if(object->vm_id != vm->id) return;

switch (object->type) {
case OBJ_MODULE: {
Expand Down Expand Up @@ -428,6 +428,10 @@ void collect_garbage(b_vm *vm) {
free_error_stacks(vm);

vm->next_gc = vm->bytes_allocated * GC_HEAP_GROWTH_FACTOR;
if(vm->next_gc < MINIMUM_GC_START) {
vm->next_gc = MINIMUM_GC_START;
}

vm->mark_value = !vm->mark_value;

#if defined(DEBUG_GC) && DEBUG_GC
Expand Down
13 changes: 13 additions & 0 deletions src/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ b_obj *allocate_object(b_vm *vm, size_t size, b_obj_type type) {
return object;
}

void migrate_objects(b_vm *src, b_vm *dest) {
if(dest->objects != NULL) {
dest->objects->next = src->objects;
}

b_obj *object = src->objects;
while (object != NULL) {
b_obj *next = object->next;
object->vm_id = (int)dest->id;
object = next;
}
}


b_obj_ptr *new_ptr(b_vm *vm, void *pointer) {
b_obj_ptr *ptr = ALLOCATE_OBJ(b_obj_ptr, OBJ_PTR);
Expand Down
1 change: 1 addition & 0 deletions src/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ static inline bool is_obj_type(b_value v, b_obj_type t) {
(type *)allocate_object(vm, sizeof(type), obj_type)

b_obj *allocate_object(b_vm *vm, size_t size, b_obj_type type);
void migrate_objects(b_vm *src, b_vm *dest);

#define ITER_TOOL_PREPARE() \
int arity = closure->function->arity; \
Expand Down
6 changes: 6 additions & 0 deletions src/standard/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ b_vm *copy_vm(b_vm *src, uint64_t id) {

memset(vm, 0, sizeof(b_vm));

vm->parent_vm = src;
vm->stack = ALLOCATE(b_value, COPIED_STACK_MIN);
vm->stack_capacity = COPIED_STACK_MIN;

Expand Down Expand Up @@ -237,6 +238,11 @@ static b_thread_handle *create_thread_handle(b_vm *vm, b_obj_closure *closure, b

static void free_thread_handle(b_thread_handle *thread) {
if(thread != NULL && thread->vm != NULL) {
// move the surviving items to the parent vm's object list.
if(thread->vm->parent_vm != NULL) {
migrate_objects(thread->vm, thread->vm->parent_vm);
}

free_vm(thread->vm);

thread->vm = NULL;
Expand Down
3 changes: 2 additions & 1 deletion src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ static void init_builtin_methods(b_vm *vm) {

void init_vm(b_vm *vm) {

vm->parent_vm = NULL;
vm->stack = ALLOCATE(b_value, STACK_MIN);
vm->stack_capacity = STACK_MIN;

Expand All @@ -527,7 +528,7 @@ void init_vm(b_vm *vm) {
vm->current_frame = NULL;
vm->root_file = NULL;
vm->bytes_allocated = 0;
vm->next_gc = DEFAULT_GC_START; // default is 1mb. Can be modified via the -g flag.
vm->next_gc = DEFAULT_GC_START; // default is 10mb. Can be modified via the -g flag.
vm->is_repl = false;
vm->mark_value = true;
vm->show_warnings = false;
Expand Down
1 change: 1 addition & 0 deletions src/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ struct s_vm {

// id
uint64_t id;
b_vm *parent_vm;
};

void init_vm(b_vm *vm);
Expand Down

0 comments on commit 5fad5de

Please sign in to comment.