diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2016-09-21 15:56:19 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2016-09-21 15:56:19 -0700 |
commit | 04445364fc9123ad40bf5581ffa4c5afac4c57dc (patch) | |
tree | 127577894550f7f99518de1e030cbefe4f8fa08b | |
parent | d81a235f33e78ef6b942788b42db073ed51fa801 (diff) | |
download | nasm-04445364fc9123ad40bf5581ffa4c5afac4c57dc.tar.gz |
incbin: if we have to fread(), try to do it only once...
If we can't mmap a file and instead have to fread(), if the data is
small enough that we can reasonably accomodate it in a memory buffer,
then just read it once.
It seems rather unlikely that very large files would be used with
TIMES anyway.
Also note: the previous comment about nasm_file_size[_by_path]() being
invoked twice was spurious; it does not actually happen.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r-- | asm/assemble.c | 18 | ||||
-rw-r--r-- | include/nasmlib.h | 2 | ||||
-rw-r--r-- | test/incbin.asm | 1 |
3 files changed, 17 insertions, 4 deletions
diff --git a/asm/assemble.c b/asm/assemble.c index 463d7378..b09f7cbb 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -544,6 +544,9 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits, return is_byte; } +/* This is totally just a wild guess what is reasonable... */ +#define INCBIN_MAX_BUF (ZERO_BUF_SIZE * 16) + int64_t assemble(int32_t segment, int64_t start, int bits, iflag_t cp, insn * instruction) { @@ -610,11 +613,13 @@ int64_t assemble(int32_t segment, int64_t start, int bits, iflag_t cp, } else if (instruction->opcode == I_INCBIN) { const char *fname = instruction->eops->stringval; FILE *fp; - static char buf[BUFSIZ]; size_t t = instruction->times; off_t base = 0; off_t len; const void *map = NULL; + char *buf = NULL; + size_t blk = 0; /* Buffered I/O block size */ + size_t m = 0; /* Bytes last read */ fp = nasm_open_read(fname, NF_BINARY|NF_FORMAP); if (!fp) { @@ -651,6 +656,10 @@ int64_t assemble(int32_t segment, int64_t start, int bits, iflag_t cp, /* Try to map file data */ map = nasm_map_file(fp, base, len); + if (!map) { + blk = len < (off_t)INCBIN_MAX_BUF ? (size_t)len : INCBIN_MAX_BUF; + buf = nasm_malloc(blk); + } while (t--) { data.insoffs = 0; @@ -658,6 +667,8 @@ int64_t assemble(int32_t segment, int64_t start, int bits, iflag_t cp, if (map) { out_rawdata(&data, map, len); + } else if ((off_t)m == len) { + out_rawdata(&data, buf, len); } else { off_t l = len; @@ -668,8 +679,7 @@ int64_t assemble(int32_t segment, int64_t start, int bits, iflag_t cp, goto end_incbin; } while (l > 0) { - size_t m = l < (off_t)sizeof(buf) ? (size_t)l : sizeof(buf); - m = fread(buf, 1, m, fp); + m = fread(buf, 1, l < (off_t)blk ? (size_t)l : blk, fp); if (!m || feof(fp)) { /* * This shouldn't happen unless the file @@ -699,6 +709,8 @@ int64_t assemble(int32_t segment, int64_t start, int bits, iflag_t cp, " reading file `%s'", fname); } close_done: + if (buf) + nasm_free(buf); if (map) nasm_unmap_file(map, len); fclose(fp); diff --git a/include/nasmlib.h b/include/nasmlib.h index e24ac1d5..b1c490ca 100644 --- a/include/nasmlib.h +++ b/include/nasmlib.h @@ -455,7 +455,7 @@ FILE *nasm_open_write(const char *filename, enum file_flags flags); /* Probe for existence of a file */ bool nasm_file_exists(const char *filename); -#define ZERO_BUF_SIZE 4096 /* Default value */ +#define ZERO_BUF_SIZE 65536 /* Default value */ #if defined(BUFSIZ) && (BUFSIZ > ZERO_BUF_SIZE) # undef ZERO_BUF_SIZE # define ZERO_BUF_SIZE BUFSIZ diff --git a/test/incbin.asm b/test/incbin.asm index 634302ea..20aa4d9f 100644 --- a/test/incbin.asm +++ b/test/incbin.asm @@ -1,5 +1,6 @@ db '*** ONCE ***', 0Ah incbin "incbin.data",32 + section more start=0x1000000 db '*** TWELVE ***', 0Ah times 12 incbin "incbin.data",32 |