gc: automatically run garbage collection if memory allocation fails
This commit is contained in:
parent
dd4795c46b
commit
d1483a0c15
2
Makefile
2
Makefile
@ -7,7 +7,7 @@ CC ?= gcc
|
|||||||
ARCH = -m32
|
ARCH = -m32
|
||||||
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g
|
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g
|
||||||
CFLAGS += -DDEBUG
|
CFLAGS += -DDEBUG
|
||||||
CFLAGS += -DDEBUG_PRINT
|
#CFLAGS += -DDEBUG_PRINT
|
||||||
LDFLAGS = -lm
|
LDFLAGS = -lm
|
||||||
OPT ?= -O0
|
OPT ?= -O0
|
||||||
DEPFLAGS = -MMD -MP
|
DEPFLAGS = -MMD -MP
|
||||||
|
@ -3,30 +3,35 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "find_attribute.h"
|
#include "find_attribute.h"
|
||||||
#include "memory_allocator.h"
|
#include "memory_allocator.h"
|
||||||
|
#include "native_types_allocate.h"
|
||||||
|
|
||||||
struct backtrace * backtrace_allocate(struct vm * vm)
|
struct objectref * backtrace_allocate(struct vm * vm)
|
||||||
{
|
{
|
||||||
struct class_entry * object_class_entry = class_resolver_lookup_class(vm->class_hash_table.length,
|
struct class_entry * class_entry = class_resolver_lookup_class(vm->class_hash_table.length,
|
||||||
vm->class_hash_table.entry,
|
vm->class_hash_table.entry,
|
||||||
(const uint8_t *)"java/lang/Object",
|
(const uint8_t *)"java/lang/Backtrace",
|
||||||
16);
|
19);
|
||||||
debugf("object class entry: %p\n", object_class_entry);
|
debugf("backtrace class entry: %p\n", class_entry);
|
||||||
|
|
||||||
int num_fields = (sizeof (struct backtrace)) / (sizeof (void *));
|
assert(class_entry->instance_fields_count >= 1);
|
||||||
struct objectref * objectref = obj_allocate(num_fields);
|
struct objectref * objectref = obj_allocate(vm, class_entry->instance_fields_count);
|
||||||
objectref->class_entry = object_class_entry;
|
objectref->class_entry = class_entry;
|
||||||
struct backtrace * backtrace = (struct backtrace *)&objectref->aref[0];
|
|
||||||
backtrace->num_entries = vm->frame_stack.ix;
|
|
||||||
int backtrace_entries_size = (sizeof (struct backtrace_entry)) * backtrace->num_entries;
|
|
||||||
backtrace->entry = memory_allocate(backtrace_entries_size);
|
|
||||||
|
|
||||||
for (int i = (vm->frame_stack.ix - 1); i >= 0; i--) {
|
int num_entries = vm->frame_stack.ix;
|
||||||
|
struct arrayref * arrayref = prim_array_allocate(vm, (sizeof (struct backtrace_entry)), num_entries);
|
||||||
|
arrayref->length = num_entries;
|
||||||
|
arrayref->class_entry = nullptr;
|
||||||
|
|
||||||
|
struct backtrace_entry * backtrace_entry = (struct backtrace_entry *)&arrayref->u32[0];
|
||||||
|
objectref->aref[0] = arrayref;
|
||||||
|
|
||||||
|
for (int i = (num_entries - 1); i >= 0; i--) {
|
||||||
struct frame * frame = &vm->frame_stack.frame[i];
|
struct frame * frame = &vm->frame_stack.frame[i];
|
||||||
backtrace->entry[i].class_file = frame->class_entry->class_file;
|
backtrace_entry[i].class_file = frame->class_entry->class_file;
|
||||||
backtrace->entry[i].method_info = frame->method_info;
|
backtrace_entry[i].method_info = frame->method_info;
|
||||||
backtrace->entry[i].pc = frame->pc;
|
backtrace_entry[i].pc = frame->pc;
|
||||||
}
|
}
|
||||||
return backtrace;
|
return objectref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_line_number(struct class_file * class_file, struct method_info * method_info, int pc)
|
static int get_line_number(struct class_file * class_file, struct method_info * method_info, int pc)
|
||||||
@ -57,20 +62,25 @@ static int get_line_number(struct class_file * class_file, struct method_info *
|
|||||||
return line_number;
|
return line_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
void backtrace_print(struct backtrace * backtrace)
|
void backtrace_print(struct objectref * objectref)
|
||||||
{
|
{
|
||||||
|
debugf("backtrace objectref class entry: %p\n", objectref->class_entry);
|
||||||
|
|
||||||
|
struct arrayref * arrayref = objectref->aref[0];
|
||||||
|
struct backtrace_entry * backtrace_entry = (struct backtrace_entry *)&arrayref->u32[0];
|
||||||
|
|
||||||
prints("backtrace:\n");
|
prints("backtrace:\n");
|
||||||
for (int i = (backtrace->num_entries - 1); i >= 0; i--) {
|
for (int i = (arrayref->length - 1); i >= 0; i--) {
|
||||||
struct backtrace_entry * backtrace_entry = &backtrace->entry[i];
|
struct backtrace_entry * entry = &backtrace_entry[i];
|
||||||
prints(" class: ");
|
prints(" class: ");
|
||||||
print__class_file__class_name(backtrace_entry->class_file);
|
print__class_file__class_name(entry->class_file);
|
||||||
prints(" method: ");
|
prints(" method: ");
|
||||||
print__method_info__method_name(backtrace_entry->class_file, backtrace_entry->method_info);
|
print__method_info__method_name(entry->class_file, entry->method_info);
|
||||||
printc('\n');
|
printc('\n');
|
||||||
printf(" pc: %3d ", backtrace_entry->pc);
|
printf(" pc: %3d ", entry->pc);
|
||||||
int line_number = get_line_number(backtrace_entry->class_file,
|
int line_number = get_line_number(entry->class_file,
|
||||||
backtrace_entry->method_info,
|
entry->method_info,
|
||||||
backtrace_entry->pc);
|
entry->pc);
|
||||||
printf(" line_number: %3d\n", line_number);
|
printf(" line_number: %3d\n", line_number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,6 @@ struct backtrace_entry {
|
|||||||
int pc;
|
int pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct backtrace {
|
struct objectref * backtrace_allocate(struct vm * vm);
|
||||||
int num_entries;
|
|
||||||
struct backtrace_entry * entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct backtrace * backtrace_allocate(struct vm * vm);
|
void backtrace_print(struct objectref * objectref);
|
||||||
|
|
||||||
void backtrace_print(struct backtrace * backtrace);
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include "fatal.h"
|
#include "fatal.h"
|
||||||
#include "parse_type.h"
|
#include "parse_type.h"
|
||||||
#include "find_attribute.h"
|
#include "find_attribute.h"
|
||||||
|
#include "frame.h"
|
||||||
|
#include "native_types_allocate.h"
|
||||||
|
|
||||||
static int field_info_field_size(struct class_file * class_file, struct field_info * field_info)
|
static int field_info_field_size(struct class_file * class_file, struct field_info * field_info)
|
||||||
{
|
{
|
||||||
@ -587,8 +589,7 @@ struct method_entry class_resolver_lookup_method_from_method_name_method_descrip
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct objectref * class_resolver_lookup_string(int class_hash_table_length,
|
struct objectref * class_resolver_lookup_string(struct vm * vm,
|
||||||
struct hash_table_entry * class_hash_table,
|
|
||||||
struct class_entry * class_entry,
|
struct class_entry * class_entry,
|
||||||
const int string_index)
|
const int string_index)
|
||||||
{
|
{
|
||||||
@ -604,14 +605,14 @@ struct objectref * class_resolver_lookup_string(int class_hash_table_length,
|
|||||||
struct constant * utf8_constant = &class_entry->class_file->constant_pool[string_constant->string.string_index - 1];
|
struct constant * utf8_constant = &class_entry->class_file->constant_pool[string_constant->string.string_index - 1];
|
||||||
assert(utf8_constant->tag == CONSTANT_Utf8);
|
assert(utf8_constant->tag == CONSTANT_Utf8);
|
||||||
|
|
||||||
struct class_entry * string_class_entry = class_resolver_lookup_class(class_hash_table_length,
|
struct class_entry * string_class_entry = class_resolver_lookup_class(vm->class_hash_table.length,
|
||||||
class_hash_table,
|
vm->class_hash_table.entry,
|
||||||
(const uint8_t *)"java/lang/String",
|
(const uint8_t *)"java/lang/String",
|
||||||
16);
|
16);
|
||||||
debugf("string class entry: %p\n", string_class_entry);
|
debugf("string class entry: %p\n", string_class_entry);
|
||||||
|
|
||||||
int32_t count = utf8_constant->utf8.length;
|
int32_t count = utf8_constant->utf8.length;
|
||||||
struct arrayref * arrayref = prim_array_allocate(1, count);
|
struct arrayref * arrayref = prim_array_allocate(vm, 1, count);
|
||||||
assert(arrayref != nullptr);
|
assert(arrayref != nullptr);
|
||||||
arrayref->class_entry = nullptr; // byte[]
|
arrayref->class_entry = nullptr; // byte[]
|
||||||
arrayref->length = utf8_constant->utf8.length;
|
arrayref->length = utf8_constant->utf8.length;
|
||||||
@ -621,7 +622,7 @@ struct objectref * class_resolver_lookup_string(int class_hash_table_length,
|
|||||||
|
|
||||||
assert(string_class_entry != nullptr);
|
assert(string_class_entry != nullptr);
|
||||||
int fields_count = string_class_entry->instance_fields_count;
|
int fields_count = string_class_entry->instance_fields_count;
|
||||||
struct objectref * objectref = obj_allocate(fields_count);
|
struct objectref * objectref = obj_allocate(vm, fields_count);
|
||||||
assert(objectref != nullptr);
|
assert(objectref != nullptr);
|
||||||
objectref->class_entry = string_class_entry;
|
objectref->class_entry = string_class_entry;
|
||||||
for (int i = 0; i < fields_count; i++) {
|
for (int i = 0; i < fields_count; i++) {
|
||||||
|
@ -86,11 +86,6 @@ struct field_entry * class_resolver_lookup_field_from_fieldref_index(int fields_
|
|||||||
struct class_entry * class_entry,
|
struct class_entry * class_entry,
|
||||||
int fieldref_index);
|
int fieldref_index);
|
||||||
|
|
||||||
struct objectref * class_resolver_lookup_string(int class_hash_table_length,
|
|
||||||
struct hash_table_entry * class_hash_table,
|
|
||||||
struct class_entry * class_entry,
|
|
||||||
const int string_index);
|
|
||||||
|
|
||||||
bool class_resolver_instanceof(int class_hash_table_length,
|
bool class_resolver_instanceof(int class_hash_table_length,
|
||||||
struct hash_table_entry * class_hash_table,
|
struct hash_table_entry * class_hash_table,
|
||||||
struct class_entry * origin_class_entry,
|
struct class_entry * origin_class_entry,
|
||||||
|
19
c/execute.c
19
c/execute.c
@ -2,12 +2,13 @@
|
|||||||
#include "memory_allocator.h"
|
#include "memory_allocator.h"
|
||||||
#include "bswap.h"
|
#include "bswap.h"
|
||||||
#include "class_resolver.h"
|
#include "class_resolver.h"
|
||||||
#include "execute_helper.h"
|
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "field_size.h"
|
#include "field_size.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "native_types.h"
|
#include "native_types.h"
|
||||||
|
#include "native_types_allocate.h"
|
||||||
#include "parse_type.h"
|
#include "parse_type.h"
|
||||||
|
#include "execute_helper.h"
|
||||||
|
|
||||||
void op_aaload(struct vm * vm)
|
void op_aaload(struct vm * vm)
|
||||||
{
|
{
|
||||||
@ -71,7 +72,7 @@ void op_anewarray(struct vm * vm, uint32_t index)
|
|||||||
index);
|
index);
|
||||||
|
|
||||||
int32_t count = operand_stack_pop_u32(vm->current_frame);
|
int32_t count = operand_stack_pop_u32(vm->current_frame);
|
||||||
struct arrayref * arrayref = ref_array_allocate(count);
|
struct arrayref * arrayref = ref_array_allocate(vm, count);
|
||||||
assert(arrayref != nullptr);
|
assert(arrayref != nullptr);
|
||||||
arrayref->length = count;
|
arrayref->length = count;
|
||||||
arrayref->class_entry = class_entry;
|
arrayref->class_entry = class_entry;
|
||||||
@ -1424,8 +1425,7 @@ void op_ldc(struct vm * vm, uint32_t index)
|
|||||||
int32_t value = constant->integer.bytes;
|
int32_t value = constant->integer.bytes;
|
||||||
operand_stack_push_u32(vm->current_frame, value);
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
} else if (constant->tag == CONSTANT_String) {
|
} else if (constant->tag == CONSTANT_String) {
|
||||||
struct objectref * objectref = class_resolver_lookup_string(vm->class_hash_table.length,
|
struct objectref * objectref = class_resolver_lookup_string(vm,
|
||||||
vm->class_hash_table.entry,
|
|
||||||
vm->current_frame->class_entry,
|
vm->current_frame->class_entry,
|
||||||
index);
|
index);
|
||||||
operand_stack_push_ref(vm->current_frame, objectref);
|
operand_stack_push_ref(vm->current_frame, objectref);
|
||||||
@ -1451,8 +1451,7 @@ void op_ldc_w(struct vm * vm, uint32_t index)
|
|||||||
int32_t value = constant->integer.bytes;
|
int32_t value = constant->integer.bytes;
|
||||||
operand_stack_push_u32(vm->current_frame, value);
|
operand_stack_push_u32(vm->current_frame, value);
|
||||||
} else if (constant->tag == CONSTANT_String) {
|
} else if (constant->tag == CONSTANT_String) {
|
||||||
struct objectref * objectref = class_resolver_lookup_string(vm->class_hash_table.length,
|
struct objectref * objectref = class_resolver_lookup_string(vm,
|
||||||
vm->class_hash_table.entry,
|
|
||||||
vm->current_frame->class_entry,
|
vm->current_frame->class_entry,
|
||||||
index);
|
index);
|
||||||
operand_stack_push_ref(vm->current_frame, objectref);
|
operand_stack_push_ref(vm->current_frame, objectref);
|
||||||
@ -1660,10 +1659,10 @@ static struct arrayref * _multiarray(struct vm * vm, int32_t * dims, int num_dim
|
|||||||
int32_t element_size;
|
int32_t element_size;
|
||||||
if (*type == 'L' || *type == '[') {
|
if (*type == 'L' || *type == '[') {
|
||||||
element_size = (sizeof (void *));
|
element_size = (sizeof (void *));
|
||||||
arrayref = ref_array_allocate(count);
|
arrayref = ref_array_allocate(vm, count);
|
||||||
} else {
|
} else {
|
||||||
element_size = field_size_array(*type);
|
element_size = field_size_array(*type);
|
||||||
arrayref = prim_array_allocate(element_size, count);
|
arrayref = prim_array_allocate(vm, element_size, count);
|
||||||
}
|
}
|
||||||
assert(arrayref != nullptr);
|
assert(arrayref != nullptr);
|
||||||
arrayref->length = count;
|
arrayref->length = count;
|
||||||
@ -1733,7 +1732,7 @@ void op_new(struct vm * vm, uint32_t index)
|
|||||||
reference to the instance, is pushed onto the operand stack. */
|
reference to the instance, is pushed onto the operand stack. */
|
||||||
|
|
||||||
int fields_count = class_entry->instance_fields_count;
|
int fields_count = class_entry->instance_fields_count;
|
||||||
struct objectref * objectref = obj_allocate(fields_count);
|
struct objectref * objectref = obj_allocate(vm, fields_count);
|
||||||
assert(objectref != nullptr);
|
assert(objectref != nullptr);
|
||||||
objectref->class_entry = class_entry;
|
objectref->class_entry = class_entry;
|
||||||
for (int i = 0; i < fields_count; i++) {
|
for (int i = 0; i < fields_count; i++) {
|
||||||
@ -1748,7 +1747,7 @@ void op_newarray(struct vm * vm, uint32_t atype)
|
|||||||
{
|
{
|
||||||
int32_t count = operand_stack_pop_u32(vm->current_frame);
|
int32_t count = operand_stack_pop_u32(vm->current_frame);
|
||||||
int32_t element_size = array_element_size(atype);
|
int32_t element_size = array_element_size(atype);
|
||||||
struct arrayref * arrayref = prim_array_allocate(element_size, count);
|
struct arrayref * arrayref = prim_array_allocate(vm, element_size, count);
|
||||||
assert(arrayref != nullptr);
|
assert(arrayref != nullptr);
|
||||||
arrayref->length = count;
|
arrayref->length = count;
|
||||||
arrayref->class_entry = nullptr;
|
arrayref->class_entry = nullptr;
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
// declared here due to circular frame.h include in class_resolver.h
|
||||||
|
struct objectref * class_resolver_lookup_string(struct vm * vm,
|
||||||
|
struct class_entry * class_entry,
|
||||||
|
const int string_index);
|
||||||
|
|
||||||
static inline void class_entry_field_entry_from_constant_index(struct vm * vm,
|
static inline void class_entry_field_entry_from_constant_index(struct vm * vm,
|
||||||
int32_t index,
|
int32_t index,
|
||||||
struct class_entry ** class_entry,
|
struct class_entry ** class_entry,
|
||||||
|
@ -548,7 +548,7 @@ void vm_exception(struct vm * vm, struct objectref * objectref)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(objectref->oref[0] != 0);
|
assert(objectref->oref[0] != 0);
|
||||||
backtrace_print((struct backtrace *)objectref->oref[0]);
|
backtrace_print(objectref->oref[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_vm_stack(struct vm * vm)
|
static void print_vm_stack(struct vm * vm)
|
||||||
|
11
c/gc.c
11
c/gc.c
@ -145,7 +145,7 @@ void gc_mark(struct vm * vm)
|
|||||||
static void sweep_address(void * address)
|
static void sweep_address(void * address)
|
||||||
{
|
{
|
||||||
struct tag * tag = (struct tag *)address;
|
struct tag * tag = (struct tag *)address;
|
||||||
printf("%p mark: %d\n", address, tag->mark);
|
//printf("%p mark: %d\n", address, tag->mark);
|
||||||
int mark = tag->mark;
|
int mark = tag->mark;
|
||||||
tag->mark = 0;
|
tag->mark = 0;
|
||||||
if (mark == 0) {
|
if (mark == 0) {
|
||||||
@ -157,3 +157,12 @@ void gc_sweep()
|
|||||||
{
|
{
|
||||||
memory_iterate_allocated(sweep_address);
|
memory_iterate_allocated(sweep_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void memory_print_free_list();
|
||||||
|
|
||||||
|
void gc_run(struct vm * vm)
|
||||||
|
{
|
||||||
|
gc_mark(vm);
|
||||||
|
gc_sweep();
|
||||||
|
//memory_print_free_list();
|
||||||
|
}
|
||||||
|
1
c/gc.h
1
c/gc.h
@ -4,3 +4,4 @@
|
|||||||
|
|
||||||
void gc_mark(struct vm * vm);
|
void gc_mark(struct vm * vm);
|
||||||
void gc_sweep();
|
void gc_sweep();
|
||||||
|
void gc_run(struct vm * vm);
|
||||||
|
@ -6,18 +6,38 @@
|
|||||||
|
|
||||||
#define block_power (5UL)
|
#define block_power (5UL)
|
||||||
#define block_size (1UL << block_power)
|
#define block_size (1UL << block_power)
|
||||||
static uint8_t memory[0x200];
|
static uint8_t memory[0x400];
|
||||||
//static uint8_t memory[0x100000];
|
//static uint8_t memory[0x100000];
|
||||||
#define free_list_length ((sizeof (memory)) / block_size)
|
static uint8_t free_list[((sizeof (memory)) / block_size)];
|
||||||
static uint8_t free_list[free_list_length];
|
const int free_list_length = (sizeof (free_list));
|
||||||
static uint32_t free_ix;
|
static uint32_t free_ix;
|
||||||
|
|
||||||
|
static_assert(((sizeof (free_list)) & (~((sizeof (free_list)) - 1))) == (sizeof (free_list)));
|
||||||
|
|
||||||
enum allocation_state {
|
enum allocation_state {
|
||||||
ALLOCATED = 0b0001,
|
ALLOCATED = 0b0001,
|
||||||
START = 0b0010,
|
START = 0b0010,
|
||||||
END = 0b0100,
|
END = 0b0100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void memory_print_free_list()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < free_list_length; i++) {
|
||||||
|
printf("%d ", free_list[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
for (int i = 0; i < free_list_length; i++) {
|
||||||
|
char c = (free_ix == i) ? '^' : ' ';
|
||||||
|
printf("%c ", c);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
for (int i = 0; i < free_list_length; i++) {
|
||||||
|
char c = memory_is_allocated((void *)((i << block_power) + memory)) ? 'X' : ' ';
|
||||||
|
printf("%c ", c);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
void memory_reset_free_list()
|
void memory_reset_free_list()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (sizeof (free_list)); i++) {
|
for (int i = 0; i < (sizeof (free_list)); i++) {
|
||||||
@ -70,14 +90,16 @@ void * memory_allocate(uint32_t size)
|
|||||||
void * mem = &memory[free_ix << block_power];
|
void * mem = &memory[free_ix << block_power];
|
||||||
free_ix = (free_ix + blocks) & (free_list_length - 1);
|
free_ix = (free_ix + blocks) & (free_list_length - 1);
|
||||||
|
|
||||||
printf("memory allocate: %p\n", mem);
|
debugf("memory allocate: %p\n", mem);
|
||||||
|
//memory_print_free_list();
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_free(void * p)
|
void memory_free(void * p)
|
||||||
{
|
{
|
||||||
printf("memory free: %p\n", p);
|
debugf("memory free: %p\n", p);
|
||||||
|
//memory_print_free_list();
|
||||||
|
|
||||||
uint8_t * buf = (uint8_t *)p;
|
uint8_t * buf = (uint8_t *)p;
|
||||||
assert(buf >= memory);
|
assert(buf >= memory);
|
||||||
@ -119,25 +141,6 @@ void memory_iterate_allocated(memory_iterate_func_t func)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void print_free_list()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < free_list_length; i++) {
|
|
||||||
printf("%d ", free_list[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
for (int i = 0; i < free_list_length; i++) {
|
|
||||||
char c = (free_ix == i) ? '^' : ' ';
|
|
||||||
printf("%c ", c);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
for (int i = 0; i < free_list_length; i++) {
|
|
||||||
char c = memory_is_allocated((void *)((i << block_power) + memory)) ? 'X' : ' ';
|
|
||||||
printf("%c ", c);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
memory_reset_free_list();
|
memory_reset_free_list();
|
||||||
@ -151,33 +154,33 @@ int main()
|
|||||||
printf("p3 %p\n", p3);
|
printf("p3 %p\n", p3);
|
||||||
void * p4 = memory_allocate(90);
|
void * p4 = memory_allocate(90);
|
||||||
printf("p4 %p\n", p4);
|
printf("p4 %p\n", p4);
|
||||||
print_free_list();
|
memory_print_free_list();
|
||||||
|
|
||||||
memory_free(p2);
|
memory_free(p2);
|
||||||
memory_free(p1);
|
memory_free(p1);
|
||||||
void * p5 = memory_allocate(256);
|
void * p5 = memory_allocate(256);
|
||||||
printf("p5 %p\n", p5);
|
printf("p5 %p\n", p5);
|
||||||
|
|
||||||
print_free_list();
|
memory_print_free_list();
|
||||||
|
|
||||||
void * p6 = memory_allocate(128);
|
void * p6 = memory_allocate(128);
|
||||||
printf("p6 %p\n", p6);
|
printf("p6 %p\n", p6);
|
||||||
|
|
||||||
memory_free(p4);
|
memory_free(p4);
|
||||||
|
|
||||||
print_free_list();
|
memory_print_free_list();
|
||||||
|
|
||||||
void * p7 = memory_allocate(128);
|
void * p7 = memory_allocate(128);
|
||||||
printf("p7 %p\n", p7);
|
printf("p7 %p\n", p7);
|
||||||
|
|
||||||
print_free_list();
|
memory_print_free_list();
|
||||||
|
|
||||||
void * p8 = memory_allocate(128);
|
void * p8 = memory_allocate(128);
|
||||||
printf("p8 %p\n", p8);
|
printf("p8 %p\n", p8);
|
||||||
print_free_list();
|
memory_print_free_list();
|
||||||
|
|
||||||
void * p9 = memory_allocate(128);
|
void * p9 = memory_allocate(128);
|
||||||
printf("p9 %p\n", p9);
|
printf("p9 %p\n", p9);
|
||||||
print_free_list();
|
memory_print_free_list();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,36 +85,3 @@ static inline int array_element_size(int atype)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct arrayref * prim_array_allocate(int element_size, int count)
|
|
||||||
{
|
|
||||||
int32_t size = count * element_size + (sizeof (struct arrayref));
|
|
||||||
struct arrayref * arrayref = memory_allocate(size);
|
|
||||||
if (arrayref != nullptr) {
|
|
||||||
arrayref->tag.type = TAG_TYPE_PRIM_ARRAY;
|
|
||||||
arrayref->tag.mark = 0;
|
|
||||||
}
|
|
||||||
return arrayref;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct arrayref * ref_array_allocate(int count)
|
|
||||||
{
|
|
||||||
int32_t size = count * (sizeof (void *)) + (sizeof (struct arrayref));
|
|
||||||
struct arrayref * arrayref = memory_allocate(size);
|
|
||||||
if (arrayref != nullptr) {
|
|
||||||
arrayref->tag.type = TAG_TYPE_REF_ARRAY;
|
|
||||||
arrayref->tag.mark = 0;
|
|
||||||
}
|
|
||||||
return arrayref;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct objectref * obj_allocate(int num_fields)
|
|
||||||
{
|
|
||||||
int32_t size = num_fields * (sizeof (void *)) + (sizeof (struct objectref));
|
|
||||||
struct objectref * objectref = memory_allocate(size);
|
|
||||||
if (objectref != nullptr) {
|
|
||||||
objectref->tag.type = TAG_TYPE_OBJECT;
|
|
||||||
objectref->tag.mark = 0;
|
|
||||||
}
|
|
||||||
return objectref;
|
|
||||||
}
|
|
||||||
|
48
c/native_types_allocate.h
Normal file
48
c/native_types_allocate.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "native_types.h"
|
||||||
|
#include "frame.h"
|
||||||
|
#include "gc.h"
|
||||||
|
|
||||||
|
static inline void * gc_memory_allocate(struct vm * vm, int size)
|
||||||
|
{
|
||||||
|
void * mem = memory_allocate(size);
|
||||||
|
if (mem == nullptr) {
|
||||||
|
gc_run(vm);
|
||||||
|
mem = memory_allocate(size);
|
||||||
|
}
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct arrayref * prim_array_allocate(struct vm * vm, int element_size, int count)
|
||||||
|
{
|
||||||
|
int32_t size = count * element_size + (sizeof (struct arrayref));
|
||||||
|
struct arrayref * arrayref = gc_memory_allocate(vm, size);
|
||||||
|
if (arrayref != nullptr) {
|
||||||
|
arrayref->tag.type = TAG_TYPE_PRIM_ARRAY;
|
||||||
|
arrayref->tag.mark = 0;
|
||||||
|
}
|
||||||
|
return arrayref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct arrayref * ref_array_allocate(struct vm * vm, int count)
|
||||||
|
{
|
||||||
|
int32_t size = count * (sizeof (void *)) + (sizeof (struct arrayref));
|
||||||
|
struct arrayref * arrayref = gc_memory_allocate(vm, size);
|
||||||
|
if (arrayref != nullptr) {
|
||||||
|
arrayref->tag.type = TAG_TYPE_REF_ARRAY;
|
||||||
|
arrayref->tag.mark = 0;
|
||||||
|
}
|
||||||
|
return arrayref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct objectref * obj_allocate(struct vm * vm, int num_fields)
|
||||||
|
{
|
||||||
|
int32_t size = num_fields * (sizeof (void *)) + (sizeof (struct objectref));
|
||||||
|
struct objectref * objectref = gc_memory_allocate(vm, size);
|
||||||
|
if (objectref != nullptr) {
|
||||||
|
objectref->tag.type = TAG_TYPE_OBJECT;
|
||||||
|
objectref->tag.mark = 0;
|
||||||
|
}
|
||||||
|
return objectref;
|
||||||
|
}
|
6
classes/java/lang/Backtrace.java
Normal file
6
classes/java/lang/Backtrace.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class Backtrace {
|
||||||
|
int[] backtrace_entry; // is actually (struct backtrace_entry)
|
||||||
|
|
||||||
|
private Backtrace() {
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ class TestGC {
|
|||||||
static TestGC static_tgc;
|
static TestGC static_tgc;
|
||||||
TestGC instance_tgc;
|
TestGC instance_tgc;
|
||||||
|
|
||||||
void main() {
|
static void test() {
|
||||||
System.out.println("static new TestGC");
|
System.out.println("static new TestGC");
|
||||||
TestGC tgc = new TestGC();
|
TestGC tgc = new TestGC();
|
||||||
static_tgc = tgc;
|
static_tgc = tgc;
|
||||||
@ -13,4 +13,16 @@ class TestGC {
|
|||||||
System.out.println("stack new TestGC");
|
System.out.println("stack new TestGC");
|
||||||
TestGC stack = new TestGC();
|
TestGC stack = new TestGC();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test2() {
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
System.out.print("new TestGC: ");
|
||||||
|
System.out.println(i);
|
||||||
|
TestGC gc = new TestGC();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main() {
|
||||||
|
test2();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user