summaryrefslogtreecommitdiff
path: root/load.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <[email protected]>2021-07-13 01:03:26 +0900
committerNobuyoshi Nakada <[email protected]>2021-07-24 23:59:07 +0900
commitb360588cd3cbac5fb4f004aa53a8fdc715906719 ()
treebcb42d5a7b1500df970cb5e146541841fb5e9e06 /load.c
parent971d24cd97ecf0fea542071af5ef3b134eeb4a6b (diff)
Sort feature index arrays by the priority of file types [Bug #15856]
When looking for libraries to load with a feature name without extension, `.rb` files are given priority. However, since the feature index arrays were not in that order of priority, but in the order in which they were loaded, a lower priority extension library might be returned. In that case, the `.rb` file had to be searched for again from the `$LOAD_PATH`, resulting in poor performance.
Notes: Merged: https://.com/ruby/ruby/pull/4679
-rw-r--r--load.c52
1 files changed, 45 insertions, 7 deletions
@@ -185,8 +185,17 @@ feature_key(const char *str, size_t len)
return st_hash(str, len, 0xfea7009e);
}
static void
-features_index_add_single(const char* str, size_t len, VALUE offset)
{
struct st_table *features_index;
VALUE this_feature_index = Qnil;
@@ -202,17 +211,43 @@ features_index_add_single(const char* str, size_t len, VALUE offset)
st_insert(features_index, short_feature_key, (st_data_t)offset);
}
else if (RB_TYPE_P(this_feature_index, T_FIXNUM)) {
VALUE feature_indexes[2];
- feature_indexes[0] = this_feature_index;
- feature_indexes[1] = offset;
this_feature_index = (VALUE)xcalloc(1, sizeof(struct RArray));
RBASIC(this_feature_index)->flags = T_ARRAY; /* fake VALUE, do not mark/sweep */
rb_ary_cat(this_feature_index, feature_indexes, numberof(feature_indexes));
st_insert(features_index, short_feature_key, (st_data_t)this_feature_index);
}
else {
Check_Type(this_feature_index, T_ARRAY);
rb_ary_push(this_feature_index, offset);
}
}
@@ -228,6 +263,7 @@ static void
features_index_add(VALUE feature, VALUE offset)
{
const char *feature_str, *feature_end, *ext, *p;
feature_str = StringValuePtr(feature);
feature_end = feature_str + RSTRING_LEN(feature);
@@ -237,6 +273,8 @@ features_index_add(VALUE feature, VALUE offset)
break;
if (*ext != '.')
ext = NULL;
/* Now `ext` points to the only string matching %r{^\.[^./]*$} that is
at the end of `feature`, or is NULL if there is no such string. */
@@ -248,14 +286,14 @@ features_index_add(VALUE feature, VALUE offset)
if (p < feature_str)
break;
/* Now *p == '/'. We reach this point for every '/' in `feature`. */
- features_index_add_single(p + 1, feature_end - p - 1, offset);
if (ext) {
- features_index_add_single(p + 1, ext - p - 1, offset);
}
}
- features_index_add_single(feature_str, feature_end - feature_str, offset);
if (ext) {
- features_index_add_single(feature_str, ext - feature_str, offset);
}
}