summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-04-20 15:13:50 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-04-20 15:13:50 +0000
commitc1ca05af16a960a2431cf7afbbae9c034147899a (patch)
treea95ee86e08d8c88cca6ee218efef6d885e024854
parent80ecaa17776de97d8f7d9c256830edb45917987a (diff)
merge revision(s) 39644,39646,39647,39874,39898: [Backport #8048]
* load.c (features_index_add_single, rb_feature_p): store single index as Fixnum to reduce the number of arrays for the indexes. based on the patch by tmm1 (Aman Gupta) in [ruby-core:53216] [Bug #8048]. * load.c (rb_feature_p), vm_core.h (rb_vm_struct): turn loaded_features_index into st_table. patches by tmm1 (Aman Gupta) in [ruby-core:53251] and [ruby-core:53274] [Bug #8048] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@40397 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--load.c78
-rw-r--r--version.h6
-rw-r--r--vm.c4
-rw-r--r--vm_core.h2
5 files changed, 77 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 2238dbd4f0..7f27129294 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Sun Apr 21 00:13:24 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * load.c (rb_feature_p), vm_core.h (rb_vm_struct): turn
+ loaded_features_index into st_table. patches by tmm1 (Aman Gupta)
+ in [ruby-core:53251] and [ruby-core:53274] [Bug #8048]
+
+Sun Apr 21 00:13:24 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * load.c (features_index_add_single, rb_feature_p): store single index
+ as Fixnum to reduce the number of arrays for the indexes. based on
+ the patch by tmm1 (Aman Gupta) in [ruby-core:53216] [Bug #8048].
+
Sat Apr 20 23:32:06 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* dir.c (glob_helper): should skip dot directories only for recursion,
diff --git a/load.c b/load.c
index ea22d5bebd..72cab598d2 100644
--- a/load.c
+++ b/load.c
@@ -11,6 +11,8 @@
VALUE ruby_dln_librefs;
+#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
+
#define IS_RBEXT(e) (strcmp((e), ".rb") == 0)
#define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
#ifdef DLEXT2
@@ -56,7 +58,7 @@ rb_construct_expanded_load_path(int type, int *has_relative, int *has_non_cache)
long i;
int level = rb_safe_level();
- ary = rb_ary_new2(RARRAY_LEN(load_path));
+ ary = rb_ary_tmp_new(RARRAY_LEN(load_path));
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
VALUE path, as_str, expanded_path;
int is_string, non_cache;
@@ -169,7 +171,7 @@ reset_loaded_features_snapshot(void)
rb_ary_replace(vm->loaded_features_snapshot, vm->loaded_features);
}
-static VALUE
+static struct st_table *
get_loaded_features_index_raw(void)
{
return GET_VM()->loaded_features_index;
@@ -184,13 +186,32 @@ get_loading_table(void)
static void
features_index_add_single(VALUE short_feature, VALUE offset)
{
- VALUE features_index, this_feature_index;
+ struct st_table *features_index;
+ VALUE this_feature_index = Qnil;
+ char *short_feature_cstr;
+
+ Check_Type(offset, T_FIXNUM);
+ Check_Type(short_feature, T_STRING);
+ short_feature_cstr = StringValueCStr(short_feature);
+
features_index = get_loaded_features_index_raw();
- if ((this_feature_index = rb_hash_lookup(features_index, short_feature)) == Qnil) {
- this_feature_index = rb_ary_new();
- rb_hash_aset(features_index, short_feature, this_feature_index);
+ st_lookup(features_index, (st_data_t)short_feature_cstr, (st_data_t *)&this_feature_index);
+
+ if (NIL_P(this_feature_index)) {
+ st_insert(features_index, (st_data_t)ruby_strdup(short_feature_cstr), (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 = rb_ary_tmp_new(numberof(feature_indexes));
+ rb_ary_cat(this_feature_index, feature_indexes, numberof(feature_indexes));
+ st_insert(features_index, (st_data_t)short_feature_cstr, (st_data_t)this_feature_index);
+ }
+ else {
+ Check_Type(this_feature_index, T_ARRAY);
+ rb_ary_push(this_feature_index, offset);
}
- rb_ary_push(this_feature_index, offset);
}
/* Add to the loaded-features index all the required entries for
@@ -240,7 +261,14 @@ features_index_add(VALUE feature, VALUE offset)
}
}
-static VALUE
+static int
+loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
+{
+ xfree((char *)key);
+ return ST_DELETE;
+}
+
+static st_table *
get_loaded_features_index(void)
{
VALUE features;
@@ -250,7 +278,7 @@ get_loaded_features_index(void)
if (!rb_ary_shared_with_p(vm->loaded_features_snapshot, vm->loaded_features)) {
/* The sharing was broken; something (other than us in rb_provide_feature())
modified loaded_features. Rebuild the index. */
- rb_hash_clear(vm->loaded_features_index);
+ st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
features = vm->loaded_features;
for (i = 0; i < RARRAY_LEN(features); i++) {
VALUE entry, as_str;
@@ -340,10 +368,10 @@ loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f)
static int
rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const char **fn)
{
- VALUE features, features_index, feature_val, this_feature_index, v, p, load_path = 0;
+ VALUE features, this_feature_index = Qnil, v, p, load_path = 0;
const char *f, *e;
long i, len, elen, n;
- st_table *loading_tbl;
+ st_table *loading_tbl, *features_index;
st_data_t data;
int type;
@@ -361,8 +389,7 @@ rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const c
features = get_loaded_features();
features_index = get_loaded_features_index();
- feature_val = rb_str_new(feature, len);
- this_feature_index = rb_hash_lookup(features_index, feature_val);
+ st_lookup(features_index, (st_data_t)feature, (st_data_t *)&this_feature_index);
/* We search `features` for an entry such that either
"#{features[i]}" == "#{load_path[j]}/#{feature}#{e}"
for some j, or
@@ -389,8 +416,19 @@ rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const c
or ends in '/'. This includes both match forms above, as well
as any distractors, so we may ignore all other entries in `features`.
*/
- for (i = 0; this_feature_index != Qnil && i < RARRAY_LEN(this_feature_index); i++) {
- long index = FIX2LONG(rb_ary_entry(this_feature_index, i));
+ for (i = 0; !NIL_P(this_feature_index); i++) {
+ VALUE entry;
+ long index;
+ if (RB_TYPE_P(this_feature_index, T_ARRAY)) {
+ if (i >= RARRAY_LEN(this_feature_index)) break;
+ entry = RARRAY_PTR(this_feature_index)[i];
+ }
+ else {
+ if (i > 0) break;
+ entry = this_feature_index;
+ }
+ index = FIX2LONG(entry);
+
v = RARRAY_PTR(features)[index];
f = StringValuePtr(v);
if ((n = RSTRING_LEN(v)) < len) continue;
@@ -1082,15 +1120,15 @@ Init_load()
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();
+ vm->expanded_load_path = rb_ary_tmp_new(0);
+ vm->load_path_snapshot = rb_ary_tmp_new(0);
vm->load_path_check_cache = 0;
rb_define_virtual_variable("$\"", get_loaded_features, 0);
rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
vm->loaded_features = rb_ary_new();
- vm->loaded_features_snapshot = rb_ary_new();
- vm->loaded_features_index = rb_hash_new();
+ vm->loaded_features_snapshot = rb_ary_tmp_new(0);
+ vm->loaded_features_index = st_init_strtable();
rb_define_global_function("load", rb_f_load, -1);
rb_define_global_function("require", rb_f_require, 1);
@@ -1100,6 +1138,6 @@ Init_load()
rb_define_global_function("autoload", rb_f_autoload, 2);
rb_define_global_function("autoload?", rb_f_autoload_p, 1);
- ruby_dln_librefs = rb_ary_new();
+ ruby_dln_librefs = rb_ary_tmp_new(0);
rb_gc_register_mark_object(ruby_dln_librefs);
}
diff --git a/version.h b/version.h
index 3c2d3be590..0e76896cc5 100644
--- a/version.h
+++ b/version.h
@@ -1,10 +1,10 @@
#define RUBY_VERSION "2.0.0"
-#define RUBY_RELEASE_DATE "2013-04-20"
-#define RUBY_PATCHLEVEL 156
+#define RUBY_RELEASE_DATE "2013-04-21"
+#define RUBY_PATCHLEVEL 157
#define RUBY_RELEASE_YEAR 2013
#define RUBY_RELEASE_MONTH 4
-#define RUBY_RELEASE_DAY 20
+#define RUBY_RELEASE_DAY 21
#include "ruby/version.h"
diff --git a/vm.c b/vm.c
index 82d4de6e3d..c2b18b56ae 100644
--- a/vm.c
+++ b/vm.c
@@ -1565,7 +1565,6 @@ rb_vm_mark(void *ptr)
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);
RUBY_MARK_UNLESS_NULL(vm->top_self);
RUBY_MARK_UNLESS_NULL(vm->coverages);
rb_gc_mark_locations(vm->special_exceptions, vm->special_exceptions + ruby_special_error_count);
@@ -1573,6 +1572,9 @@ rb_vm_mark(void *ptr)
if (vm->loading_table) {
rb_mark_tbl(vm->loading_table);
}
+ if (vm->loaded_features_index) {
+ rb_mark_tbl(vm->loaded_features_index);
+ }
vm_trace_mark_event_hooks(&vm->event_hooks);
diff --git a/vm_core.h b/vm_core.h
index 1838f2a099..2ac57fc112 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -364,7 +364,7 @@ typedef struct rb_vm_struct {
VALUE expanded_load_path;
VALUE loaded_features;
VALUE loaded_features_snapshot;
- VALUE loaded_features_index;
+ struct st_table *loaded_features_index;
struct st_table *loading_table;
/* signal */