From 84e65c63e7482590d535e86f7660a00ae8a0cecb Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 17 Jul 2019 19:23:16 +0200 Subject: Start on amal program Fix mutex issue in lhs expr which can cause a deadlock when a file has an error and throws and doesn't close the mutex and another thread waits for that mutex. The mutex can instead be removed and ignore race conditions which are uncommon. This should improve memory usage and performance. --- src/bytecode/bytecode.c | 51 +++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'src/bytecode') diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c index 29d99c0..7c4fe08 100644 --- a/src/bytecode/bytecode.c +++ b/src/bytecode/bytecode.c @@ -19,7 +19,7 @@ } while(0) int bytecode_init(Bytecode *self, ScopedAllocator *allocator) { - return buffer_init(&self->instructions, allocator); + return buffer_init(&self->data, allocator); } static CHECK_RESULT usize ssa_extract_form1(u8 *instruction_data, SsaInsForm1 *result) { @@ -59,7 +59,7 @@ static CHECK_RESULT usize ssa_extract_jump(u8 *instruction_data, SsaInsJump *res } static void add_header(BytecodeCompilerContext *self) { - /*doc(BytecodeHeader) + /*doc(Bytecode header) # Header layout |Size|Name |Description | |----|-------------|----------------------------------------------------------------------------| @@ -76,7 +76,7 @@ static void add_header(BytecodeCompilerContext *self) { const u8 patch_version = 0; Buffer *instructions; - instructions = &self->bytecode->instructions; + instructions = &self->bytecode.data; throw_if_error(buffer_append(instructions, &magic_number, 4)); throw_if_error(buffer_append(instructions, &major_version, 1)); throw_if_error(buffer_append(instructions, &minor_version, 1)); @@ -90,7 +90,7 @@ static void add_intermediates(BytecodeCompilerContext *self) { SsaNumber *intermediates_end; ssa = self->parser->ssa; - instructions = &self->bytecode->instructions; + instructions = &self->bytecode.data; intermediate = buffer_begin(&ssa->intermediates); intermediates_end = buffer_end(&ssa->intermediates); @@ -108,20 +108,21 @@ void add_strings(BytecodeCompilerContext *self) { Buffer *instructions; BufferView *string; BufferView *strings_end; + u32 strings_size; ssa = self->parser->ssa; - instructions = &self->bytecode->instructions; + instructions = &self->bytecode.data; string = buffer_begin(&ssa->strings); strings_end = buffer_end(&ssa->strings); + strings_size = 0; - /* - The 8 here is a arbitrary chosen number since we don't know the actual - size of all strings without counting. The logic is that the average - size of all strings length would be 8. - */ - throw_if_error(buffer_expand(instructions, - sizeof(u16) + (sizeof(u16) + 8) * ssa->strings.size)); - throw_if_error(buffer_append(instructions, &ssa->strings.size, sizeof(u16))); + for(; string != strings_end; ++string) { + strings_size += sizeof(u16) + string->size; + } + string = buffer_begin(&ssa->strings); + + throw_if_error(buffer_expand(instructions, sizeof(u32) + strings_size)); + throw_if_error(buffer_append(instructions, &strings_size, sizeof(u32))); for(; string != strings_end; ++string) { throw_if_error(buffer_append(instructions, &string->size, sizeof(u16))); throw_if_error(buffer_append(instructions, &string->data, string->size)); @@ -129,7 +130,7 @@ void add_strings(BytecodeCompilerContext *self) { } static void add_ins1(BytecodeCompilerContext *self, AmalOpcode opcode, const char *fmt) { - throw_if_error(buffer_append(&self->bytecode->instructions, &opcode, sizeof(AmalOpcodeType))); + throw_if_error(buffer_append(&self->bytecode.data, &opcode, sizeof(AmalOpcodeType))); fprintf(stderr, fmt); fputc('\n', stderr); } @@ -138,7 +139,7 @@ static void add_ins1(BytecodeCompilerContext *self, AmalOpcode opcode, const cha static void add_ins2(BytecodeCompilerContext *self, AmalOpcode opcode, u8 reg, const char *fmt) { Buffer *instructions; size_t index; - instructions = &self->bytecode->instructions; + instructions = &self->bytecode.data; index = instructions->size; throw_if_error(buffer_append_empty(instructions, sizeof(AmalOpcodeType) + sizeof(reg))); @@ -151,7 +152,7 @@ static void add_ins2(BytecodeCompilerContext *self, AmalOpcode opcode, u8 reg, c static void add_ins3(BytecodeCompilerContext *self, AmalOpcode opcode, u8 dst_reg, u8 src_reg, const char *fmt) { Buffer *instructions; size_t index; - instructions = &self->bytecode->instructions; + instructions = &self->bytecode.data; index = instructions->size; throw_if_error(buffer_append_empty(instructions, sizeof(AmalOpcodeType) + sizeof(dst_reg) + sizeof(src_reg))); @@ -165,7 +166,7 @@ static void add_ins3(BytecodeCompilerContext *self, AmalOpcode opcode, u8 dst_re static void add_ins4(BytecodeCompilerContext *self, AmalOpcode opcode, u16 data, const char *fmt) { Buffer *instructions; size_t index; - instructions = &self->bytecode->instructions; + instructions = &self->bytecode.data; index = instructions->size; throw_if_error(buffer_append_empty(instructions, sizeof(AmalOpcodeType) + sizeof(data))); @@ -178,7 +179,7 @@ static void add_ins4(BytecodeCompilerContext *self, AmalOpcode opcode, u16 data, static void add_ins5(BytecodeCompilerContext *self, AmalOpcode opcode, u8 dst_reg, u8 reg1, u8 reg2, const char *fmt) { Buffer *instructions; size_t index; - instructions = &self->bytecode->instructions; + instructions = &self->bytecode.data; index = instructions->size; throw_if_error(buffer_append_empty(instructions, sizeof(AmalOpcodeType) + sizeof(dst_reg) + sizeof(reg1) + sizeof(reg2))); @@ -193,7 +194,7 @@ static void add_ins5(BytecodeCompilerContext *self, AmalOpcode opcode, u8 dst_re static void add_ins6(BytecodeCompilerContext *self, AmalOpcode opcode, u8 dst_reg, u16 data, const char *fmt) { Buffer *instructions; size_t index; - instructions = &self->bytecode->instructions; + instructions = &self->bytecode.data; index = instructions->size; throw_if_error(buffer_append_empty(instructions, sizeof(AmalOpcodeType) + sizeof(dst_reg) + sizeof(data))); @@ -237,6 +238,10 @@ static void add_instructions(BytecodeCompilerContext *self) { FILE *file; char *filename; + + u32 num_instructions_index; + num_instructions_index = self->bytecode.data.size; + throw_if_error(buffer_append_empty(&self->bytecode.data, sizeof(num_instructions_index))); #ifdef COMPILE_TO_C LhsExpr *reg_types[NUM_MAX_REGS]; /* TODO: Remove this. Encode this data in the register itself */ SsaRegister func_arg_stack[NUM_MAX_FUNC_ARGS]; /* TODO: Remove this? */ @@ -470,6 +475,14 @@ static void add_instructions(BytecodeCompilerContext *self) { assert(bool_false && "Instruction not yet implemented"); } } + + /* Prepend instructions with its size */ + { + u32 instructions_size; + instructions_size = self->bytecode.data.size - num_instructions_index; + am_memcpy(&self->bytecode.data.data[num_instructions_index], &instructions_size, sizeof(instructions_size)); + } + #endif /* COMPILE_TO_C */ fclose(file); } -- cgit v1.2.3