avoid iseq allocation from static irep binary. it reduces 424KB allocation for mrbtest

parent dc3c91df
......@@ -13,6 +13,9 @@
#include "mruby/numeric.h"
#include "mruby/debug.h"
#define FLAG_BYTEORDER_NATIVE 2
#define FLAG_BYTEORDER_NONATIVE 0
#ifdef ENABLE_STDIO
static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep);
......@@ -58,15 +61,21 @@ get_iseq_block_size(mrb_state *mrb, mrb_irep *irep)
}
static ptrdiff_t
write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags)
{
uint8_t *cur = buf;
uint32_t iseq_no;
cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */
if (flags & FLAG_BYTEORDER_NATIVE) {
memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code));
cur += irep->ilen * sizeof(mrb_code);
}
else {
for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
}
}
return cur - buf;
}
......@@ -263,7 +272,7 @@ get_irep_record_size(mrb_state *mrb, mrb_irep *irep)
}
static int
write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size)
write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size, uint8_t flags)
{
uint32_t i;
......@@ -279,7 +288,7 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_rec
memset(bin, 0, *irep_record_size);
bin += write_irep_header(mrb, irep, bin);
bin += write_iseq_block(mrb, irep, bin);
bin += write_iseq_block(mrb, irep, bin, flags);
bin += write_pool_block(mrb, irep, bin);
bin += write_syms_block(mrb, irep, bin);
......@@ -287,7 +296,7 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_rec
int result;
size_t rsize;
result = write_irep_record(mrb, irep->reps[i], bin, &rsize);
result = write_irep_record(mrb, irep->reps[i], bin, &rsize, flags);
if (result != MRB_DUMP_OK) {
return result;
}
......@@ -325,7 +334,7 @@ write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin)
}
static int
write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, uint8_t flags)
{
int result;
size_t section_size = 0; /* size of irep record */
......@@ -339,7 +348,7 @@ write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
cur += sizeof(struct rite_section_irep_header);
section_size += sizeof(struct rite_section_irep_header);
result = write_irep_record(mrb, irep, cur, &rsize);
result = write_irep_record(mrb, irep, cur, &rsize, flags);
if (result != MRB_DUMP_OK) {
return result;
}
......@@ -795,13 +804,25 @@ lv_section_exit:
}
static int
write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin)
write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags)
{
struct rite_binary_header *header = (struct rite_binary_header *)bin;
uint16_t crc;
uint32_t offset;
if (flags & FLAG_BYTEORDER_NATIVE) {
uint32_t ident = 0;
size_t i;
for(i=0; i<sizeof(ident); i++) {
ident<<=8;
ident|=RITE_BINARY_IDENTIFIER[i];
}
memcpy(header->binary_identify, (char*)&ident, sizeof(uint32_t));
}
else {
memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify));
}
memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version));
memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name));
memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version));
......@@ -841,8 +862,8 @@ is_lv_defined(mrb_irep *irep)
return FALSE;
}
int
mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size)
static int
dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size, uint8_t flags)
{
int result = MRB_DUMP_GENERAL_FAILURE;
size_t section_irep_size;
......@@ -891,7 +912,7 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
cur = *bin = (uint8_t*)mrb_malloc(mrb, *bin_size);
cur += sizeof(struct rite_binary_header);
result = write_section_irep(mrb, irep, cur);
result = write_section_irep(mrb, irep, cur, flags);
if (result != MRB_DUMP_OK) {
goto error_exit;
}
......@@ -920,7 +941,7 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
}
write_footer(mrb, cur);
write_rite_binary_header(mrb, *bin_size, *bin);
write_rite_binary_header(mrb, *bin_size, *bin, flags);
error_exit:
if (result != MRB_DUMP_OK) {
......@@ -936,6 +957,12 @@ error_exit:
return result;
}
int
mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size)
{
return dump_irep(mrb, irep, debug_info, bin, bin_size, FLAG_BYTEORDER_NONATIVE);
}
int
mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp)
{
......@@ -947,7 +974,7 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp)
return MRB_DUMP_INVALID_ARGUMENT;
}
result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size);
result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NATIVE);
if (result == MRB_DUMP_OK) {
if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) {
result = MRB_DUMP_WRITE_FAULT;
......@@ -985,7 +1012,7 @@ mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE *fp, co
return MRB_DUMP_INVALID_ARGUMENT;
}
result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size);
result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NATIVE);
if (result == MRB_DUMP_OK) {
if (fprintf(fp, "#include <stdint.h>\n") < 0) { /* for uint8_t under at least Darwin */
mrb_free(mrb, bin);
......
......@@ -14,6 +14,11 @@
#include "mruby/debug.h"
#include "mruby/error.h"
#define FLAG_BYTEORDER_NATIVE 2
#define FLAG_BYTEORDER_NONATIVE 0
#define FLAG_SRC_MALLOC 1
#define FLAG_SRC_STATIC 0
#if !defined(_WIN32) && SIZE_MAX < UINT32_MAX
# define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y))
# define SIZE_ERROR(x) ((x) > SIZE_MAX)
......@@ -34,7 +39,7 @@ offset_crc_body(void)
}
static mrb_irep*
read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc)
read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
{
size_t i;
const uint8_t *src = bin;
......@@ -67,12 +72,20 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all
if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) {
return NULL;
}
if (!(flags & FLAG_SRC_MALLOC) &&
(flags & FLAG_BYTEORDER_NATIVE)) {
irep->iseq = (mrb_code*)src;
src += sizeof(uint32_t) * irep->ilen;
irep->flags |= MRB_ISEQ_NO_FREE;
}
else {
irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen);
for (i = 0; i < irep->ilen; i++) {
irep->iseq[i] = (size_t)bin_to_uint32(src); /* iseq */
irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */
src += sizeof(uint32_t);
}
}
}
/* POOL BLOCK */
plen = (size_t)bin_to_uint32(src); /* number of pool */
......@@ -89,7 +102,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all
tt = *src++; /* pool TT */
pool_data_len = bin_to_uint16(src); /* pool data length */
src += sizeof(uint16_t);
if (alloc) {
if (flags & FLAG_SRC_MALLOC) {
s = mrb_str_new(mrb, (char *)src, pool_data_len);
}
else {
......@@ -137,7 +150,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all
continue;
}
if (alloc) {
if (flags & FLAG_SRC_MALLOC) {
irep->syms[i] = mrb_intern(mrb, (char *)src, snl);
}
else {
......@@ -159,9 +172,9 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all
}
static mrb_irep*
read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc)
read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
{
mrb_irep *irep = read_irep_record_1(mrb, bin, len, alloc);
mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags);
size_t i;
if (irep == NULL) {
......@@ -172,7 +185,7 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc
for (i=0; i<irep->rlen; i++) {
size_t rlen;
irep->reps[i] = read_irep_record(mrb, bin, &rlen, alloc);
irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags);
if (irep->reps[i] == NULL) {
return NULL;
}
......@@ -183,12 +196,12 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc
}
static mrb_irep*
read_section_irep(mrb_state *mrb, const uint8_t *bin, mrb_bool alloc)
read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
{
size_t len;
bin += sizeof(struct rite_section_irep_header);
return read_irep_record(mrb, bin, &len, alloc);
return read_irep_record(mrb, bin, &len, flags);
}
static int
......@@ -357,7 +370,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
}
static int
read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc)
read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
{
const uint8_t *bin;
ptrdiff_t diff;
......@@ -378,7 +391,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_boo
for (i = 0; i < filenames_len; ++i) {
uint16_t f_len = bin_to_uint16(bin);
bin += sizeof(uint16_t);
if (alloc) {
if (flags & FLAG_SRC_MALLOC) {
filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len);
}
else {
......@@ -446,7 +459,7 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec
}
static int
read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc)
read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
{
const uint8_t *bin;
ptrdiff_t diff;
......@@ -456,7 +469,8 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool a
int result;
uint32_t syms_len;
mrb_sym *syms;
mrb_sym (*intern_func)(mrb_state*, const char*, size_t) = alloc? mrb_intern : mrb_intern_static;
mrb_sym (*intern_func)(mrb_state*, const char*, size_t) =
(flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static;
bin = start;
header = (struct rite_section_lv_header const*)bin;
......@@ -489,13 +503,26 @@ lv_exit:
}
static int
read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc)
read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, mrb_bool *byteorder)
{
const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
*byteorder = FALSE;
if (memcmp(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)) != 0) {
uint32_t ident = 0;
size_t i;
for(i=0; i<sizeof(ident); i++) {
ident<<=8;
ident|=RITE_BINARY_IDENTIFIER[i];
}
if (ident == *(uint32_t*)header->binary_identify) {
*byteorder = TRUE;
}
else {
return MRB_DUMP_INVALID_FILE_HEADER;
}
}
if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) {
return MRB_DUMP_INVALID_FILE_HEADER;
......@@ -518,15 +545,20 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
uint16_t crc;
size_t bin_size = 0;
size_t n;
mrb_bool byteorder;
uint8_t flags = FLAG_SRC_STATIC;
if ((mrb == NULL) || (bin == NULL)) {
return NULL;
}
result = read_binary_header(bin, &bin_size, &crc);
result = read_binary_header(bin, &bin_size, &crc, &byteorder);
if (result != MRB_DUMP_OK) {
return NULL;
}
if (byteorder) {
flags |= FLAG_BYTEORDER_NATIVE;
}
n = offset_crc_body();
if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) {
......@@ -537,7 +569,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
do {
section_header = (const struct rite_section_header *)bin;
if (memcmp(section_header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
irep = read_section_irep(mrb, bin, FALSE);
irep = read_section_irep(mrb, bin, flags);
if (!irep) return NULL;
}
else if (memcmp(section_header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
......@@ -549,14 +581,14 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
}
else if (memcmp(section_header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
if (!irep) return NULL; /* corrupted data */
result = read_section_debug(mrb, bin, irep, FALSE);
result = read_section_debug(mrb, bin, irep, flags);
if (result < MRB_DUMP_OK) {
return NULL;
}
}
else if (memcmp(section_header->section_identify, RITE_SECTION_LV_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
if (!irep) return NULL;
result = read_section_lv(mrb, bin, irep, FALSE);
result = read_section_lv(mrb, bin, irep, flags);
if (result < MRB_DUMP_OK) {
return NULL;
}
......@@ -668,7 +700,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp)
if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) {
return NULL;
}
irep = read_irep_record_1(mrb, buf, &len, TRUE);
irep = read_irep_record_1(mrb, buf, &len, FLAG_SRC_MALLOC);
mrb_free(mrb, ptr);
if (!irep) return NULL;
for (i=0; i<irep->rlen; i++) {
......@@ -715,7 +747,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
mrb_free(mrb, buf);
return NULL;
}
result = read_binary_header(buf, NULL, &crc);
result = read_binary_header(buf, NULL, &crc, NULL);
mrb_free(mrb, buf);
if (result != MRB_DUMP_OK) {
return NULL;
......@@ -773,7 +805,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
mrb_free(mrb, bin);
return NULL;
}
result = read_section_debug(mrb, bin, irep, TRUE);
result = read_section_debug(mrb, bin, irep, FLAG_SRC_MALLOC);
mrb_free(mrb, bin);
}
if (result < MRB_DUMP_OK) return NULL;
......@@ -788,7 +820,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
mrb_free(mrb, bin);
return NULL;
}
result = read_section_lv(mrb, bin, irep, TRUE);
result = read_section_lv(mrb, bin, irep, FLAG_SRC_MALLOC);
mrb_free(mrb, bin);
}
if (result < MRB_DUMP_OK) return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment