Skip to content

Commit 7639d0d

Browse files
authored
Merge pull request #437 from Shopify/less-alloc
Remove extraneous memory allocations in C
2 parents 88548cc + 0e9ce33 commit 7639d0d

File tree

1 file changed

+17
-20
lines changed

1 file changed

+17
-20
lines changed

ext/bootsnap/bootsnap.c

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,6 @@ open_cache_file(const char * path, struct bs_cache_key * key, const char ** errn
467467
static int
468468
fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE * output_data, int * exception_tag, const char ** errno_provenance)
469469
{
470-
char * data = NULL;
471470
ssize_t nread;
472471
int ret;
473472

@@ -479,8 +478,8 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE *
479478
ret = ERROR_WITH_ERRNO;
480479
goto done;
481480
}
482-
data = ALLOC_N(char, data_size);
483-
nread = read(fd, data, data_size);
481+
storage_data = rb_str_buf_new(data_size);
482+
nread = read(fd, RSTRING_PTR(storage_data), data_size);
484483
if (nread < 0) {
485484
*errno_provenance = "bs_fetch:fetch_cached_data:read";
486485
ret = ERROR_WITH_ERRNO;
@@ -491,7 +490,7 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE *
491490
goto done;
492491
}
493492

494-
storage_data = rb_str_new(data, data_size);
493+
rb_str_set_len(storage_data, nread);
495494

496495
*exception_tag = bs_storage_to_output(handler, args, storage_data, output_data);
497496
if (*output_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
@@ -500,7 +499,6 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE *
500499
}
501500
ret = 0;
502501
done:
503-
if (data != NULL) xfree(data);
504502
return ret;
505503
}
506504

@@ -607,17 +605,22 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, cons
607605

608606

609607
/* Read contents from an fd, whose contents are asserted to be +size+ bytes
610-
* long, into a buffer */
611-
static ssize_t
612-
bs_read_contents(int fd, size_t size, char ** contents, const char ** errno_provenance)
608+
* long, returning a Ruby string on success and Qfalse on failure */
609+
static VALUE
610+
bs_read_contents(int fd, size_t size, const char ** errno_provenance)
613611
{
612+
VALUE contents;
614613
ssize_t nread;
615-
*contents = ALLOC_N(char, size);
616-
nread = read(fd, *contents, size);
614+
contents = rb_str_buf_new(size);
615+
nread = read(fd, RSTRING_PTR(contents), size);
616+
617617
if (nread < 0) {
618618
*errno_provenance = "bs_fetch:bs_read_contents:read";
619+
return Qfalse;
620+
} else {
621+
rb_str_set_len(contents, nread);
622+
return contents;
619623
}
620-
return nread;
621624
}
622625

623626
/*
@@ -668,7 +671,6 @@ static VALUE
668671
bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args)
669672
{
670673
struct bs_cache_key cached_key, current_key;
671-
char * contents = NULL;
672674
int cache_fd = -1, current_fd = -1;
673675
int res, valid_cache = 0, exception_tag = 0;
674676
const char * errno_provenance = NULL;
@@ -713,8 +715,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
713715
else if (res == CACHE_UNCOMPILABLE) {
714716
/* If fetch_cached_data returned `Uncompilable` we fallback to `input_to_output`
715717
This happens if we have say, an unsafe YAML cache, but try to load it in safe mode */
716-
if (bs_read_contents(current_fd, current_key.size, &contents, &errno_provenance) < 0) goto fail_errno;
717-
input_data = rb_str_new(contents, current_key.size);
718+
if ((input_data = bs_read_contents(current_fd, current_key.size, &errno_provenance)) == Qfalse) goto fail_errno;
718719
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
719720
if (exception_tag != 0) goto raise;
720721
goto succeed;
@@ -727,8 +728,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
727728
/* Cache is stale, invalid, or missing. Regenerate and write it out. */
728729

729730
/* Read the contents of the source file into a buffer */
730-
if (bs_read_contents(current_fd, current_key.size, &contents, &errno_provenance) < 0) goto fail_errno;
731-
input_data = rb_str_new(contents, current_key.size);
731+
if ((input_data = bs_read_contents(current_fd, current_key.size, &errno_provenance)) == Qfalse) goto fail_errno;
732732

733733
/* Try to compile the input_data using input_to_storage(input_data) */
734734
exception_tag = bs_input_to_storage(handler, args, input_data, path_v, &storage_data);
@@ -775,7 +775,6 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
775775
goto succeed; /* output_data is now the correct return. */
776776

777777
#define CLEANUP \
778-
if (contents != NULL) xfree(contents); \
779778
if (current_fd >= 0) close(current_fd); \
780779
if (cache_fd >= 0) close(cache_fd);
781780

@@ -836,8 +835,7 @@ bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE handler)
836835
/* Cache is stale, invalid, or missing. Regenerate and write it out. */
837836

838837
/* Read the contents of the source file into a buffer */
839-
if (bs_read_contents(current_fd, current_key.size, &contents, &errno_provenance) < 0) goto fail;
840-
input_data = rb_str_new(contents, current_key.size);
838+
if ((input_data = bs_read_contents(current_fd, current_key.size, &errno_provenance)) == Qfalse) goto fail;
841839

842840
/* Try to compile the input_data using input_to_storage(input_data) */
843841
exception_tag = bs_input_to_storage(handler, Qnil, input_data, path_v, &storage_data);
@@ -858,7 +856,6 @@ bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE handler)
858856
goto succeed;
859857

860858
#define CLEANUP \
861-
if (contents != NULL) xfree(contents); \
862859
if (current_fd >= 0) close(current_fd); \
863860
if (cache_fd >= 0) close(cache_fd);
864861

0 commit comments

Comments
 (0)