mirror of
https://github.com/ruby/ruby.git
synced 2026-08-02 20:49:12 +08:00
file.c: right size the rb_find_file_ext & rb_find_file buffer
It generally end up frozen in `$LOADED_FEATURES` so it's preferable to predict its size and only deal with an embedded string most of the time. It saves on having to allocate a `MAXPATHLEN + 2` (1026) bytes long buffer and then realloc it later to shink it.
This commit is contained in:
parent
1c1dafa769
commit
d17f8ecd19
Notes:
git
2026-06-19 19:20:34 +00:00
10
file.c
10
file.c
@ -7108,13 +7108,14 @@ rb_find_file_ext(VALUE *filep, const char *const *ext)
|
||||
return 0;
|
||||
}
|
||||
|
||||
RB_GC_GUARD(load_path) = rb_get_expanded_load_path();
|
||||
long expanded_load_path_maxlen;
|
||||
RB_GC_GUARD(load_path) = rb_get_expanded_load_path(&expanded_load_path_maxlen);
|
||||
if (!load_path) return 0;
|
||||
|
||||
fname = rb_str_dup(*filep);
|
||||
RBASIC_CLEAR_CLASS(fname);
|
||||
fnlen = RSTRING_LEN(fname);
|
||||
tmp = rb_str_tmp_new(MAXPATHLEN + 2);
|
||||
tmp = rb_str_tmp_new(expanded_load_path_maxlen + fnlen + 2);
|
||||
rb_enc_associate_index(tmp, rb_usascii_encindex());
|
||||
for (j=0; ext[j]; j++) {
|
||||
rb_str_cat2(fname, ext[j]);
|
||||
@ -7157,11 +7158,12 @@ rb_find_file(VALUE path)
|
||||
return path;
|
||||
}
|
||||
|
||||
RB_GC_GUARD(load_path) = rb_get_expanded_load_path();
|
||||
long expanded_load_path_maxlen;
|
||||
RB_GC_GUARD(load_path) = rb_get_expanded_load_path(&expanded_load_path_maxlen);
|
||||
if (load_path) {
|
||||
long i;
|
||||
|
||||
tmp = rb_str_tmp_new(MAXPATHLEN + 2);
|
||||
tmp = rb_str_tmp_new(expanded_load_path_maxlen + RSTRING_LEN(path) + 2);
|
||||
rb_enc_associate_index(tmp, rb_usascii_encindex());
|
||||
for (i = 0; i < RARRAY_LEN(load_path); i++) {
|
||||
VALUE str = RARRAY_AREF(load_path, i);
|
||||
|
||||
@ -25,6 +25,7 @@ struct rb_box_struct {
|
||||
VALUE load_path_snapshot;
|
||||
VALUE load_path_check_cache;
|
||||
VALUE expanded_load_path;
|
||||
long expanded_load_path_maxlen;
|
||||
VALUE loaded_features;
|
||||
VALUE loaded_features_snapshot;
|
||||
VALUE loaded_features_realpaths;
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#include "ruby/ruby.h" /* for VALUE */
|
||||
|
||||
/* load.c */
|
||||
VALUE rb_get_expanded_load_path(void);
|
||||
VALUE rb_get_expanded_load_path(long *maxlen);
|
||||
VALUE rb_load_entrypoint(VALUE fname, VALUE wrap);
|
||||
VALUE rb_require_relative_entrypoint(VALUE fname);
|
||||
int rb_require_internal(VALUE fname);
|
||||
|
||||
33
load.c
33
load.c
@ -55,13 +55,13 @@ enum expand_type {
|
||||
string objects in $LOAD_PATH are frozen.
|
||||
*/
|
||||
static void
|
||||
rb_construct_expanded_load_path(rb_box_t *box, enum expand_type type, int *has_relative, int *has_non_cache)
|
||||
rb_construct_expanded_load_path(rb_box_t *box, enum expand_type type, int *has_relative, int *has_non_cache, long *maxlen_out)
|
||||
{
|
||||
VALUE load_path = box->load_path;
|
||||
VALUE expanded_load_path = box->expanded_load_path;
|
||||
VALUE snapshot;
|
||||
VALUE ary;
|
||||
long i;
|
||||
long i, maxlen = 0;
|
||||
|
||||
ary = rb_ary_hidden_new(RARRAY_LEN(load_path));
|
||||
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
|
||||
@ -81,7 +81,10 @@ rb_construct_expanded_load_path(rb_box_t *box, enum expand_type type, int *has_r
|
||||
(!as_cstr[0] || as_cstr[0] != '~')) ||
|
||||
(type == EXPAND_NON_CACHE)) {
|
||||
/* Use cached expanded path. */
|
||||
rb_ary_push(ary, RARRAY_AREF(expanded_load_path, i));
|
||||
expanded_path = RARRAY_AREF(expanded_load_path, i);
|
||||
long len = RSTRING_LEN(expanded_path);
|
||||
if (len > maxlen) maxlen = len;
|
||||
rb_ary_push(ary, expanded_path);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -95,12 +98,15 @@ rb_construct_expanded_load_path(rb_box_t *box, enum expand_type type, int *has_r
|
||||
as_str = rb_get_path_check_convert(as_str);
|
||||
expanded_path = rb_check_realpath(Qnil, as_str, NULL);
|
||||
if (NIL_P(expanded_path)) expanded_path = as_str;
|
||||
long len = RSTRING_LEN(expanded_path);
|
||||
if (len > maxlen) maxlen = len;
|
||||
rb_ary_push(ary, rb_fstring(expanded_path));
|
||||
}
|
||||
rb_ary_freeze(ary);
|
||||
box->expanded_load_path = ary;
|
||||
snapshot = box->load_path_snapshot;
|
||||
load_path = box->load_path;
|
||||
*maxlen_out = maxlen;
|
||||
rb_ary_replace(snapshot, load_path);
|
||||
}
|
||||
|
||||
@ -111,11 +117,12 @@ get_expanded_load_path(rb_box_t *box)
|
||||
const VALUE non_cache = Qtrue;
|
||||
const VALUE load_path_snapshot = box->load_path_snapshot;
|
||||
const VALUE load_path = box->load_path;
|
||||
long maxlen = 0;
|
||||
|
||||
if (!rb_ary_shared_with_p(load_path_snapshot, load_path)) {
|
||||
/* The load path was modified. Rebuild the expanded load path. */
|
||||
int has_relative = 0, has_non_cache = 0;
|
||||
rb_construct_expanded_load_path(box, EXPAND_ALL, &has_relative, &has_non_cache);
|
||||
rb_construct_expanded_load_path(box, EXPAND_ALL, &has_relative, &has_non_cache, &maxlen);
|
||||
if (has_relative) {
|
||||
box->load_path_check_cache = rb_dir_getwd_ospath();
|
||||
}
|
||||
@ -131,7 +138,7 @@ get_expanded_load_path(rb_box_t *box)
|
||||
int has_relative = 1, has_non_cache = 1;
|
||||
/* Expand only non-cacheable objects. */
|
||||
rb_construct_expanded_load_path(box, EXPAND_NON_CACHE,
|
||||
&has_relative, &has_non_cache);
|
||||
&has_relative, &has_non_cache, &maxlen);
|
||||
}
|
||||
else if (check_cache) {
|
||||
int has_relative = 1, has_non_cache = 1;
|
||||
@ -141,21 +148,29 @@ get_expanded_load_path(rb_box_t *box)
|
||||
Expand relative load path and non-cacheable objects again. */
|
||||
box->load_path_check_cache = cwd;
|
||||
rb_construct_expanded_load_path(box, EXPAND_RELATIVE,
|
||||
&has_relative, &has_non_cache);
|
||||
&has_relative, &has_non_cache, &maxlen);
|
||||
}
|
||||
else {
|
||||
/* Expand only tilde (User HOME) and non-cacheable objects. */
|
||||
rb_construct_expanded_load_path(box, EXPAND_HOME,
|
||||
&has_relative, &has_non_cache);
|
||||
&has_relative, &has_non_cache, &maxlen);
|
||||
}
|
||||
}
|
||||
if (maxlen) {
|
||||
box->expanded_load_path_maxlen = maxlen;
|
||||
}
|
||||
return box->expanded_load_path;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_get_expanded_load_path(void)
|
||||
rb_get_expanded_load_path(long *maxlen)
|
||||
{
|
||||
return get_expanded_load_path((rb_box_t *)rb_loading_box());
|
||||
rb_box_t *box = (rb_box_t *)rb_loading_box();
|
||||
VALUE load_path = get_expanded_load_path((rb_box_t *)box);
|
||||
if (maxlen) {
|
||||
*maxlen = box->expanded_load_path_maxlen;
|
||||
}
|
||||
return load_path;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
||||
2
ruby.c
2
ruby.c
@ -2540,7 +2540,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
|
||||
const ID id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
|
||||
int modifiable = FALSE;
|
||||
|
||||
rb_get_expanded_load_path();
|
||||
rb_get_expanded_load_path(NULL);
|
||||
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
|
||||
VALUE path = RARRAY_AREF(load_path, i);
|
||||
int mark = rb_attr_get(path, id_initial_load_path_mark) == path;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user