summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-09-04 17:16:34 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-09-04 17:16:34 +0900
commit3492be401a16ff661beefd03c9f152744900e5c0 (patch)
treec7306cedebad115eaccc9dbcd64ca696bc95440e /src
parentdc3c91dfdc25a63fef647464530f0ae4778a3687 (diff)
downloadmruby-3492be401a16ff661beefd03c9f152744900e5c0.tar.gz
mruby-3492be401a16ff661beefd03c9f152744900e5c0.zip
avoid iseq allocation from static irep binary. it reduces 424KB allocation for mrbtest
Diffstat (limited to 'src')
-rw-r--r--src/dump.c59
-rw-r--r--src/load.c84
2 files changed, 101 insertions, 42 deletions
diff --git a/src/dump.c b/src/dump.c
index f529c4f02..905bfc72b 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -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) {
@@ -937,6 +958,12 @@ error_exit:
}
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)
{
uint8_t *bin = NULL;
@@ -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);
diff --git a/src/load.c b/src/load.c
index 9e8325022..80fc719c2 100644
--- a/src/load.c
+++ b/src/load.c
@@ -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;