ruby-changes:55390
From: tenderlove <ko1@a...>
Date: Wed, 17 Apr 2019 18:41:48 +0900 (JST)
Subject: [ruby-changes:55390] tenderlove:r67598 (trunk): Reverting compaction for now
tenderlove 2019-04-17 18:41:41 +0900 (Wed, 17 Apr 2019) New Revision: 67598 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=67598 Log: Reverting compaction for now For some reason symbols (or classes) are being overridden in trunk Removed files: trunk/test/ruby/test_gc_compact.rb Modified files: trunk/NEWS trunk/class.c trunk/constant.h trunk/ext/json/generator/generator.c trunk/ext/json/parser/parser.c trunk/gc.c trunk/gc.h trunk/hash.c trunk/id_table.c trunk/id_table.h trunk/include/ruby/intern.h trunk/include/ruby/ruby.h trunk/include/ruby/st.h trunk/internal.h trunk/iseq.c trunk/iseq.h trunk/method.h trunk/st.c trunk/symbol.c trunk/symbol.h trunk/thread.c trunk/transient_heap.c trunk/transient_heap.h trunk/variable.c trunk/vm.c trunk/vm_core.h trunk/vm_eval.c Index: test/ruby/test_gc_compact.rb =================================================================== --- test/ruby/test_gc_compact.rb (revision 67597) +++ test/ruby/test_gc_compact.rb (nonexistent) @@ -1,97 +0,0 @@ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_gc_compact.rb#L0 -# frozen_string_literal: true -require 'test/unit' -require 'fiddle' - -class TestGCCompact < Test::Unit::TestCase - def memory_location(obj) - (Fiddle.dlwrap(obj) >> 1) - end - - def assert_object_ids(list) - same_count = list.find_all { |obj| - memory_location(obj) == obj.object_id - }.count - list.count - same_count - end - - def big_list - 1000.times.map { - # try to make some empty slots by allocating an object and discarding - Object.new - Object.new - } # likely next to each other - end - - # Find an object that's allocated in a slot that had a previous - # tenant, and that tenant moved and is still alive - def find_object_in_recycled_slot(addresses) - new_object = nil - - loop do - new_object = Object.new - if addresses.include? memory_location(new_object) - break - end - end - - new_object - end - - def test_find_collided_object - list_of_objects = big_list - - ids = list_of_objects.map(&:object_id) # store id in map - addresses = list_of_objects.map(&self.:memory_location) - - assert_equal ids, addresses - - # All object ids should be equal - assert_equal 0, assert_object_ids(list_of_objects) # should be 0 - - GC.verify_compaction_references - - # Some should have moved - id_count = assert_object_ids(list_of_objects) - skip "couldn't get objects to move" if id_count == 0 - assert_operator id_count, :>, 0 - - new_ids = list_of_objects.map(&:object_id) - - # Object ids should not change after compaction - assert_equal ids, new_ids - - new_tenant = find_object_in_recycled_slot(addresses) - assert new_tenant - - # This is the object that used to be in new_object's position - previous_tenant = list_of_objects[addresses.index(memory_location(new_tenant))] - - assert_not_equal previous_tenant.object_id, new_tenant.object_id - - # Should be able to look up object by object_id - assert_equal new_tenant, ObjectSpace._id2ref(new_tenant.object_id) - - # Should be able to look up object by object_id - assert_equal previous_tenant, ObjectSpace._id2ref(previous_tenant.object_id) - - int = (new_tenant.object_id >> 1) - # These two should be the same! but they are not :( - assert_equal int, ObjectSpace._id2ref(int.object_id) - end - - def test_many_collisions - list_of_objects = big_list - ids = list_of_objects.map(&:object_id) - addresses = list_of_objects.map(&self.:memory_location) - - GC.verify_compaction_references - - new_tenants = 10.times.map { - find_object_in_recycled_slot(addresses) - } - - collisions = GC.stat(:object_id_collisions) - skip "couldn't get objects to collide" if collisions == 0 - assert_operator collisions, :>, 0 - end -end Property changes on: test/ruby/test_gc_compact.rb ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -LF \ No newline at end of property Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 67597) +++ include/ruby/ruby.h (revision 67598) @@ -512,7 +512,6 @@ enum ruby_value_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L512 RUBY_T_NODE = 0x1b, RUBY_T_ICLASS = 0x1c, RUBY_T_ZOMBIE = 0x1d, - RUBY_T_MOVED = 0x1e, RUBY_T_MASK = 0x1f }; @@ -543,7 +542,6 @@ enum ruby_value_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L542 #define T_UNDEF RUBY_T_UNDEF #define T_NODE RUBY_T_NODE #define T_ZOMBIE RUBY_T_ZOMBIE -#define T_MOVED RUBY_T_MOVED #define T_MASK RUBY_T_MASK #define RB_BUILTIN_TYPE(x) (int)(((struct RBasic*)(x))->flags & RUBY_T_MASK) @@ -847,7 +845,6 @@ enum ruby_fl_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L845 RUBY_FL_FINALIZE = (1<<7), RUBY_FL_TAINT = (1<<8), RUBY_FL_UNTRUSTED = RUBY_FL_TAINT, - RUBY_FL_SEEN_OBJ_ID = (1<<9), RUBY_FL_EXIVAR = (1<<10), RUBY_FL_FREEZE = (1<<11), @@ -886,7 +883,7 @@ enum ruby_fl_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L883 struct RUBY_ALIGNAS(SIZEOF_VALUE) RBasic { VALUE flags; - VALUE klass; + const VALUE klass; }; VALUE rb_obj_hide(VALUE obj); @@ -1108,7 +1105,7 @@ struct RArray { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1105 struct RRegexp { struct RBasic basic; struct re_pattern_buffer *ptr; - VALUE src; + const VALUE src; unsigned long usecnt; }; #define RREGEXP_PTR(r) (RREGEXP(r)->ptr) @@ -1147,8 +1144,7 @@ struct rb_data_type_struct { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1144 void (*dmark)(void*); void (*dfree)(void*); size_t (*dsize)(const void *); - void (*dcompact)(void*); - void *reserved[1]; /* For future extension. + void *reserved[2]; /* For future extension. This array *must* be filled with ZERO. */ } function; const rb_data_type_t *parent; @@ -1259,7 +1255,6 @@ int rb_big_sign(VALUE); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1255 #define RBIGNUM_NEGATIVE_P(b) (RBIGNUM_SIGN(b)==0) #define R_CAST(st) (struct st*) -#define RMOVED(obj) (R_CAST(RMoved)(obj)) #define RBASIC(obj) (R_CAST(RBasic)(obj)) #define ROBJECT(obj) (R_CAST(RObject)(obj)) #define RCLASS(obj) (R_CAST(RClass)(obj)) @@ -1278,7 +1273,6 @@ int rb_big_sign(VALUE); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1273 #define FL_FINALIZE ((VALUE)RUBY_FL_FINALIZE) #define FL_TAINT ((VALUE)RUBY_FL_TAINT) #define FL_UNTRUSTED ((VALUE)RUBY_FL_UNTRUSTED) -#define FL_SEEN_OBJ_ID ((VALUE)RUBY_FL_SEEN_OBJ_ID) #define FL_EXIVAR ((VALUE)RUBY_FL_EXIVAR) #define FL_FREEZE ((VALUE)RUBY_FL_FREEZE) Index: symbol.c =================================================================== --- symbol.c (revision 67597) +++ symbol.c (revision 67598) @@ -60,7 +60,12 @@ enum id_entry_type { https://github.com/ruby/ruby/blob/trunk/symbol.c#L60 ID_ENTRY_SIZE }; -rb_symbols_t global_symbols = {tNEXT_ID-1}; +static struct symbols { + rb_id_serial_t last_id; + st_table *str_sym; + VALUE ids; + VALUE dsymbol_fstr_hash; +} global_symbols = {tNEXT_ID-1}; static const struct st_hash_type symhash = { rb_str_hash_cmp, Index: iseq.h =================================================================== --- iseq.h (revision 67597) +++ iseq.h (revision 67598) @@ -236,7 +236,7 @@ struct iseq_catch_table_entry { https://github.com/ruby/ruby/blob/trunk/iseq.h#L236 * CATCH_TYPE_REDO, CATCH_TYPE_NEXT: * NULL. */ - rb_iseq_t *iseq; + const rb_iseq_t *iseq; unsigned int start; unsigned int end; Index: symbol.h =================================================================== --- symbol.h (revision 67597) +++ symbol.h (revision 67598) @@ -54,13 +54,6 @@ id_type(ID id) https://github.com/ruby/ruby/blob/trunk/symbol.h#L54 typedef uint32_t rb_id_serial_t; -typedef struct { - rb_id_serial_t last_id; - st_table *str_sym; - VALUE ids; - VALUE dsymbol_fstr_hash; -} rb_symbols_t; - static inline rb_id_serial_t rb_id_to_serial(ID id) { Index: method.h =================================================================== --- method.h (revision 67597) +++ method.h (revision 67598) @@ -40,9 +40,9 @@ typedef struct rb_scope_visi_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L40 /*! CREF (Class REFerence) */ typedef struct rb_cref_struct { VALUE flags; - VALUE refinements; - VALUE klass; - struct rb_cref_struct * next; + const VALUE refinements; + const VALUE klass; + struct rb_cref_struct * const next; const rb_scope_visibility_t scope_visi; } rb_cref_t; @@ -50,10 +50,10 @@ typedef struct rb_cref_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L50 typedef struct rb_method_entry_struct { VALUE flags; - VALUE defined_class; + const VALUE defined_class; struct rb_method_definition_struct * const def; ID called_id; - VALUE owner; + const VALUE owner; } rb_method_entry_t; typedef struct rb_callable_method_entry_struct { /* same fields with rb_method_entry_t */ @@ -123,8 +123,8 @@ typedef struct rb_iseq_struct rb_iseq_t; https://github.com/ruby/ruby/blob/trunk/method.h#L123 #endif typedef struct rb_method_iseq_struct { - rb_iseq_t * iseqptr; /*!< iseq pointer, should be separated from iseqval */ - rb_cref_t * cref; /*!< class reference, should be marked */ + const rb_iseq_t * const iseqptr; /*!< iseq pointer, should be separated from iseqval */ + rb_cref_t * const cref; /*!< class reference, should be marked */ } rb_method_iseq_t; /* check rb_add_method_iseq() when modify the fields */ typedef struct rb_method_cfunc_struct { @@ -135,20 +135,20 @@ typedef struct rb_method_cfunc_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L135 typedef struct rb_method_attr_struct { ID id; - VALUE location; /* should be marked */ + const VALUE location; /* should be marked */ } rb_method_attr_t; typedef struct rb_method_alias_struct { - struct rb_method_entry_struct * original_me; /* original_me->klass is original owner */ + const struct rb_method_entry_struct * const original_me; /* original_me->klass is original owner */ } rb_method_alias_t; typedef struct rb_method_refined_struct { - struct rb_method_entry_struct * orig_me; - VALUE owner; + const struct rb_method_entry_struct * const orig_me; + const VALUE owner; } rb_method_refined_t; typedef struct rb_method_bmethod_struct { - VALUE proc; /* should be marked */ + const VALUE proc; /* should be marked */ struct rb_hook_list_struct *hooks; } rb_method_bmethod_t; Index: NEWS =================================================================== --- NEWS (revision 67597) +++ NEWS (revision 67598) @@ -109,15 +109,6 @@ JIT:: https://github.com/ruby/ruby/blob/trunk/NEWS#L109 * Default value of +--jit-min-calls+ is changed from 5 to 10,000 -GC:: - - * New `GC.compact` method for compacting the heap. - This function compacts live objects in the heap so that fewer pages may - be used, and the heap may be more CoW friendly. [Feature #15626] - - Details on the algorithm and caveats can be found here: - https://bugs.ruby-lang.org/issues/15626 - === Miscellaneous changes * Require compilers to support C99 [Misc #15347] Index: constant.h =================================================================== --- constant.h (revision 67597) +++ constant.h (revision 67598) @@ -31,8 +31,8 @@ typedef enum { https://github.com/ruby/ruby/blob/trunk/constant.h#L31 typedef struct rb_const_entry_struct { rb_const_flag_t flag; int line; - VALUE value; /* should be mark */ - VALUE file; /* should be mark */ + const VALUE value; /* should be mark */ + const VALUE file; /* should be mark */ } rb_const_entry_t; VALUE rb_mod_private_constant(int argc, const VALUE *argv, VALUE obj); Index: vm.c =================================================================== --- vm.c (revision 67597) +++ vm.c (revision 67598) @@ -2203,15 +2203,6 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*fun https://github.com/ruby/ruby/blob/trunk/vm.c#L2203 /* vm */ void -rb_vm_update_references(void *ptr) -{ - if (ptr) { - rb_vm_t *vm = ptr; - rb_update_st_references(vm->frozen_strings); - } -} - -void rb_vm_mark(void *ptr) { RUBY_MARK_ENTER("vm"); @@ -2219,30 +2210,12 @@ rb_vm_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/vm.c#L2210 if (ptr) { rb_vm_t *vm = ptr; rb_thread_t *th = 0; - long i, len; - const VALUE *obj_ary; list_for_each(&vm->living_threads, th, vmlt_node) { rb_gc_mark(th->self); } rb_gc_mark(vm->thgroup_default); rb_gc_mark(vm->mark_object_ary); - - len = RARRAY_LEN(vm->mark_object_ary); - obj_ary = RARRAY_CONST_PTR(vm->mark_object_ary); - for (i=0; i < len; i++) { - const VALUE *ptr; - long j, jlen; - - rb_gc_mark(*obj_ary); - jlen = RARRAY_LEN(*obj_ary); - ptr = RARRAY_CONST_PTR(*obj_ary); - for (j=0; j < jlen; j++) { - rb_gc_mark(*ptr++); - } - obj_ary++; - } - rb_gc_mark(vm->load_path); rb_gc_mark(vm->load_path_snapshot); RUBY_MARK_UNLESS_NULL(vm->load_path_check_cache); @@ -2252,8 +2225,6 @@ rb_vm_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/vm.c#L2225 rb_gc_mark(vm->top_self); RUBY_MARK_UNLESS_NULL(vm->coverages); rb_gc_mark(vm->defined_module_hash); - /* Prevent classes from moving */ - rb_mark_tbl(rb_hash_tbl(vm->defined_module_hash, __FILE__, __LINE__)); if (vm->loading_table) { rb_mark_tbl(vm->loading_table); @@ -2492,7 +2463,7 @@ rb_execution_context_mark(const rb_execu https://github.com/ruby/ruby/blob/trunk/vm.c#L2463 rb_control_frame_t *cfp = ec->cfp; rb_control_frame_t *limit_cfp = (void *)(ec->vm_stack + ec->vm_stack_size); - rb_gc_mark_stack_values((long)(sp - p), p); + rb_gc_mark_values((long)(sp - p), p); while (cfp != limit_cfp) { const VALUE *ep = cfp->ep; Index: hash.c =================================================================== --- hash.c (revision 67597) +++ hash.c (revision 67598) @@ -781,7 +781,7 @@ ar_add_direct_with_hash(VALUE hash, st_d https://github.com/ruby/ruby/blob/trunk/hash.c#L781 } static int -ar_general_foreach(VALUE hash, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg) +ar_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg) { if (RHASH_AR_TABLE_SIZE(hash) > 0) { unsigned i, bound = RHASH_AR_TABLE_BOUND(hash); @@ -799,20 +799,6 @@ ar_general_foreach(VALUE hash, int (*fun https://github.com/ruby/ruby/blob/trunk/hash.c#L799 case ST_CHECK: case ST_STOP: return 0; - case ST_REPLACE: - if (replace) { - VALUE key; - VALUE value; - - key = cur_entry->key; - value = cur_entry->record; - retval = (*replace)(&key, &value, arg, TRUE); - - ar_table_entry *entry = RHASH_AR_TABLE_REF(hash, i); - entry->key = key; - entry->record = value; - } - break; case ST_DELETE: ar_clear_entry(RHASH_AR_TABLE_REF(hash, i)); RHASH_AR_TABLE_SIZE_DEC(hash); @@ -824,18 +810,6 @@ ar_general_foreach(VALUE hash, int (*fun https://github.com/ruby/ruby/blob/trunk/hash.c#L810 } static int -ar_foreach_with_replace(VALUE hash, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg) -{ - return ar_general_foreach(hash, func, replace, arg); -} - -static int -ar_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg) -{ - return ar_general_foreach(hash, func, NULL, arg); -} - -static int ar_foreach_check(VALUE hash, int (*func)(ANYARGS), st_data_t arg, st_data_t never) { @@ -871,7 +845,6 @@ ar_foreach_check(VALUE hash, int (*func) https://github.com/ruby/ruby/blob/trunk/hash.c#L845 case ST_CONTINUE: break; case ST_STOP: - case ST_REPLACE: return 0; case ST_DELETE: { if (!ar_empty_entry(cur_entry)) { @@ -1284,17 +1257,6 @@ rb_hash_stlike_foreach(VALUE hash, int ( https://github.com/ruby/ruby/blob/trunk/hash.c#L1257 } } -int -rb_hash_stlike_foreach_with_replace(VALUE hash, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg) -{ - if (RHASH_AR_TABLE_P(hash)) { - return ar_foreach_with_replace(hash, func, replace, arg); - } - else { - return st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg); - } -} - static VALUE hash_foreach_call(VALUE arg) { Index: vm_core.h =================================================================== --- vm_core.h (revision 67597) +++ vm_core.h (revision 67598) @@ -346,7 +346,7 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L346 } type; /* instruction sequence type */ unsigned int iseq_size; - VALUE *iseq_encoded; /* encoded iseq (insn addr and operands) */ + const VALUE *iseq_encoded; /* encoded iseq (insn addr and operands) */ /** * parameter information @@ -414,7 +414,7 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L414 int bits_start; int rest_start; const ID *table; - VALUE *default_values; + const VALUE *default_values; } *keyword; } param; @@ -433,7 +433,7 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L433 const ID *local_table; /* must free */ /* catch table */ - struct iseq_catch_table *catch_table; + const struct iseq_catch_table *catch_table; /* for child iseq */ const struct rb_iseq_struct *parent_iseq; @@ -1029,7 +1029,7 @@ typedef struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1029 typedef struct { VALUE flags; /* imemo header */ - rb_iseq_t *iseq; + const rb_iseq_t *iseq; const VALUE *ep; const VALUE *env; unsigned int env_size; Index: id_table.c =================================================================== --- id_table.c (revision 67597) +++ id_table.c (revision 67598) @@ -267,28 +267,6 @@ rb_id_table_delete(struct rb_id_table *t https://github.com/ruby/ruby/blob/trunk/id_table.c#L267 } void -rb_id_table_foreach_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, rb_id_table_update_callback_func_t *replace, void *data) -{ - int i, capa = tbl->capa; - - for (i=0; i<capa; i++) { - if (ITEM_KEY_ISSET(tbl, i)) { - const id_key_t key = ITEM_GET_KEY(tbl, i); - enum rb_id_table_iterator_result ret = (*func)(Qundef, tbl->items[i].val, data); - assert(key != 0); - - if (ret == ID_TABLE_REPLACE) { - VALUE val = tbl->items[i].val; - ret = (*replace)(NULL, &val, data, TRUE); - tbl->items[i].val = val; - } - else if (ret == ID_TABLE_STOP) - return; - } - } -} - -void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data) { int i, capa = tbl->capa; Index: transient_heap.c =================================================================== --- transient_heap.c (revision 67597) +++ transient_heap.c (revision 67598) @@ -796,56 +796,6 @@ blocks_clear_marked_index(struct transie https://github.com/ruby/ruby/blob/trunk/transient_heap.c#L796 } } -static void -transient_heap_block_update_refs(struct transient_heap* theap, struct transient_heap_block* block) -{ - int i=0, n=0; - - while (i<block->info.index) { - void *ptr = &block->buff[i]; - struct transient_alloc_header *header = ptr; - - unpoison_memory_region(header, sizeof *header, false); - - void *poisoned = __asan_region_is_poisoned(header->obj, SIZEOF_VALUE); - unpoison_object(header->obj, false); - - header->obj = rb_gc_new_location(header->obj); - - if (poisoned) { - poison_object(header->obj); - } - - i += header->size; - poison_memory_region(header, sizeof *header); (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/