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>
This commit is contained in:
H. Peter Anvin 2016-09-21 15:56:19 -07:00
parent d81a235f33
commit 04445364fc
3 changed files with 17 additions and 4 deletions

View file

@ -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);

View file

@ -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

View file

@ -1,5 +1,6 @@
db '*** ONCE ***', 0Ah
incbin "incbin.data",32
section more start=0x1000000
db '*** TWELVE ***', 0Ah
times 12 incbin "incbin.data",32