0004-Cache-the-expanded-load-path.patch

Patch 4 - cache for $LOAD_PATH - Greg Price, 10/14/2012 01:56 PM

Download (4.33 KB)

View differences:

ChangeLog
1
Mon Sep 10 10:28:36 2012  Greg Price  <price@mit.edu>
2

  
3
	* load.c (rb_get_expanded_load_path): cache the expanded load
4
	  path.  This saves 4KB of allocation and some stats for every
5
	  element of the load path (so nearly a MB in my Rails app)
6
	  on every require.
7

  
8
	* load.c (rb_construct_expanded_load_path): ensure that $LOAD_PATH
9
	  entries are frozen strings.  The user must mutate $LOAD_PATH
10
	  itself rather than its individual entries.
11

  
12
	* vm_core.h (rb_vm_struct): add fields.
13

  
14
	* vm.c (rb_vm_mark): mark new fields.
15

  
16
	* ruby.c (process_options): modify $LOAD_PATH directly rather than
17
	  its elements.
18

  
1 19
Tue Sep  4 14:15:18 2012  Greg Price  <price@mit.edu>
2 20

  
3 21
	* load.c (rb_feature_p, rb_provide_feature, et al.):
load.c
33 33
    return load_path;
34 34
}
35 35

  
36
VALUE
37
rb_get_expanded_load_path(void)
36
static void
37
rb_construct_expanded_load_path(void)
38 38
{
39
    VALUE load_path = rb_get_load_path();
39
    rb_vm_t *vm = GET_VM();
40
    VALUE load_path = vm->load_path;
40 41
    VALUE ary;
41 42
    long i;
42 43

  
43 44
    ary = rb_ary_new2(RARRAY_LEN(load_path));
44 45
    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
45
	VALUE path = rb_file_expand_path_fast(RARRAY_PTR(load_path)[i], Qnil);
46
	rb_str_freeze(path);
47
	rb_ary_push(ary, path);
46
	VALUE path, as_str, expanded_path;
47
	as_str = path = RARRAY_PTR(load_path)[i];
48
	StringValue(as_str);
49
	if (as_str != path)
50
	    rb_ary_store(load_path, i, as_str);
51
	rb_str_freeze(as_str);
52
	expanded_path = rb_file_expand_path_fast(as_str, Qnil);
53
	rb_str_freeze(expanded_path);
54
	rb_ary_push(ary, expanded_path);
48 55
    }
49 56
    rb_obj_freeze(ary);
50
    return ary;
57
    vm->expanded_load_path = ary;
58
    rb_ary_replace(vm->load_path_snapshot, vm->load_path);
59
}
60

  
61
static VALUE
62
rb_get_expanded_load_path(void)
63
{
64
    rb_vm_t *vm = GET_VM();
65
    if (!rb_ary_shared_with_p(vm->load_path_snapshot, vm->load_path)) {
66
	/* The load path was modified.	Rebuild the expanded load path. */
67
	rb_construct_expanded_load_path();
68
    }
69
    return vm->expanded_load_path;
51 70
}
52 71

  
53 72
static VALUE
......
941 960
    rb_alias_variable(rb_intern("$-I"), id_load_path);
942 961
    rb_alias_variable(rb_intern("$LOAD_PATH"), id_load_path);
943 962
    vm->load_path = rb_ary_new();
963
    vm->expanded_load_path = rb_ary_new();
964
    vm->load_path_snapshot = rb_ary_new();
944 965

  
945 966
    rb_define_virtual_variable("$\"", get_loaded_features, 0);
946 967
    rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
ruby.c
1377 1377
	long i;
1378 1378
	VALUE load_path = GET_VM()->load_path;
1379 1379
	for (i = 0; i < RARRAY_LEN(load_path); ++i) {
1380
	    rb_enc_associate(RARRAY_PTR(load_path)[i], lenc);
1380
	    RARRAY_PTR(load_path)[i] =
1381
		rb_enc_associate(rb_str_dup(RARRAY_PTR(load_path)[i]), lenc);
1381 1382
	}
1382 1383
    }
1383 1384
    if (!(opt->disable & DISABLE_BIT(gems))) {
vm.c
1500 1500
	RUBY_MARK_UNLESS_NULL(vm->thgroup_default);
1501 1501
	RUBY_MARK_UNLESS_NULL(vm->mark_object_ary);
1502 1502
	RUBY_MARK_UNLESS_NULL(vm->load_path);
1503
	RUBY_MARK_UNLESS_NULL(vm->load_path_snapshot);
1504
	RUBY_MARK_UNLESS_NULL(vm->expanded_load_path);
1503 1505
	RUBY_MARK_UNLESS_NULL(vm->loaded_features);
1504 1506
	RUBY_MARK_UNLESS_NULL(vm->loaded_features_snapshot);
1505 1507
	RUBY_MARK_UNLESS_NULL(vm->loaded_features_index);
vm_core.h
321 321
    /* load */
322 322
    VALUE top_self;
323 323
    VALUE load_path;
324
    VALUE load_path_snapshot;
325
    VALUE expanded_load_path;
324 326
    VALUE loaded_features;
325 327
    VALUE loaded_features_snapshot;
326 328
    VALUE loaded_features_index;
327
-