mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
avoid iseq allocation from static irep binary. it reduces 424KB allocation for mrbtest
This commit is contained in:
+43
-16
@@ -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,14 +61,20 @@ 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 */
|
||||
for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
|
||||
cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* 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;
|
||||
|
||||
memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify));
|
||||
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);
|
||||
|
||||
+58
-26
@@ -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,10 +72,18 @@ 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;
|
||||
}
|
||||
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 */
|
||||
src += sizeof(uint32_t);
|
||||
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] = (mrb_code)bin_to_uint32(src); /* iseq */
|
||||
src += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,12 +503,25 @@ 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) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER;
|
||||
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) {
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user