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

ruby-changes:36342

From: ko1 <ko1@a...>
Date: Fri, 14 Nov 2014 16:29:48 +0900 (JST)
Subject: [ruby-changes:36342] ko1:r48423 (trunk): * gc.c (gc_stat_internal): add compatible layer.

ko1	2014-11-14 16:29:33 +0900 (Fri, 14 Nov 2014)

  New Revision: 48423

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

  Log:
    * gc.c (gc_stat_internal): add compatible layer.
      From Ruby 2.2, keys of GC.stat are changed [Feature #9924].
      To provide compatible layer, GC.stat add a default_proc
      (if default_proc of given Hash object is not set).
      At first use of this compatible layer of interpreter process,
      show a warning message like that:
      program: GC.stat[:total_allocated_object]
      warning message: "warning: GC.stat keys were changed from Ruby
      2.1. In this case,  you refer to obsolete `total_allocated_object'
      (new key is `total_allocated_objects').
      Please check <https://bugs.ruby-lang.org/issues/9924>
      for more information."
      Pleaes correct my English message :)
    * hash.c (rb_hash_set_default_proc): export (in internal).
    * internal.h: ditto.

  Modified files:
    trunk/ChangeLog
    trunk/gc.c
    trunk/hash.c
    trunk/internal.h
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 48422)
+++ ChangeLog	(revision 48423)
@@ -1,3 +1,25 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Nov 14 16:19:08 2014  Koichi Sasada  <ko1@a...>
+
+	* gc.c (gc_stat_internal): add compatible layer.
+	  From Ruby 2.2, keys of GC.stat are changed [Feature #9924].
+	  To provide compatible layer, GC.stat add a default_proc
+	  (if default_proc of given Hash object is not set).
+
+	  At first use of this compatible layer of interpreter process,
+	  show a warning message like that:
+	  program: GC.stat[:total_allocated_object]
+	  warning message: "warning: GC.stat keys were changed from Ruby
+	  2.1. In this case,  you refer to obsolete `total_allocated_object'
+	  (new key is `total_allocated_objects').
+	  Please check <https://bugs.ruby-lang.org/issues/9924>
+	  for more information."
+
+	  Pleaes correct my English message :)
+
+	* hash.c (rb_hash_set_default_proc): export (in internal).
+
+	* internal.h: ditto.
+
 Fri Nov 14 10:41:25 2014  Koichi Sasada  <ko1@a...>
 
 	* gc.c: guard by #if/#endif with GC_ENABLE_INCREMENTAL_MARK
Index: gc.c
===================================================================
--- gc.c	(revision 48422)
+++ gc.c	(revision 48423)
@@ -6332,46 +6332,84 @@ gc_latest_gc_info(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/gc.c#L6332
     return gc_info_decode(objspace->profile.latest_gc_info, arg);
 }
 
-size_t
-gc_stat_internal(VALUE hash_or_sym)
-{
-    static VALUE sym_count;
-    static VALUE sym_heap_allocated_pages, sym_heap_sorted_length, sym_heap_allocatable_pages;
-    static VALUE sym_heap_available_slots, sym_heap_live_slots, sym_heap_free_slots, sym_heap_final_slots;
-    static VALUE sym_heap_marked_slots, sym_heap_swept_slots;
-    static VALUE sym_heap_eden_pages, sym_heap_tomb_pages;
-    static VALUE sym_total_allocated_pages, sym_total_freed_pages;
-    static VALUE sym_total_allocated_objects, sym_total_freed_objects;
-    static VALUE sym_malloc_increase_bytes, sym_malloc_increase_bytes_limit;
+enum gc_stat_sym {
+    gc_stat_sym_count,
+    gc_stat_sym_heap_allocated_pages,
+    gc_stat_sym_heap_sorted_length,
+    gc_stat_sym_heap_allocatable_pages,
+    gc_stat_sym_heap_available_slots,
+    gc_stat_sym_heap_live_slots,
+    gc_stat_sym_heap_free_slots,
+    gc_stat_sym_heap_final_slots,
+    gc_stat_sym_heap_marked_slots,
+    gc_stat_sym_heap_swept_slots,
+    gc_stat_sym_heap_eden_pages,
+    gc_stat_sym_heap_tomb_pages,
+    gc_stat_sym_total_allocated_pages,
+    gc_stat_sym_total_freed_pages,
+    gc_stat_sym_total_allocated_objects,
+    gc_stat_sym_total_freed_objects,
+    gc_stat_sym_malloc_increase_bytes,
+    gc_stat_sym_malloc_increase_bytes_limit,
 #if USE_RGENGC
-    static VALUE sym_minor_gc_count, sym_major_gc_count;
-    static VALUE sym_remembered_wb_unprotected_objects, sym_remembered_wb_unprotected_objects_limit;
-    static VALUE sym_old_objects, sym_old_objects_limit;
+    gc_stat_sym_minor_gc_count,
+    gc_stat_sym_major_gc_count,
+    gc_stat_sym_remembered_wb_unprotected_objects,
+    gc_stat_sym_remembered_wb_unprotected_objects_limit,
+    gc_stat_sym_old_objects,
+    gc_stat_sym_old_objects_limit,
 #if RGENGC_ESTIMATE_OLDMALLOC
-    static VALUE sym_oldmalloc_increase_bytes, sym_oldmalloc_increase_bytes_limit;
+    gc_stat_sym_oldmalloc_increase_bytes,
+    gc_stat_sym_oldmalloc_increase_bytes_limit,
 #endif
 #if RGENGC_PROFILE
-    static VALUE sym_total_generated_normal_object_count, sym_total_generated_shady_object_count;
-    static VALUE sym_total_shade_operation_count, sym_total_promoted_count;
-    static VALUE sym_total_remembered_normal_object_count, sym_total_remembered_shady_object_count;
-#endif /* RGENGC_PROFILE */
-#endif /* USE_RGENGC */
+    gc_stat_sym_total_generated_normal_object_count,
+    gc_stat_sym_total_generated_shady_object_count,
+    gc_stat_sym_total_shade_operation_count,
+    gc_stat_sym_total_promoted_count,
+    gc_stat_sym_total_remembered_normal_object_count,
+    gc_stat_sym_total_remembered_shady_object_count,
+#endif
+#endif
+    gc_stat_sym_last
+};
 
-    rb_objspace_t *objspace = &rb_objspace;
-    VALUE hash = Qnil, key = Qnil;
+enum gc_stat_compat_sym {
+    gc_stat_compat_sym_gc_stat_heap_used,
+    gc_stat_compat_sym_heap_eden_page_length,
+    gc_stat_compat_sym_heap_tomb_page_length,
+    gc_stat_compat_sym_heap_increment,
+    gc_stat_compat_sym_heap_length,
+    gc_stat_compat_sym_heap_live_slot,
+    gc_stat_compat_sym_heap_free_slot,
+    gc_stat_compat_sym_heap_final_slot,
+    gc_stat_compat_sym_heap_swept_slot,
+#if USE_RGENGC
+    gc_stat_compat_sym_remembered_shady_object,
+    gc_stat_compat_sym_remembered_shady_object_limit,
+    gc_stat_compat_sym_old_object,
+    gc_stat_compat_sym_old_object_limit,
+#endif
+    gc_stat_compat_sym_total_allocated_object,
+    gc_stat_compat_sym_total_freed_object,
+    gc_stat_compat_sym_malloc_increase,
+    gc_stat_compat_sym_malloc_limit,
+#if RGENGC_ESTIMATE_OLDMALLOC
+    gc_stat_compat_sym_oldmalloc_increase,
+    gc_stat_compat_sym_oldmalloc_limit,
+#endif
+    gc_stat_compat_sym_last
+};
 
-    if (RB_TYPE_P(hash_or_sym, T_HASH)) {
-	hash = hash_or_sym;
-    }
-    else if (SYMBOL_P(hash_or_sym)) {
-	key = hash_or_sym;
-    }
-    else {
-	rb_raise(rb_eTypeError, "non-hash or symbol argument");
-    }
+static VALUE gc_stat_symbols[gc_stat_sym_last];
+static VALUE gc_stat_compat_symbols[gc_stat_compat_sym_last];
+static VALUE gc_stat_compat_table;
 
-    if (sym_count == 0) {
-#define S(s) sym_##s = ID2SYM(rb_intern_const(#s))
+static void
+setup_gc_stat_symbols(void)
+{
+    if (gc_stat_symbols[0] == 0) {
+#define S(s) gc_stat_symbols[gc_stat_sym_##s] = ID2SYM(rb_intern_const(#s))
 	S(count);
 	S(heap_allocated_pages);
 	S(heap_sorted_length);
@@ -6411,13 +6449,122 @@ gc_stat_internal(VALUE hash_or_sym) https://github.com/ruby/ruby/blob/trunk/gc.c#L6449
 #endif /* RGENGC_PROFILE */
 #endif /* USE_RGENGC */
 #undef S
+#define S(s) gc_stat_compat_symbols[gc_stat_compat_sym_##s] = ID2SYM(rb_intern_const(#s))
+	S(gc_stat_heap_used);
+	S(heap_eden_page_length);
+	S(heap_tomb_page_length);
+	S(heap_increment);
+	S(heap_length);
+	S(heap_live_slot);
+	S(heap_free_slot);
+	S(heap_final_slot);
+	S(heap_swept_slot);
+#if USE_RGEGC
+	S(remembered_shady_object);
+	S(remembered_shady_object_limit);
+	S(old_object);
+	S(old_object_limit);
+#endif
+	S(total_allocated_object);
+	S(total_freed_object);
+	S(malloc_increase);
+	S(malloc_limit);
+#if RGENGC_ESTIMATE_OLDMALLOC
+	S(oldmalloc_increase);
+	S(oldmalloc_limit);
+#endif
+#undef S
+
+	{
+	    VALUE table = gc_stat_compat_table = rb_hash_new();
+	    rb_gc_register_mark_object(table);
+
+	    /* compatibility layer for Ruby 2.1 */
+#define OLD_SYM(s) gc_stat_compat_symbols[gc_stat_compat_sym_##s]
+#define NEW_SYM(s) gc_stat_symbols[gc_stat_sym_##s]
+	    rb_hash_aset(table, OLD_SYM(gc_stat_heap_used), NEW_SYM(heap_allocated_pages));
+	    rb_hash_aset(table, OLD_SYM(heap_eden_page_length), NEW_SYM(heap_eden_pages));
+	    rb_hash_aset(table, OLD_SYM(heap_tomb_page_length), NEW_SYM(heap_tomb_pages));
+	    rb_hash_aset(table, OLD_SYM(heap_increment), NEW_SYM(heap_allocatable_pages));
+	    rb_hash_aset(table, OLD_SYM(heap_length), NEW_SYM(heap_sorted_length));
+	    rb_hash_aset(table, OLD_SYM(heap_live_slot), NEW_SYM(heap_live_slots));
+	    rb_hash_aset(table, OLD_SYM(heap_free_slot), NEW_SYM(heap_free_slots));
+	    rb_hash_aset(table, OLD_SYM(heap_final_slot), NEW_SYM(heap_final_slots));
+	    rb_hash_aset(table, OLD_SYM(heap_swept_slot), NEW_SYM(heap_swept_slots));
+#if USE_RGEGC
+	    rb_hash_aset(table, OLD_SYM(remembered_shady_object), NEW_SYM(remembered_wb_unprotected_objects));
+	    rb_hash_aset(table, OLD_SYM(remembered_shady_object_limit), NEW_SYM(remembered_wb_unprotected_objects_limit));
+	    rb_hash_aset(table, OLD_SYM(old_object), NEW_SYM(old_objects));
+	    rb_hash_aset(table, OLD_SYM(old_object_limit), NEW_SYM(old_objects_limit));
+#endif
+	    rb_hash_aset(table, OLD_SYM(total_allocated_object), NEW_SYM(total_allocated_objects));
+	    rb_hash_aset(table, OLD_SYM(total_freed_object), NEW_SYM(total_freed_objects));
+	    rb_hash_aset(table, OLD_SYM(malloc_increase), NEW_SYM(malloc_increase_bytes));
+	    rb_hash_aset(table, OLD_SYM(malloc_limit), NEW_SYM(malloc_increase_bytes_limit));
+#if RGENGC_ESTIMATE_OLDMALLOC
+	    rb_hash_aset(table, OLD_SYM(oldmalloc_increase), NEW_SYM(oldmalloc_increase_bytes));
+	    rb_hash_aset(table, OLD_SYM(oldmalloc_limit), NEW_SYM(oldmalloc_increase_bytes_limit));
+#endif
+#undef OLD_SYM
+#undef NEW_SYM
+	    rb_obj_freeze(table);
+	}
+    }
+}
+
+static VALUE
+default_proc_for_compat_func(VALUE hash, VALUE dmy, int argc, VALUE *argv)
+{
+    VALUE key = argv[1];
+    VALUE new_key = Qnil;
+
+    if ((new_key = rb_hash_aref(gc_stat_compat_table, key)) != Qnil) {
+	static int warned = 0;
+	if (warned == 0) {
+	    rb_warn("GC.stat keys were changed from Ruby 2.1. "
+		    "In this case, you refer to obsolete `%"PRIsVALUE"' (new key is `%"PRIsVALUE"'). "
+		    "Please check <https://bugs.ruby-lang.org/issues/9924> for more information.",
+		    key, new_key);
+	    warned = 1;
+	}
+	return rb_hash_aref(hash, new_key);
+    }
+
+    return Qnil;
+}
+
+size_t
+gc_stat_internal(VALUE hash_or_sym)
+{
+    rb_objspace_t *objspace = &rb_objspace;
+    VALUE hash = Qnil, key = Qnil;
+
+    setup_gc_stat_symbols();
+
+    if (RB_TYPE_P(hash_or_sym, T_HASH)) {
+	hash = hash_or_sym;
+
+	if (NIL_P(RHASH_IFNONE(hash))) {
+	    static VALUE default_proc_for_compat = 0;
+	    if (default_proc_for_compat == 0) { /* TODO: it should be */
+		default_proc_for_compat = rb_proc_new(default_proc_for_compat_func, Qnil);
+		rb_gc_register_mark_object(default_proc_for_compat);
+	    }
+	    rb_hash_set_default_proc(hash, default_proc_for_compat);
+	}
+    }
+    else if (SYMBOL_P(hash_or_sym)) {
+	key = hash_or_sym;
+    }
+    else {
+	rb_raise(rb_eTypeError, "non-hash or symbol argument");
     }
 
 #define SET(name, attr) \
-    if (key == sym_##name) \
+    if (key == gc_stat_symbols[gc_stat_sym_##name]) \
 	return attr; \
     else if (hash != Qnil) \
-	rb_hash_aset(hash, sym_##name, SIZET2NUM(attr));
+	rb_hash_aset(hash, gc_stat_symbols[gc_stat_sym_##name], SIZET2NUM(attr));
 
     SET(count, objspace->profile.count);
 
Index: hash.c
===================================================================
--- hash.c	(revision 48422)
+++ hash.c	(revision 48423)
@@ -901,7 +901,7 @@ rb_hash_default_proc(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L901
  *     h["cat"]   #=> "catcat"
  */
 
-static VALUE
+VALUE
 rb_hash_set_default_proc(VALUE hash, VALUE proc)
 {
     VALUE b;
Index: internal.h
===================================================================
--- internal.h	(revision 48422)
+++ internal.h	(revision 48423)
@@ -671,6 +671,7 @@ void rb_gc_resurrect(VALUE ptr); https://github.com/ruby/ruby/blob/trunk/internal.h#L671
 /* hash.c */
 struct st_table *rb_hash_tbl_raw(VALUE hash);
 VALUE rb_hash_has_key(VALUE hash, VALUE key);
+VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
 
 #define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h)
 VALUE rb_hash_keys(VALUE hash);

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

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