Project

General

Profile

0001-Use-shared-substrings-in-feature-index-cache-hash.patch

tenderlovemaking (Aaron Patterson), 02/10/2018 12:31 AM

View differences:

load.c
166 166
    return GET_VM()->loaded_features_index;
167 167
}
168 168

  
169
static VALUE
170
get_loaded_features_index_pool_raw(void)
171
{
172
    return GET_VM()->loaded_features_index_pool;
173
}
174

  
169 175
static st_table *
170 176
get_loading_table(void)
171 177
{
......
173 179
}
174 180

  
175 181
static void
176
features_index_add_single(VALUE short_feature, VALUE offset)
182
features_index_add_single(const char *short_feature_cstr, VALUE offset)
177 183
{
178 184
    struct st_table *features_index;
179 185
    VALUE this_feature_index = Qnil;
180
    char *short_feature_cstr;
181 186

  
182 187
    Check_Type(offset, T_FIXNUM);
183
    Check_Type(short_feature, T_STRING);
184
    short_feature_cstr = StringValueCStr(short_feature);
185 188

  
186 189
    features_index = get_loaded_features_index_raw();
187 190
    st_lookup(features_index, (st_data_t)short_feature_cstr, (st_data_t *)&this_feature_index);
188 191

  
189 192
    if (NIL_P(this_feature_index)) {
190
	st_insert(features_index, (st_data_t)ruby_strdup(short_feature_cstr), (st_data_t)offset);
193
	st_insert(features_index, (st_data_t)short_feature_cstr, (st_data_t)offset);
191 194
    }
192 195
    else if (RB_TYPE_P(this_feature_index, T_FIXNUM)) {
193 196
	VALUE feature_indexes[2];
......
215 218
static void
216 219
features_index_add(VALUE feature, VALUE offset)
217 220
{
218
    VALUE short_feature;
219
    const char *feature_str, *feature_end, *ext, *p;
221
    VALUE short_feature_no_ext;
222
    const char *feature_str, *feature_end, *feature_no_ext_str, *ext, *p;
220 223

  
221 224
    feature_str = StringValuePtr(feature);
222 225
    feature_end = feature_str + RSTRING_LEN(feature);
......
229 232
    /* Now `ext` points to the only string matching %r{^\.[^./]*$} that is
230 233
       at the end of `feature`, or is NULL if there is no such string. */
231 234

  
232
    p = ext ? ext : feature_end;
235
    if (ext) {
236
	p = ext;
237
	short_feature_no_ext = rb_fstring(rb_str_freeze(rb_str_subseq(feature, 0, ext - feature_str)));
238
	feature_no_ext_str = StringValuePtr(short_feature_no_ext);
239
	rb_ary_push(get_loaded_features_index_pool_raw(), short_feature_no_ext);
240
    } else {
241
	p = feature_end;
242
	short_feature_no_ext = Qnil;
243
    }
244

  
233 245
    while (1) {
234 246
	long beg;
235 247

  
......
240 252
	    break;
241 253
	/* Now *p == '/'.  We reach this point for every '/' in `feature`. */
242 254
	beg = p + 1 - feature_str;
243
	short_feature = rb_str_subseq(feature, beg, feature_end - p - 1);
244
	features_index_add_single(short_feature, offset);
255
	features_index_add_single(feature_str + beg, offset);
245 256
	if (ext) {
246
	    short_feature = rb_str_subseq(feature, beg, ext - p - 1);
247
	    features_index_add_single(short_feature, offset);
257
	    features_index_add_single(feature_no_ext_str + beg, offset);
248 258
	}
249 259
    }
250
    features_index_add_single(feature, offset);
260
    features_index_add_single(feature_str, offset);
251 261
    if (ext) {
252
	short_feature = rb_str_subseq(feature, 0, ext - feature_str);
253
	features_index_add_single(short_feature, offset);
262
	features_index_add_single(feature_no_ext_str, offset);
254 263
    }
255 264
}
256 265

  
......
262 271
	rb_ary_free(obj);
263 272
	xfree((void *)obj);
264 273
    }
265
    xfree((char *)key);
266 274
    return ST_DELETE;
267 275
}
268 276

  
......
277 285
	/* The sharing was broken; something (other than us in rb_provide_feature())
278 286
	   modified loaded_features.  Rebuild the index. */
279 287
	st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
288
	rb_ary_clear(vm->loaded_features_index_pool);
280 289
	features = vm->loaded_features;
281 290
	for (i = 0; i < RARRAY_LEN(features); i++) {
282 291
	    VALUE entry, as_str;
......
1193 1202
    vm->loaded_features = rb_ary_new();
1194 1203
    vm->loaded_features_snapshot = rb_ary_tmp_new(0);
1195 1204
    vm->loaded_features_index = st_init_strtable();
1205
    vm->loaded_features_index_pool = rb_ary_new();
1196 1206

  
1197 1207
    rb_define_global_function("load", rb_f_load, -1);
1198 1208
    rb_define_global_function("require", rb_f_require, 1);
vm.c
2130 2130
	rb_gc_mark(vm->expanded_load_path);
2131 2131
	rb_gc_mark(vm->loaded_features);
2132 2132
	rb_gc_mark(vm->loaded_features_snapshot);
2133
	rb_gc_mark(vm->loaded_features_index_pool);
2133 2134
	rb_gc_mark(vm->top_self);
2134 2135
	RUBY_MARK_UNLESS_NULL(vm->coverages);
2135 2136
	rb_gc_mark(vm->defined_module_hash);
vm_core.h
560 560
    VALUE expanded_load_path;
561 561
    VALUE loaded_features;
562 562
    VALUE loaded_features_snapshot;
563
    VALUE loaded_features_index_pool;
563 564
    struct st_table *loaded_features_index;
564 565
    struct st_table *loading_table;
565 566

  
566
-