dumping ground for random patches and texts
 help / color / mirror / Atom feed
* [PATCH] introduce rb_autoload_value to replace rb_autoload
@ 2015-11-06  3:46 Eric Wong
  0 siblings, 0 replies; 2+ messages in thread
From: Eric Wong @ 2015-11-06  3:46 UTC (permalink / raw)
  To: spew

rb_autoload_value may be safer by preventing premature GC.  It
can also be more efficient by passing a pre-frozen string that
can be deduped using rb_fstring.  Common autoload callers (e.g.
rubygems, rdoc) already use string literals as the file
argument.

There seems to be no reason to expose rb_autoload_value to the
public C API since autoload is not performance-critical.
Applications may declare autoloads in Ruby code or via
rb_funcall; so merely deprecate rb_autoload without exposing
rb_autoload_value to new users.

Running: valgrind -v ruby -rrdoc -rubygems -e exit
shows a minor memory reduction (32-bit userspace)

before:

  in use at exit: 1,600,621 bytes in 28,819 blocks
total heap usage: 55,786 allocs, 26,967 frees, 6,693,790 bytes allocated

after:

  in use at exit: 1,599,778 bytes in 28,789 blocks
total heap usage: 55,739 allocs, 26,950 frees, 6,692,973 bytes allocated
---
 include/ruby/intern.h |  2 +-
 internal.h            |  1 +
 load.c                |  2 +-
 thread_pthread.c      |  2 +-
 variable.c            | 24 ++++++++++++++++++------
 5 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index af6b75d..d2ac732 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -935,7 +935,7 @@ VALUE rb_path_to_class(VALUE);
 VALUE rb_path2class(const char*);
 void rb_name_class(VALUE, ID);
 VALUE rb_class_name(VALUE);
-void rb_autoload(VALUE, ID, const char*);
+DEPRECATED(void rb_autoload(VALUE, ID, const char*));
 VALUE rb_autoload_load(VALUE, ID);
 VALUE rb_autoload_p(VALUE, ID);
 VALUE rb_f_trace_var(int, const VALUE*);
diff --git a/internal.h b/internal.h
index d135035..6a2454e 100644
--- a/internal.h
+++ b/internal.h
@@ -1174,6 +1174,7 @@ size_t rb_generic_ivar_memsize(VALUE);
 VALUE rb_search_class_path(VALUE);
 VALUE rb_attr_delete(VALUE, ID);
 VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
+void rb_autoload_value(VALUE mod, ID id, VALUE file);
 
 /* version.c */
 extern VALUE ruby_engine_name;
diff --git a/load.c b/load.c
index 3f5e143..804607b 100644
--- a/load.c
+++ b/load.c
@@ -1099,7 +1099,7 @@ rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
     ID id = rb_to_id(sym);
 
     FilePathValue(file);
-    rb_autoload(mod, id, RSTRING_PTR(file));
+    rb_autoload_value(mod, id, file);
     return Qnil;
 }
 
diff --git a/thread_pthread.c b/thread_pthread.c
index b361e8b..de88b95 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -716,7 +716,7 @@ ruby_init_stack(volatile VALUE *addr
 	if (get_main_stack(&stackaddr, &size) == 0) {
 	    native_main_thread.stack_maxsize = size;
 	    native_main_thread.stack_start = stackaddr;
-	    reserve_stack(stackaddr, size);
+	    //reserve_stack(stackaddr, size);
 	    return;
 	}
     }
diff --git a/variable.c b/variable.c
index ec6924a..97a404d 100644
--- a/variable.c
+++ b/variable.c
@@ -1937,8 +1937,17 @@ static const rb_data_type_t autoload_data_i_type = {
 void
 rb_autoload(VALUE mod, ID id, const char *file)
 {
+    if (!file || !*file) {
+	rb_raise(rb_eArgError, "empty file name");
+    }
+    rb_autoload_value(mod, id, rb_fstring_cstr(file));
+}
+
+void
+rb_autoload_value(VALUE mod, ID id, VALUE file)
+{
     st_data_t av;
-    VALUE ad, fn;
+    VALUE ad;
     struct st_table *tbl;
     struct autoload_data_i *ele;
     rb_const_entry_t *ce;
@@ -1947,7 +1956,9 @@ rb_autoload(VALUE mod, ID id, const char *file)
 	rb_raise(rb_eNameError, "autoload must be constant name: %"PRIsVALUE"",
 		 QUOTE_ID(id));
     }
-    if (!file || !*file) {
+
+    Check_Type(file, T_STRING);
+    if (!RSTRING_LEN(file)) {
 	rb_raise(rb_eArgError, "empty file name");
     }
 
@@ -1968,12 +1979,13 @@ rb_autoload(VALUE mod, ID id, const char *file)
 	RB_OBJ_WRITTEN(mod, Qnil, av);
 	DATA_PTR(av) = tbl = st_init_numtable();
     }
-    fn = rb_str_new2(file);
-    FL_UNSET(fn, FL_TAINT);
-    OBJ_FREEZE(fn);
 
     ad = TypedData_Make_Struct(0, struct autoload_data_i, &autoload_data_i_type, ele);
-    ele->feature = fn;
+    if (OBJ_TAINTED(file)) {
+	file = rb_str_dup(file);
+	FL_UNSET(file, FL_TAINT);
+    }
+    ele->feature = rb_fstring(file);
     ele->safe_level = rb_safe_level();
     ele->value = Qundef;
     ele->state = 0;
-- 
EW


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH] introduce rb_autoload_value to replace rb_autoload
@ 2015-11-06  3:54 Eric Wong
  0 siblings, 0 replies; 2+ messages in thread
From: Eric Wong @ 2015-11-06  3:54 UTC (permalink / raw)
  To: spew

rb_autoload_value may be safer by preventing premature GC.  It
can also be more efficient by passing a pre-frozen string that
can be deduped using rb_fstring.  Common autoload callers (e.g.
rubygems, rdoc) already use string literals as the file
argument.

There seems to be no reason to expose rb_autoload_value to the
public C API since autoload is not performance-critical.
Applications may declare autoloads in Ruby code or via
rb_funcall; so merely deprecate rb_autoload without exposing
rb_autoload_value to new users.

Running: valgrind -v ruby -rrdoc -rubygems -e exit
shows a minor memory reduction (32-bit userspace)

before:

  in use at exit: 1,600,621 bytes in 28,819 blocks
total heap usage: 55,786 allocs, 26,967 frees, 6,693,790 bytes allocated

after:

  in use at exit: 1,599,778 bytes in 28,789 blocks
total heap usage: 55,739 allocs, 26,950 frees, 6,692,973 bytes allocated
---
 include/ruby/intern.h |  2 +-
 internal.h            |  1 +
 load.c                |  2 +-
 variable.c            | 24 ++++++++++++++++++------
 4 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index af6b75d..d2ac732 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -935,7 +935,7 @@ VALUE rb_path_to_class(VALUE);
 VALUE rb_path2class(const char*);
 void rb_name_class(VALUE, ID);
 VALUE rb_class_name(VALUE);
-void rb_autoload(VALUE, ID, const char*);
+DEPRECATED(void rb_autoload(VALUE, ID, const char*));
 VALUE rb_autoload_load(VALUE, ID);
 VALUE rb_autoload_p(VALUE, ID);
 VALUE rb_f_trace_var(int, const VALUE*);
diff --git a/internal.h b/internal.h
index d135035..6a2454e 100644
--- a/internal.h
+++ b/internal.h
@@ -1174,6 +1174,7 @@ size_t rb_generic_ivar_memsize(VALUE);
 VALUE rb_search_class_path(VALUE);
 VALUE rb_attr_delete(VALUE, ID);
 VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
+void rb_autoload_value(VALUE mod, ID id, VALUE file);
 
 /* version.c */
 extern VALUE ruby_engine_name;
diff --git a/load.c b/load.c
index 3f5e143..804607b 100644
--- a/load.c
+++ b/load.c
@@ -1099,7 +1099,7 @@ rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
     ID id = rb_to_id(sym);
 
     FilePathValue(file);
-    rb_autoload(mod, id, RSTRING_PTR(file));
+    rb_autoload_value(mod, id, file);
     return Qnil;
 }
 
diff --git a/variable.c b/variable.c
index ec6924a..97a404d 100644
--- a/variable.c
+++ b/variable.c
@@ -1937,8 +1937,17 @@ static const rb_data_type_t autoload_data_i_type = {
 void
 rb_autoload(VALUE mod, ID id, const char *file)
 {
+    if (!file || !*file) {
+	rb_raise(rb_eArgError, "empty file name");
+    }
+    rb_autoload_value(mod, id, rb_fstring_cstr(file));
+}
+
+void
+rb_autoload_value(VALUE mod, ID id, VALUE file)
+{
     st_data_t av;
-    VALUE ad, fn;
+    VALUE ad;
     struct st_table *tbl;
     struct autoload_data_i *ele;
     rb_const_entry_t *ce;
@@ -1947,7 +1956,9 @@ rb_autoload(VALUE mod, ID id, const char *file)
 	rb_raise(rb_eNameError, "autoload must be constant name: %"PRIsVALUE"",
 		 QUOTE_ID(id));
     }
-    if (!file || !*file) {
+
+    Check_Type(file, T_STRING);
+    if (!RSTRING_LEN(file)) {
 	rb_raise(rb_eArgError, "empty file name");
     }
 
@@ -1968,12 +1979,13 @@ rb_autoload(VALUE mod, ID id, const char *file)
 	RB_OBJ_WRITTEN(mod, Qnil, av);
 	DATA_PTR(av) = tbl = st_init_numtable();
     }
-    fn = rb_str_new2(file);
-    FL_UNSET(fn, FL_TAINT);
-    OBJ_FREEZE(fn);
 
     ad = TypedData_Make_Struct(0, struct autoload_data_i, &autoload_data_i_type, ele);
-    ele->feature = fn;
+    if (OBJ_TAINTED(file)) {
+	file = rb_str_dup(file);
+	FL_UNSET(file, FL_TAINT);
+    }
+    ele->feature = rb_fstring(file);
     ele->safe_level = rb_safe_level();
     ele->value = Qundef;
     ele->state = 0;
-- 
EW


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-11-06  3:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-06  3:54 [PATCH] introduce rb_autoload_value to replace rb_autoload Eric Wong
  -- strict thread matches above, loose matches on Subject: below --
2015-11-06  3:46 Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).