[前][次][番号順一覧][スレッド一覧]

ruby-changes:25423

From: shirosaki <ko1@a...>
Date: Tue, 6 Nov 2012 00:28:02 +0900 (JST)
Subject: [ruby-changes:25423] shirosaki:r37481 (trunk): Cache the expanded load path

shirosaki	2012-11-06 00:27:05 +0900 (Tue, 06 Nov 2012)

  New Revision: 37481

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37481

  Log:
    Cache the expanded load path
    
    * load.c (rb_get_expanded_load_path): cache the expanded load
      path.  This saves 4KB of allocation and some stats for every
      element of the load path (so nearly a MB in my Rails app)
      on every require.
    
    * load.c (rb_construct_expanded_load_path): ensure that $LOAD_PATH
      entries are frozen strings.  The user must mutate $LOAD_PATH
      itself rather than its individual entries.
    
    * vm_core.h (rb_vm_struct): add fields.
    
    * vm.c (rb_vm_mark): mark new fields.
    
    * ruby.c (process_options): modify $LOAD_PATH directly rather than
      its elements.
      Patch by Greg Price.
      [ruby-core:47970] [Bug #7158]

  Modified files:
    trunk/ChangeLog
    trunk/load.c
    trunk/ruby.c
    trunk/vm.c
    trunk/vm_core.h

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37480)
+++ ChangeLog	(revision 37481)
@@ -1,3 +1,23 @@
+Mon Nov  5 23:26:05 2012  Greg Price  <price@m...>
+
+	* load.c (rb_get_expanded_load_path): cache the expanded load
+	  path.  This saves 4KB of allocation and some stats for every
+	  element of the load path (so nearly a MB in my Rails app)
+	  on every require.
+
+	* load.c (rb_construct_expanded_load_path): ensure that $LOAD_PATH
+	  entries are frozen strings.  The user must mutate $LOAD_PATH
+	  itself rather than its individual entries.
+
+	* vm_core.h (rb_vm_struct): add fields.
+
+	* vm.c (rb_vm_mark): mark new fields.
+
+	* ruby.c (process_options): modify $LOAD_PATH directly rather than
+	  its elements.
+	  Patch by Greg Price.
+	  [ruby-core:47970] [Bug #7158]
+
 Mon Nov  5 23:24:42 2012  Greg Price  <price@m...>
 
 	* load.c (rb_feature_p, rb_provide_feature): index $LOADED_FEATURES
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 37480)
+++ vm_core.h	(revision 37481)
@@ -354,6 +354,8 @@
     /* load */
     VALUE top_self;
     VALUE load_path;
+    VALUE load_path_snapshot;
+    VALUE expanded_load_path;
     VALUE loaded_features;
     VALUE loaded_features_snapshot;
     VALUE loaded_features_index;
Index: load.c
===================================================================
--- load.c	(revision 37480)
+++ load.c	(revision 37481)
@@ -33,24 +33,43 @@
     return load_path;
 }
 
-VALUE
-rb_get_expanded_load_path(void)
+static void
+rb_construct_expanded_load_path(void)
 {
-    VALUE load_path = rb_get_load_path();
+    rb_vm_t *vm = GET_VM();
+    VALUE load_path = vm->load_path;
     VALUE ary;
     long i;
 
     ary = rb_ary_new2(RARRAY_LEN(load_path));
     for (i = 0; i < RARRAY_LEN(load_path); ++i) {
-	VALUE path = rb_file_expand_path_fast(RARRAY_PTR(load_path)[i], Qnil);
-	rb_str_freeze(path);
-	rb_ary_push(ary, path);
+	VALUE path, as_str, expanded_path;
+	as_str = path = RARRAY_PTR(load_path)[i];
+	StringValue(as_str);
+	if (as_str != path)
+	    rb_ary_store(load_path, i, as_str);
+	rb_str_freeze(as_str);
+	expanded_path = rb_file_expand_path_fast(as_str, Qnil);
+	rb_str_freeze(expanded_path);
+	rb_ary_push(ary, expanded_path);
     }
     rb_obj_freeze(ary);
-    return ary;
+    vm->expanded_load_path = ary;
+    rb_ary_replace(vm->load_path_snapshot, vm->load_path);
 }
 
 static VALUE
+rb_get_expanded_load_path(void)
+{
+    rb_vm_t *vm = GET_VM();
+    if (!rb_ary_shared_with_p(vm->load_path_snapshot, vm->load_path)) {
+	/* The load path was modified.	Rebuild the expanded load path. */
+	rb_construct_expanded_load_path();
+    }
+    return vm->expanded_load_path;
+}
+
+static VALUE
 load_path_getter(ID id, rb_vm_t *vm)
 {
     return vm->load_path;
@@ -942,6 +961,8 @@
     rb_alias_variable(rb_intern("$-I"), id_load_path);
     rb_alias_variable(rb_intern("$LOAD_PATH"), id_load_path);
     vm->load_path = rb_ary_new();
+    vm->expanded_load_path = rb_ary_new();
+    vm->load_path_snapshot = rb_ary_new();
 
     rb_define_virtual_variable("$\"", get_loaded_features, 0);
     rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
Index: vm.c
===================================================================
--- vm.c	(revision 37480)
+++ vm.c	(revision 37481)
@@ -1512,6 +1512,8 @@
 	RUBY_MARK_UNLESS_NULL(vm->thgroup_default);
 	RUBY_MARK_UNLESS_NULL(vm->mark_object_ary);
 	RUBY_MARK_UNLESS_NULL(vm->load_path);
+	RUBY_MARK_UNLESS_NULL(vm->load_path_snapshot);
+	RUBY_MARK_UNLESS_NULL(vm->expanded_load_path);
 	RUBY_MARK_UNLESS_NULL(vm->loaded_features);
 	RUBY_MARK_UNLESS_NULL(vm->loaded_features_snapshot);
 	RUBY_MARK_UNLESS_NULL(vm->loaded_features_index);
Index: ruby.c
===================================================================
--- ruby.c	(revision 37480)
+++ ruby.c	(revision 37481)
@@ -1418,7 +1418,8 @@
 	long i;
 	VALUE load_path = GET_VM()->load_path;
 	for (i = 0; i < RARRAY_LEN(load_path); ++i) {
-	    rb_enc_associate(RARRAY_PTR(load_path)[i], lenc);
+	    RARRAY_PTR(load_path)[i] =
+		rb_enc_associate(rb_str_dup(RARRAY_PTR(load_path)[i]), lenc);
 	}
     }
     if (!(opt->disable & DISABLE_BIT(gems))) {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]