summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkazu <kazu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-10 09:15:21 +0000
committerkazu <kazu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-10 09:15:21 +0000
commit25c1fd3b9037d9eb39596bb994eeabed812adada (patch)
treed50105485a5d01efee139d56b3c570561adfff97
parent0cc2ffbc1bf135a3b7a8656b9242e87b1ad96d6c (diff)
Reverting all commits from r67479 to r67496 because of CI failures
Because hard to specify commits related to r67479 only. So please commit again. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--NEWS9
-rw-r--r--array.c2
-rw-r--r--class.c8
-rw-r--r--compile.c6
-rw-r--r--constant.h4
-rw-r--r--defs/id.def1
-rw-r--r--ext/json/generator/generator.c2
-rw-r--r--ext/json/parser/parser.c2
-rw-r--r--ext/openssl/ossl_bn.c7
-rw-r--r--gc.c1308
-rw-r--r--gc.h4
-rw-r--r--hash.c40
-rw-r--r--id_table.c22
-rw-r--r--id_table.h3
-rw-r--r--include/ruby/intern.h5
-rw-r--r--include/ruby/ruby.h10
-rw-r--r--include/ruby/st.h3
-rw-r--r--internal.h42
-rw-r--r--io.c3
-rw-r--r--iseq.c102
-rw-r--r--iseq.h2
-rw-r--r--lib/net/imap.rb1
-rw-r--r--method.h24
-rw-r--r--mjit_worker.c3
-rw-r--r--parse.y8
-rw-r--r--st.c23
-rw-r--r--symbol.c7
-rw-r--r--symbol.h7
-rw-r--r--test/openssl/test_bn.rb5
-rw-r--r--test/ruby/test_gc.rb1
-rw-r--r--test/ruby/test_gc_compact.rb103
-rw-r--r--timev.h3
-rw-r--r--transient_heap.c50
-rw-r--r--transient_heap.h2
-rw-r--r--variable.c32
-rw-r--r--version.h2
-rw-r--r--vm.c31
-rw-r--r--vm_args.c2
-rw-r--r--vm_core.h8
-rw-r--r--vm_eval.c1
-rw-r--r--vm_method.c7
41 files changed, 152 insertions, 1753 deletions
diff --git a/NEWS b/NEWS
index 65fc6cb164..75fa91798d 100644
--- a/NEWS
+++ b/NEWS
@@ -98,15 +98,6 @@ JIT::
* 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]
diff --git a/array.c b/array.c
index bcc653f387..a47a836ea0 100644
--- a/array.c
+++ b/array.c
@@ -1326,7 +1326,7 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
MJIT_FUNC_EXPORTED VALUE
rb_ary_behead(VALUE ary, long n)
{
- if (n<=0) return ary;
+ if(n<=0) return ary;
rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
diff --git a/class.c b/class.c
index d0ff92b6eb..b76af269bb 100644
--- a/class.c
+++ b/class.c
@@ -539,7 +539,6 @@ boot_defclass(const char *name, VALUE super)
rb_name_class(obj, id);
rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
- rb_vm_add_root_module(id, obj);
return obj;
}
@@ -731,9 +730,6 @@ rb_define_class_id_under(VALUE outer, ID id, VALUE super)
" (%"PRIsVALUE" is given but was %"PRIsVALUE")",
outer, rb_id2str(id), RCLASS_SUPER(klass), super);
}
- /* Class may have been defined in Ruby and not pin-rooted */
- rb_vm_add_root_module(id, klass);
-
return klass;
}
if (!super) {
@@ -744,7 +740,6 @@ rb_define_class_id_under(VALUE outer, ID id, VALUE super)
rb_set_class_path_string(klass, outer, rb_id2str(id));
rb_const_set(outer, id, klass);
rb_class_inherited(super, klass);
- rb_vm_add_root_module(id, klass);
rb_gc_register_mark_object(klass);
return klass;
@@ -782,13 +777,10 @@ rb_define_module(const char *name)
rb_raise(rb_eTypeError, "%s is not a module (%"PRIsVALUE")",
name, rb_obj_class(module));
}
- /* Module may have been defined in Ruby and not pin-rooted */
- rb_vm_add_root_module(id, module);
return module;
}
module = rb_define_module_id(id);
rb_vm_add_root_module(id, module);
- rb_gc_register_mark_object(module);
rb_const_set(rb_cObject, id, module);
return module;
diff --git a/compile.c b/compile.c
index e937c337e6..46b8217e7e 100644
--- a/compile.c
+++ b/compile.c
@@ -574,7 +574,6 @@ static int
iseq_add_mark_object_compile_time(const rb_iseq_t *iseq, VALUE v)
{
if (!SPECIAL_CONST_P(v)) {
- rb_gc_writebarrier((VALUE)iseq, v);
rb_ary_push(ISEQ_COMPILE_DATA(iseq)->mark_ary, v);
}
return COMPILE_OK;
@@ -584,7 +583,6 @@ static inline VALUE
freeze_literal(rb_iseq_t *iseq, VALUE lit)
{
lit = rb_fstring(lit);
- rb_gc_writebarrier((VALUE)iseq, lit);
rb_ary_push(ISEQ_COMPILE_DATA(iseq)->mark_ary, lit);
return lit;
}
@@ -1366,10 +1364,12 @@ iseq_set_exception_local_table(rb_iseq_t *iseq)
/* TODO: every id table is same -> share it.
* Current problem is iseq_free().
*/
+ ID id_dollar_bang;
ID *ids = (ID *)ALLOC_N(ID, 1);
+ CONST_ID(id_dollar_bang, "#$!");
iseq->body->local_table_size = 1;
- ids[0] = idERROR_INFO;
+ ids[0] = id_dollar_bang;
iseq->body->local_table = ids;
return COMPILE_OK;
}
diff --git a/constant.h b/constant.h
index 6c8cda08db..fcccf07384 100644
--- a/constant.h
+++ b/constant.h
@@ -31,8 +31,8 @@ typedef enum {
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);
diff --git a/defs/id.def b/defs/id.def
index 24ca5d3f9f..91a9768ad6 100644
--- a/defs/id.def
+++ b/defs/id.def
@@ -70,7 +70,6 @@ firstline, predefined = __LINE__+1, %[\
$_ LASTLINE
$~ BACKREF
- $! ERROR_INFO
]
# VM ID OP Parser Token
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c
index e59a120008..6b3cdd7e58 100644
--- a/ext/json/generator/generator.c
+++ b/ext/json/generator/generator.c
@@ -1344,8 +1344,6 @@ void Init_generator(void)
eGeneratorError = rb_path2class("JSON::GeneratorError");
eNestingError = rb_path2class("JSON::NestingError");
- rb_gc_register_mark_object(eGeneratorError);
- rb_gc_register_mark_object(eNestingError);
cState = rb_define_class_under(mGenerator, "State", rb_cObject);
rb_define_alloc_func(cState, cState_s_allocate);
diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c
index 0bd328ca42..f68676879b 100644
--- a/ext/json/parser/parser.c
+++ b/ext/json/parser/parser.c
@@ -2091,8 +2091,6 @@ void Init_parser(void)
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
eParserError = rb_path2class("JSON::ParserError");
eNestingError = rb_path2class("JSON::NestingError");
- rb_gc_register_mark_object(eParserError);
- rb_gc_register_mark_object(eNestingError);
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
rb_define_method(cParser, "initialize", cParser_initialize, -1);
rb_define_method(cParser, "parse", cParser_parse, 0);
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index 6f0064e966..4666ce6c2f 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -187,7 +187,6 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
BIGNUM *bn;
VALUE str, bs;
int base = 10;
- char *ptr;
if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
base = NUM2INT(bs);
@@ -214,14 +213,12 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
GetBN(self, bn);
switch (base) {
case 0:
- ptr = StringValuePtr(str);
- if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
+ if (!BN_mpi2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
ossl_raise(eBNError, NULL);
}
break;
case 2:
- ptr = StringValuePtr(str);
- if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
+ if (!BN_bin2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
ossl_raise(eBNError, NULL);
}
break;
diff --git a/gc.c b/gc.c
index 0a1c5e8f69..9336a0dcf6 100644
--- a/gc.c
+++ b/gc.c
@@ -29,7 +29,6 @@
#include "ruby_atomic.h"
#include "probes.h"
#include "id_table.h"
-#include "symbol.h"
#include <stdio.h>
#include <stdarg.h>
#include <setjmp.h>
@@ -195,9 +194,6 @@ static ruby_gc_params_t gc_params = {
FALSE,
};
-static st_table *id_to_obj_tbl;
-static st_table *obj_to_id_tbl;
-
/* GC_DEBUG:
* enable to embed GC debugging information.
*/
@@ -408,7 +404,6 @@ typedef struct RVALUE {
VALUE flags; /* always 0 for freed obj */
struct RVALUE *next;
} free;
- struct RMoved moved;
struct RBasic basic;
struct RObject object;
struct RClass klass;
@@ -586,7 +581,6 @@ typedef struct rb_objspace {
#if USE_RGENGC
size_t minor_gc_count;
size_t major_gc_count;
- size_t object_id_collisions;
#if RGENGC_PROFILE > 0
size_t total_generated_normal_object_count;
size_t total_generated_shady_object_count;
@@ -641,12 +635,6 @@ typedef struct rb_objspace {
size_t error_count;
#endif
} rgengc;
-
- struct {
- size_t considered_count_table[T_MASK];
- size_t moved_count_table[T_MASK];
- } rcompactor;
-
#if GC_ENABLE_INCREMENTAL_MARK
struct {
size_t pooled_slots;
@@ -694,8 +682,6 @@ struct heap_page {
#if USE_RGENGC
bits_t wb_unprotected_bits[HEAP_PAGE_BITMAP_LIMIT];
#endif
- /* If set, the object is not movable */
- bits_t pinned_bits[HEAP_PAGE_BITMAP_LIMIT];
/* the following three bitmaps are cleared at the beginning of full GC */
bits_t mark_bits[HEAP_PAGE_BITMAP_LIMIT];
#if USE_RGENGC
@@ -720,7 +706,6 @@ struct heap_page {
/* getting bitmap */
#define GET_HEAP_MARK_BITS(x) (&GET_HEAP_PAGE(x)->mark_bits[0])
-#define GET_HEAP_PINNED_BITS(x) (&GET_HEAP_PAGE(x)->pinned_bits[0])
#if USE_RGENGC
#define GET_HEAP_UNCOLLECTIBLE_BITS(x) (&GET_HEAP_PAGE(x)->uncollectible_bits[0])
#define GET_HEAP_WB_UNPROTECTED_BITS(x) (&GET_HEAP_PAGE(x)->wb_unprotected_bits[0])
@@ -841,9 +826,7 @@ VALUE rb_mGC;
int ruby_disable_gc = 0;
void rb_iseq_mark(const rb_iseq_t *iseq);
-void rb_iseq_update_references(rb_iseq_t *iseq);
void rb_iseq_free(const rb_iseq_t *iseq);
-void rb_vm_update_references(void *ptr);
void rb_gcdebug_print_obj_condition(VALUE obj);
@@ -878,11 +861,8 @@ static void gc_sweep_rest(rb_objspace_t *objspace);
static void gc_sweep_continue(rb_objspace_t *objspace, rb_heap_t *heap);
static inline void gc_mark(rb_objspace_t *objspace, VALUE ptr);
-static inline void gc_pin(rb_objspace_t *objspace, VALUE ptr);
-static inline void gc_mark_and_pin(rb_objspace_t *objspace, VALUE ptr);
static void gc_mark_ptr(rb_objspace_t *objspace, VALUE ptr);
NO_SANITIZE("memory", static void gc_mark_maybe(rb_objspace_t *objspace, VALUE ptr));
-static void gc_mark_and_pin_maybe(rb_objspace_t *objspace, VALUE ptr);
static void gc_mark_children(rb_objspace_t *objspace, VALUE ptr);
static int gc_mark_stacked_objects_incremental(rb_objspace_t *, size_t count);
@@ -915,14 +895,6 @@ static inline void gc_prof_sweep_timer_stop(rb_objspace_t *);
static inline void gc_prof_set_malloc_info(rb_objspace_t *);
static inline void gc_prof_set_heap_info(rb_objspace_t *);
-#define TYPED_UPDATE_IF_MOVED(_objspace, _type, _thing) do { \
- if (gc_object_moved_p(_objspace, (VALUE)_thing)) { \
- (_thing) = (_type)RMOVED((_thing))->destination; \
- } \
-} while (0)
-
-#define UPDATE_IF_MOVED(_objspace, _thing) TYPED_UPDATE_IF_MOVED(_objspace, VALUE, _thing)
-
#define gc_prof_record(objspace) (objspace)->profile.current_record
#define gc_prof_enabled(objspace) ((objspace)->profile.run && (objspace)->profile.current_record)
@@ -1048,7 +1020,6 @@ tick(void)
#define FL_UNSET2(x,f) FL_CHECK2("FL_UNSET2", x, RBASIC(x)->flags &= ~(f))
#define RVALUE_MARK_BITMAP(obj) MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(obj), (obj))
-#define RVALUE_PIN_BITMAP(obj) MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), (obj))
#define RVALUE_PAGE_MARKED(page, obj) MARKED_IN_BITMAP((page)->mark_bits, (obj))
#if USE_RGENGC
@@ -1143,39 +1114,12 @@ check_rvalue_consistency(const VALUE obj)
#endif
static inline int
-gc_object_moved_p(rb_objspace_t * objspace, VALUE obj)
-{
- if (RB_SPECIAL_CONST_P(obj)) {
- return FALSE;
- }
- else {
- void *poisoned = poisoned_object_p(obj);
- unpoison_object(obj, false);
-
- int ret = BUILTIN_TYPE(obj) == T_MOVED;
- /* Re-poison slot if it's not the one we want */
- if (poisoned) {
- GC_ASSERT(BUILTIN_TYPE(obj) == T_NONE);
- poison_object(obj);
- }
- return ret;
- }
-}
-
-static inline int
RVALUE_MARKED(VALUE obj)
{
check_rvalue_consistency(obj);
return RVALUE_MARK_BITMAP(obj) != 0;
}
-static inline int
-RVALUE_PINNED(VALUE obj)
-{
- check_rvalue_consistency(obj);
- return RVALUE_PIN_BITMAP(obj) != 0;
-}
-
#if USE_RGENGC
static inline int
RVALUE_WB_UNPROTECTED(VALUE obj)
@@ -2263,18 +2207,6 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
FL_UNSET(obj, FL_EXIVAR);
}
- if (FL_TEST(obj, FL_FINALIZE)) {
- VALUE id;
-
- FL_UNSET(obj, FL_FINALIZE);
-
- if (st_lookup(obj_to_id_tbl, (st_data_t)obj, &id)) {
- gc_report(4, objspace, "Collecting %p -> %p\n", (void *)obj, (void *)obj_id_to_ref(id));
- st_delete(obj_to_id_tbl, (st_data_t *)&obj, 0);
- st_delete(id_to_obj_tbl, (st_data_t *)&id, 0);
- }
- }
-
#if USE_RGENGC
if (RVALUE_WB_UNPROTECTED(obj)) CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
@@ -2442,7 +2374,6 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
break;
case T_RATIONAL:
case T_COMPLEX:
- case T_MOVED:
break;
case T_ICLASS:
/* Basically , T_ICLASS shares table with the module */
@@ -2552,10 +2483,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
}
if (FL_TEST(obj, FL_FINALIZE)) {
- /* "object_id" objects will not have a block to call */
- if (st_lookup(finalizer_table, obj, 0)) {
- make_zombie(objspace, obj, 0, 0);
- }
+ make_zombie(objspace, obj, 0, 0);
return 1;
}
else {
@@ -2711,7 +2639,6 @@ internal_object_p(VALUE obj)
UNEXPECTED_NODE(internal_object_p);
break;
case T_NONE:
- case T_MOVED:
case T_IMEMO:
case T_ICLASS:
case T_ZOMBIE:
@@ -3299,10 +3226,6 @@ id2ref(VALUE obj, VALUE objid)
if (FLONUM_P(ptr)) return (VALUE)ptr;
ptr = obj_id_to_ref(objid);
- if (st_lookup(id_to_obj_tbl, objid, &ptr)) {
- return ptr;
- }
-
if ((ptr % sizeof(RVALUE)) == (4 << 2)) {
ID symid = ptr / sizeof(RVALUE);
if (rb_id2str(symid) == 0)
@@ -3391,32 +3314,6 @@ rb_obj_id(VALUE obj)
else if (SPECIAL_CONST_P(obj)) {
return LONG2NUM((SIGNED_VALUE)obj);
}
- VALUE id;
-
- if (st_lookup(obj_to_id_tbl, (st_data_t)obj, &id)) {
- gc_report(4, &rb_objspace, "Second time object_id was called on this object: %p\n", (void*)obj);
- return id;
- }
- else {
- id = nonspecial_obj_id(obj);
-
- while (1) {
- /* id is the object id */
- if (st_lookup(id_to_obj_tbl, (st_data_t)id, 0)) {
- gc_report(4, &rb_objspace, "object_id called on %p, but there was a collision at %d\n", (void*)obj, NUM2INT(id));
- rb_objspace_t *objspace = &rb_objspace;
- objspace->profile.object_id_collisions++;
- id += 40;
- }
- else {
- gc_report(4, &rb_objspace, "Initial insert: %p id: %d\n", (void*)obj, NUM2INT(id));
- st_insert(obj_to_id_tbl, (st_data_t)obj, id);
- st_insert(id_to_obj_tbl, (st_data_t)id, obj);
- FL_SET(obj, FL_FINALIZE);
- return id;
- }
- }
- }
return nonspecial_obj_id(obj);
}
@@ -3540,7 +3437,6 @@ obj_memsize_of(VALUE obj, int use_all_types)
break;
case T_ZOMBIE:
- case T_MOVED:
break;
default:
@@ -3597,7 +3493,6 @@ type_sym(size_t type)
COUNT_TYPE(T_NODE);
COUNT_TYPE(T_ICLASS);
COUNT_TYPE(T_ZOMBIE);
- COUNT_TYPE(T_MOVED);
#undef COUNT_TYPE
default: return INT2NUM(type); break;
}
@@ -4309,7 +4204,7 @@ mark_locations_array(rb_objspace_t *objspace, register const VALUE *x, register
VALUE v;
while (n--) {
v = *x;
- gc_mark_and_pin_maybe(objspace, v);
+ gc_mark_maybe(objspace, v);
x++;
}
}
@@ -4331,12 +4226,12 @@ rb_gc_mark_locations(const VALUE *start, const VALUE *end)
}
static void
-gc_mark_and_pin_values(rb_objspace_t *objspace, long n, const VALUE *values)
+gc_mark_values(rb_objspace_t *objspace, long n, const VALUE *values)
{
long i;
for (i=0; i<n; i++) {
- gc_mark_and_pin(objspace, values[i]);
+ gc_mark(objspace, values[i]);
}
}
@@ -4344,53 +4239,18 @@ void
rb_gc_mark_values(long n, const VALUE *values)
{
rb_objspace_t *objspace = &rb_objspace;
- gc_mark_and_pin_values(objspace, n, values);
-}
-
-static void
-gc_mark_and_pin_stack_values(rb_objspace_t *objspace, long n, const VALUE *values)
-{
- long i;
-
- for (i=0; i<n; i++) {
- /* skip MOVED objects that are on the stack */
- if (is_markable_object(objspace, values[i]) && T_MOVED != BUILTIN_TYPE(values[i])) {
- gc_mark_and_pin(objspace, values[i]);
- }
- }
-}
-
-void
-rb_gc_mark_stack_values(long n, const VALUE *values)
-{
- rb_objspace_t *objspace = &rb_objspace;
- gc_mark_and_pin_stack_values(objspace, n, values);
-}
-
-static int
-mark_entry_no_pin(st_data_t key, st_data_t value, st_data_t data)
-{
- rb_objspace_t *objspace = (rb_objspace_t *)data;
- gc_mark(objspace, (VALUE)value);
- return ST_CONTINUE;
+ gc_mark_values(objspace, n, values);
}
static int
mark_entry(st_data_t key, st_data_t value, st_data_t data)
{
rb_objspace_t *objspace = (rb_objspace_t *)data;
- gc_mark_and_pin(objspace, (VALUE)value);
+ gc_mark(objspace, (VALUE)value);
return ST_CONTINUE;
}
static void
-mark_tbl_no_pin(rb_objspace_t *objspace, st_table *tbl)
-{
- if (!tbl || tbl->num_entries == 0) return;
- st_foreach(tbl, mark_entry_no_pin, (st_data_t)objspace);
-}
-
-static void
mark_tbl(rb_objspace_t *objspace, st_table *tbl)
{
if (!tbl || tbl->num_entries == 0) return;
@@ -4423,12 +4283,7 @@ mark_keyvalue(st_data_t key, st_data_t value, st_data_t data)
{
rb_objspace_t *objspace = (rb_objspace_t *)data;
- if (SPECIAL_CONST_P((VALUE)key) || BUILTIN_TYPE((VALUE)key) == T_STRING) {
- gc_mark(objspace, (VALUE)key);
- }
- else {
- gc_mark_and_pin(objspace, (VALUE)key);
- }
+ gc_mark(objspace, (VALUE)key);
gc_mark(objspace, (VALUE)value);
return ST_CONTINUE;
}
@@ -4608,14 +4463,8 @@ rb_mark_tbl(st_table *tbl)
mark_tbl(&rb_objspace, tbl);
}
-void
-rb_mark_tbl_no_pin(st_table *tbl)
-{
- mark_tbl_no_pin(&rb_objspace, tbl);
-}
-
static void
-gc_mark_maybe_(rb_objspace_t *objspace, VALUE obj, int pin)
+gc_mark_maybe(rb_objspace_t *objspace, VALUE obj)
{
(void)VALGRIND_MAKE_MEM_DEFINED(&obj, sizeof(obj));
if (is_pointer_to_heap(objspace, (void *)obj)) {
@@ -4624,35 +4473,19 @@ gc_mark_maybe_(rb_objspace_t *objspace, VALUE obj, int pin)
unpoison_object(obj, false);
type = BUILTIN_TYPE(obj);
- /* Garbage can live on the stack, so do not mark or pin */
- if (type != T_MOVED && type != T_ZOMBIE && type != T_NONE) {
- if (pin) {
- gc_pin(objspace, obj);
- }
+ if (type != T_ZOMBIE && type != T_NONE) {
gc_mark_ptr(objspace, obj);
}
if (ptr) {
- GC_ASSERT(BUILTIN_TYPE(obj) == T_NONE);
poison_object(obj);
}
}
}
-static void
-gc_mark_and_pin_maybe(rb_objspace_t *objspace, VALUE obj)
-{
- gc_mark_maybe_(objspace, obj, TRUE);
-}
-
-static void
-gc_mark_maybe(rb_objspace_t *objspace, VALUE obj)
-{
- gc_mark_maybe_(objspace, obj, FALSE);
-}
void
rb_gc_mark_maybe(VALUE obj)
{
- gc_mark_and_pin_maybe(&rb_objspace, obj);
+ gc_mark_maybe(&rb_objspace, obj);
}
static inline int
@@ -4788,21 +4621,6 @@ gc_mark_ptr(rb_objspace_t *objspace, VALUE obj)
}
static inline void
-gc_mark_and_pin(rb_objspace_t *objspace, VALUE obj)
-{
- if (!is_markable_object(objspace, obj)) return;
- MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj);
- gc_mark_ptr(objspace, obj);
-}
-
-static inline void
-gc_pin(rb_objspace_t *objspace, VALUE obj)
-{
- if (!is_markable_object(objspace, obj)) return;
- MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj);
-}
-
-static inline void
gc_mark(rb_objspace_t *objspace, VALUE obj)
{
if (!is_markable_object(objspace, obj)) return;
@@ -4810,15 +4628,9 @@ gc_mark(rb_objspace_t *objspace, VALUE obj)
}
void
-rb_gc_mark_no_pin(VALUE ptr)
-{
- gc_mark(&rb_objspace, ptr);
-}
-
-void
rb_gc_mark(VALUE ptr)
{
- gc_mark_and_pin(&rb_objspace, ptr);
+ gc_mark(&rb_objspace, ptr);
}
/* CAUTION: THIS FUNCTION ENABLE *ONLY BEFORE* SWEEPING.
@@ -4831,12 +4643,6 @@ rb_objspace_marked_object_p(VALUE obj)
return RVALUE_MARKED(obj) ? TRUE : FALSE;
}
-int
-rb_objspace_pinned_object_p(VALUE obj)
-{
- return RVALUE_PINNED(obj) ? TRUE : FALSE;
-}
-
static inline void
gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj)
{
@@ -4858,9 +4664,9 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
{
const rb_env_t *env = (const rb_env_t *)obj;
GC_ASSERT(VM_ENV_ESCAPED_P(env->ep));
- gc_mark_and_pin_values(objspace, (long)env->env_size, env->env);
+ gc_mark_values(objspace, (long)env->env_size, env->env);
VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
- gc_mark_and_pin(objspace, (VALUE)rb_vm_env_prev_env(env));
+ gc_mark(objspace, (VALUE)rb_vm_env_prev_env(env));
gc_mark(objspace, (VALUE)env->iseq);
}
return;
@@ -4952,7 +4758,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
case T_MODULE:
mark_m_tbl(objspace, RCLASS_M_TBL(obj));
if (!RCLASS_EXT(obj)) break;
- mark_tbl_no_pin(objspace, RCLASS_IV_TBL(obj));
+ mark_tbl(objspace, RCLASS_IV_TBL(obj));
mark_const_tbl(objspace, RCLASS_CONST_TBL(obj));
gc_mark(objspace, RCLASS_SUPER((VALUE)obj));
break;
@@ -5080,7 +4886,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
#if GC_DEBUG
rb_gcdebug_print_obj_condition((VALUE)obj);
#endif
- if (BUILTIN_TYPE(obj) == T_MOVED) rb_bug("rb_gc_mark(): %p is T_MOVED", (void *)obj);
if (BUILTIN_TYPE(obj) == T_NONE) rb_bug("rb_gc_mark(): %p is T_NONE", (void *)obj);
if (BUILTIN_TYPE(obj) == T_ZOMBIE) rb_bug("rb_gc_mark(): %p is T_ZOMBIE", (void *)obj);
rb_bug("rb_gc_mark(): unknown data type 0x%x(%p) %s",
@@ -5560,12 +5365,7 @@ verify_internal_consistency_i(void *page_start, void *page_end, size_t stride, v
/* count objects */
data->live_object_count++;
- /* Normally, we don't expect T_MOVED objects to be in the heap.
- * But they can stay alive on the stack, */
- if (!gc_object_moved_p(objspace, obj)) {
- /* moved slots don't have children */
- rb_objspace_reachable_objects_from(obj, check_children_i, (void *)data);
- }
+ rb_objspace_reachable_objects_from(obj, check_children_i, (void *)data);
#if USE_RGENGC
/* check health of children */
@@ -5679,7 +5479,7 @@ gc_verify_heap_pages_(rb_objspace_t *objspace, struct list_head *head)
list_for_each(head, page, page_node) {
unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
RVALUE *p = page->freelist;
- while (p) {
+ while(p) {
RVALUE *prev = p;
unpoison_object((VALUE)p, false);
if (BUILTIN_TYPE(p) != T_NONE) {
@@ -6315,7 +6115,6 @@ rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace, rb_heap_t *heap)
list_for_each(&heap->pages, page, page_node) {
memset(&page->mark_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
- memset(&page->pinned_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
memset(&page->marking_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
memset(&page->uncollectible_bits[0], 0, HEAP_PAGE_BITMAP_SIZE);
page->flags.has_uncollectible_shady_objects = FALSE;
@@ -6570,7 +6369,7 @@ rb_obj_gc_flags(VALUE obj, ID* flags, size_t max)
size_t n = 0;
static ID ID_marked;
#if USE_RGENGC
- static ID ID_wb_protected, ID_old, ID_marking, ID_uncollectible, ID_pinned;
+ static ID ID_wb_protected, ID_old, ID_marking, ID_uncollectible;
#endif
if (!ID_marked) {
@@ -6581,7 +6380,6 @@ rb_obj_gc_flags(VALUE obj, ID* flags, size_t max)
I(old);
I(marking);
I(uncollectible);
- I(pinned);
#endif
#undef I
}
@@ -6593,7 +6391,6 @@ rb_obj_gc_flags(VALUE obj, ID* flags, size_t max)
if (MARKED_IN_BITMAP(GET_HEAP_MARKING_BITS(obj), obj) && n<max) flags[n++] = ID_marking;
#endif
if (MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj) && n<max) flags[n++] = ID_marked;
- if (MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj) && n<max) flags[n++] = ID_pinned;
return n;
}
@@ -7167,955 +6964,6 @@ gc_start_internal(int argc, VALUE *argv, VALUE self)
return Qnil;
}
-static int
-gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj)
-{
- if (SPECIAL_CONST_P(obj)) {
- return FALSE;
- }
-
- switch(BUILTIN_TYPE(obj)) {
- case T_NONE:
- case T_NIL:
- case T_MOVED:
- case T_ZOMBIE:
- return FALSE;
- break;
- case T_STRING:
- case T_OBJECT:
- case T_FLOAT:
- case T_IMEMO:
- case T_ARRAY:
- case T_BIGNUM:
- case T_ICLASS:
- case T_MODULE:
- case T_REGEXP:
- case T_DATA:
- case T_SYMBOL:
- case T_MATCH:
- case T_STRUCT:
- case T_HASH:
- case T_FILE:
- case T_COMPLEX:
- case T_RATIONAL:
- case T_NODE:
- case T_CLASS:
- if (FL_TEST(obj, FL_FINALIZE)) {
- if (st_lookup(finalizer_table, obj, 0)) {
- return FALSE;
- }
- }
- return !rb_objspace_pinned_object_p(obj);
- break;
-
- default:
- rb_bug("gc_is_moveable_obj: unreachable (%d)", (int)BUILTIN_TYPE(obj));
- break;
- }
-
- return FALSE;
-}
-
-static int
-update_id_to_obj(st_data_t *key, st_data_t *value, st_data_t arg, int exists)
-{
- if (exists) {
- *value = arg;
- return ST_CONTINUE;
- }
- else {
- return ST_STOP;
- }
-}
-
-static void
-gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free)
-{
- int marked;
- int wb_unprotected;
- int uncollectible;
- int marking;
- RVALUE *dest = (RVALUE *)free;
- RVALUE *src = (RVALUE *)scan;
-
- gc_report(4, objspace, "Moving object: %s -> %p\n", obj_info(scan), (void *)free);
-
- GC_ASSERT(BUILTIN_TYPE(scan) != T_NONE);
- GC_ASSERT(BUILTIN_TYPE(free) == T_NONE);
-
- /* Save off bits for current object. */
- marked = rb_objspace_marked_object_p((VALUE)src);
- wb_unprotected = RVALUE_WB_UNPROTECTED((VALUE)src);
- uncollectible = RVALUE_UNCOLLECTIBLE((VALUE)src);
- marking = RVALUE_MARKING((VALUE)src);
-
- objspace->total_allocated_objects++;
-
- /* Clear bits for eventual T_MOVED */
- CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS((VALUE)src), (VALUE)src);
- CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS((VALUE)src), (VALUE)src);
- CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS((VALUE)src), (VALUE)src);
- CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)src), (VALUE)src);
-
- if (FL_TEST(src, FL_EXIVAR)) {
- rb_mv_generic_ivar((VALUE)src, (VALUE)dest);
- }
-
- VALUE id;
-
- /* If the source object's object_id has been seen, we need to update
- * the object to object id mapping. */
- if (st_lookup(obj_to_id_tbl, (VALUE)src, &id)) {
- gc_report(4, objspace, "Moving object with seen id: %p -> %p\n", (void *)src, (void *)dest);
- st_delete(obj_to_id_tbl, (st_data_t *)&src, 0);
- st_insert(obj_to_id_tbl, (VALUE)dest, id);
- st_update(id_to_obj_tbl, (st_data_t)id, update_id_to_obj, (st_data_t)dest);
- }
-
- /* Move the object */
- memcpy(dest, src, sizeof(RVALUE));
- memset(src, 0, sizeof(RVALUE));
-
- /* Set bits for object in new location */
- if (marking) {
- MARK_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)dest), (VALUE)dest);
- }
- else {
- CLEAR_IN_BITMAP(GET_HEAP_MARKING_BITS((VALUE)dest), (VALUE)dest);
- }
-
- if (marked) {
- MARK_IN_BITMAP(GET_HEAP_MARK_BITS((VALUE)dest), (VALUE)dest);
- }
- else {
- CLEAR_IN_BITMAP(GET_HEAP_MARK_BITS((VALUE)dest), (VALUE)dest);
- }
-
- if (wb_unprotected) {
- MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS((VALUE)dest), (VALUE)dest);
- }
- else {
- CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS((VALUE)dest), (VALUE)dest);
- }
-
- if (uncollectible) {
- MARK_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS((VALUE)dest), (VALUE)dest);
- }
- else {
- CLEAR_IN_BITMAP(GET_HEAP_UNCOLLECTIBLE_BITS((VALUE)dest), (VALUE)dest);
- }
-
- /* Assign forwarding address */
- src->as.moved.flags = T_MOVED;
- src->as.moved.destination = (VALUE)dest;
- GC_ASSERT(BUILTIN_TYPE((VALUE)dest) != T_NONE);
-}
-
-struct heap_cursor {
- RVALUE *slot;
- size_t index;
- struct heap_page *page;
- rb_objspace_t * objspace;
-};
-
-static void
-advance_cursor(struct heap_cursor *free, struct heap_page **page_list)
-{
- if (free->slot == free->page->start + free->page->total_slots - 1) {
- free->index++;
- free->page = page_list[free->index];
- free->slot = free->page->start;
- }
- else {
- free->slot++;
- }
-}
-
-static void
-retreat_cursor(struct heap_cursor *scan, struct heap_page **page_list)
-{
- if (scan->slot == scan->page->start) {
- scan->index--;
- scan->page = page_list[scan->index];
- scan->slot = scan->page->start + scan->page->total_slots - 1;
- }
- else {
- scan->slot--;
- }
-}
-
-static int
-not_met(struct heap_cursor *free, struct heap_cursor *scan)
-{
- if (free->index < scan->index)
- return 1;
-
- if (free->index > scan->index)
- return 0;
-
- return free->slot < scan->slot;
-}
-
-static void
-init_cursors(rb_objspace_t *objspace, struct heap_cursor *free, struct heap_cursor *scan, struct heap_page **page_list)
-{
- struct heap_page *page;
- page = page_list[0];
-
- free->index = 0;
- free->page = page;
- free->slot = page->start;
- free->objspace = objspace;
-
- page = page_list[heap_allocated_pages - 1];
- scan->index = heap_allocated_pages - 1;
- scan->page = page;
- scan->slot = page->start + page->total_slots - 1;
- scan->objspace = objspace;
-}
-
-int count_pinned(struct heap_page *page)
-{
- RVALUE *pstart = page->start;
- RVALUE *pend = pstart + page->total_slots;
- int pinned = 0;
-
- VALUE v = (VALUE)pstart;
- for (; v != (VALUE)pend; v += sizeof(RVALUE)) {
- void *poisoned = poisoned_object_p(v);
- unpoison_object(v, false);
-
- if (RBASIC(v)->flags && RVALUE_PINNED(v)) {
- pinned++;
- }
-
- if (poisoned) {
- GC_ASSERT(BUILTIN_TYPE(v) == T_NONE);
- poison_object(v);
- }
- }
-
- return pinned;
-}
-
-int compare_pinned(const void *left, const void *right, void *dummy)
-{
- int left_count = count_pinned(*(struct heap_page * const *)left);
- int right_count = count_pinned(*(struct heap_page * const *)right);
- return right_count - left_count;
-}
-
-static void
-gc_compact_heap(rb_objspace_t *objspace)
-{
- struct heap_cursor free_cursor;
- struct heap_cursor scan_cursor;
- struct heap_page **page_list;
-
- memset(objspace->rcompactor.considered_count_table, 0, T_MASK * sizeof(size_t));
- memset(objspace->rcompactor.moved_count_table, 0, T_MASK * sizeof(size_t));
-
- page_list = calloc(heap_allocated_pages, sizeof(struct heap_page *));
- memcpy(page_list, heap_pages_sorted, heap_allocated_pages * sizeof(struct heap_page *));
- ruby_qsort(page_list, heap_allocated_pages, sizeof(struct heap_page *), compare_pinned, NULL);
-
- init_cursors(objspace, &free_cursor, &scan_cursor, page_list);
-
- /* Two finger algorithm */
- while (not_met(&free_cursor, &scan_cursor)) {
- /* Free cursor movement */
-
- /* Unpoison free_cursor slot */
- void *free_slot_poison = poisoned_object_p((VALUE)free_cursor.slot);
- unpoison_object((VALUE)free_cursor.slot, false);
-
- while (BUILTIN_TYPE(free_cursor.slot) != T_NONE && not_met(&free_cursor, &scan_cursor)) {
- /* Re-poison slot if it's not the one we want */
- if (free_slot_poison) {
- GC_ASSERT(BUILTIN_TYPE(free_cursor.slot) == T_NONE);
- poison_object((VALUE)free_cursor.slot);
- }
-
- advance_cursor(&free_cursor, page_list);
-
- /* Unpoison free_cursor slot */
- free_slot_poison = poisoned_object_p((VALUE)free_cursor.slot);
- unpoison_object((VALUE)free_cursor.slot, false);
- }
-
- /* Unpoison scan_cursor slot */
- void *scan_slot_poison = poisoned_object_p((VALUE)scan_cursor.slot);
- unpoison_object((VALUE)scan_cursor.slot, false);
-
- /* Scan cursor movement */
- objspace->rcompactor.considered_count_table[BUILTIN_TYPE((VALUE)scan_cursor.slot)]++;
-
- while (!gc_is_moveable_obj(objspace, (VALUE)scan_cursor.slot) && not_met(&free_cursor, &scan_cursor)) {
-
- /* Re-poison slot if it's not the one we want */
- if (scan_slot_poison) {
- GC_ASSERT(BUILTIN_TYPE(scan_cursor.slot) == T_NONE);
- poison_object((VALUE)scan_cursor.slot);
- }
-
- retreat_cursor(&scan_cursor, page_list);
-
- /* Unpoison scan_cursor slot */
- scan_slot_poison = poisoned_object_p((VALUE)scan_cursor.slot);
- unpoison_object((VALUE)scan_cursor.slot, false);
-
- objspace->rcompactor.considered_count_table[BUILTIN_TYPE((VALUE)scan_cursor.slot)]++;
- }
-
- if (not_met(&free_cursor, &scan_cursor)) {
- objspace->rcompactor.moved_count_table[BUILTIN_TYPE((VALUE)scan_cursor.slot)]++;
-
- GC_ASSERT(BUILTIN_TYPE(free_cursor.slot) == T_NONE);
- GC_ASSERT(BUILTIN_TYPE(scan_cursor.slot) != T_NONE);
- GC_ASSERT(BUILTIN_TYPE(scan_cursor.slot) != T_MOVED);
-
- gc_move(objspace, (VALUE)scan_cursor.slot, (VALUE)free_cursor.slot);
-
- GC_ASSERT(BUILTIN_TYPE(free_cursor.slot) != T_MOVED);
- GC_ASSERT(BUILTIN_TYPE(free_cursor.slot) != T_NONE);
- GC_ASSERT(BUILTIN_TYPE(scan_cursor.slot) == T_MOVED);
-
- advance_cursor(&free_cursor, page_list);
- retreat_cursor(&scan_cursor, page_list);
- }
- }
- free(page_list);
-}
-
-static void
-gc_ref_update_array(rb_objspace_t * objspace, VALUE v)
-{
- long i, len;
-
- if (FL_TEST(v, ELTS_SHARED))
- return;
-
- len = RARRAY_LEN(v);
- if (len > 0) {
- VALUE *ptr = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(v);
- for (i = 0; i < len; i++) {
- UPDATE_IF_MOVED(objspace, ptr[i]);
- }
- }
-}
-
-static void
-gc_ref_update_object(rb_objspace_t * objspace, VALUE v)
-{
- VALUE *ptr = ROBJECT_IVPTR(v);
-
- if (ptr) {
- uint32_t i, len = ROBJECT_NUMIV(v);
- for (i = 0; i < len; i++) {
- UPDATE_IF_MOVED(objspace, ptr[i]);
- }
- }
-}
-
-static int
-hash_replace_ref(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
-{
- rb_objspace_t *objspace = (rb_objspace_t *)argp;
-
- if (gc_object_moved_p(objspace, (VALUE)*key)) {
- *key = rb_gc_new_location((VALUE)*key);
- }
-
- if (gc_object_moved_p(objspace, (VALUE)*value)) {
- *value = rb_gc_new_location((VALUE)*value);
- }
-
- return ST_CONTINUE;
-}
-
-static int
-hash_foreach_replace(st_data_t key, st_data_t value, st_data_t argp, int error)
-{
- rb_objspace_t *objspace;
-
- objspace = (rb_objspace_t *)argp;
-
- if (gc_object_moved_p(objspace, (VALUE)key)) {
- return ST_REPLACE;
- }
-
- if (gc_object_moved_p(objspace, (VALUE)value)) {
- return ST_REPLACE;
- }
- return ST_CONTINUE;
-}
-
-static void
-gc_update_table_refs(rb_objspace_t * objspace, st_table *ht)
-{
- if (st_foreach_with_replace(ht, hash_foreach_replace, hash_replace_ref, (st_data_t)objspace)) {
- rb_raise(rb_eRuntimeError, "hash modified during iteration");
- }
-}
-
-/* Update MOVED references in an st_table */
-void
-rb_gc_update_tbl_refs(st_table *ptr)
-{
- rb_objspace_t *objspace = &rb_objspace;
- gc_update_table_refs(objspace, ptr);
-}
-
-static void
-gc_ref_update_hash(rb_objspace_t * objspace, VALUE v)
-{
- rb_hash_stlike_foreach_with_replace(v, hash_foreach_replace, hash_replace_ref, (st_data_t)objspace);
-}
-
-void rb_update_st_references(struct st_table *ht)
-{
- rb_objspace_t *objspace = &rb_objspace;
- gc_update_table_refs(objspace, ht);
-}
-
-static void
-gc_ref_update_method_entry(rb_objspace_t *objspace, rb_method_entry_t *me)
-{
- rb_method_definition_t *def = me->def;
-
- UPDATE_IF_MOVED(objspace, me->owner);
- UPDATE_IF_MOVED(objspace, me->defined_class);
-
- if (def) {
- switch (def->type) {
- case VM_METHOD_TYPE_ISEQ:
- if (def->body.iseq.iseqptr) {
- TYPED_UPDATE_IF_MOVED(objspace, rb_iseq_t *, def->body.iseq.iseqptr);
- }
- TYPED_UPDATE_IF_MOVED(objspace, rb_cref_t *, def->body.iseq.cref);
- break;
- case VM_METHOD_TYPE_ATTRSET:
- case VM_METHOD_TYPE_IVAR:
- UPDATE_IF_MOVED(objspace, def->body.attr.location);
- break;
- case VM_METHOD_TYPE_BMETHOD:
- UPDATE_IF_MOVED(objspace, def->body.bmethod.proc);
- break;
- case VM_METHOD_TYPE_ALIAS:
- TYPED_UPDATE_IF_MOVED(objspace, struct rb_method_entry_struct *, def->body.alias.original_me);
- return;
- case VM_METHOD_TYPE_REFINED:
- TYPED_UPDATE_IF_MOVED(objspace, struct rb_method_entry_struct *, def->body.refined.orig_me);
- UPDATE_IF_MOVED(objspace, def->body.refined.owner);
- break;
- case VM_METHOD_TYPE_CFUNC:
- case VM_METHOD_TYPE_ZSUPER:
- case VM_METHOD_TYPE_MISSING:
- case VM_METHOD_TYPE_OPTIMIZED:
- case VM_METHOD_TYPE_UNDEF:
- case VM_METHOD_TYPE_NOTIMPLEMENTED:
- break;
- }
- }
-}
-
-static void
-gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj)
-{
- switch(imemo_type(obj)) {
- case imemo_env:
- {
- rb_env_t *env = (rb_env_t *)obj;
- TYPED_UPDATE_IF_MOVED(objspace, rb_iseq_t *, env->iseq);
- }
- break;
- break;
- case imemo_cref:
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.cref.klass);
- TYPED_UPDATE_IF_MOVED(objspace, struct rb_cref_struct *, RANY(obj)->as.imemo.cref.next);
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.cref.refinements);
- break;
- case imemo_svar:
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.cref_or_me);
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.lastline);
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.backref);
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.svar.others);
- break;
- case imemo_throw_data:
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.throw_data.throw_obj);
- break;
- case imemo_ifunc:
- if (is_pointer_to_heap(objspace, RANY(obj)->as.imemo.ifunc.data)) {
- TYPED_UPDATE_IF_MOVED(objspace, void *, RANY(obj)->as.imemo.ifunc.data);
- }
- break;
- case imemo_memo:
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.memo.v1);
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.memo.v2);
- if (is_pointer_to_heap(objspace, (void *)RANY(obj)->as.imemo.memo.u3.value)) {
- UPDATE_IF_MOVED(objspace, RANY(obj)->as.imemo.memo.u3.value);
- }
- break;
- case imemo_ment:
- gc_ref_update_method_entry(objspace, &RANY(obj)->as.imemo.ment);
- break;
- case imemo_iseq:
- rb_iseq_update_references((rb_iseq_t *)obj);
- break;
- case imemo_ast:
- case imemo_parser_strterm:
- case imemo_tmpbuf:
- break;
- default:
- rb_bug("not reachable %d", imemo_type(obj));
- break;
- }
-}
-
-static enum rb_id_table_iterator_result
-check_id_table_move(ID id, VALUE value, void *data)
-{
- rb_objspace_t *objspace = (rb_objspace_t *)data;
-
- if (gc_object_moved_p(objspace, (VALUE)value)) {
- return ID_TABLE_REPLACE;
- }
-
- return ID_TABLE_CONTINUE;
-}
-
-/* Returns the new location of an object, if it moved. Otherwise returns
- * the existing location. */
-VALUE
-rb_gc_new_location(VALUE value)
-{
-
- VALUE destination;
-
- if (!SPECIAL_CONST_P((void *)value)) {
- void *poisoned = poisoned_object_p(value);
- unpoison_object(value, false);
-
- if (BUILTIN_TYPE(value) == T_MOVED) {
- destination = (VALUE)RMOVED(value)->destination;
- assert(BUILTIN_TYPE(destination) != T_NONE);
- }
- else {
- destination = value;
- }
-
- /* Re-poison slot if it's not the one we want */
- if (poisoned) {
- GC_ASSERT(BUILTIN_TYPE(value) == T_NONE);
- poison_object(value);
- }
- }
- else {
- destination = value;
- }
-
- return destination;
-}
-
-static enum rb_id_table_iterator_result
-update_id_table(ID *key, VALUE * value, void *data, int existing)
-{
- rb_objspace_t *objspace = (rb_objspace_t *)data;
-
- if (gc_object_moved_p(objspace, (VALUE)*value)) {
- *value = rb_gc_new_location((VALUE)*value);
- }
-
- return ID_TABLE_CONTINUE;
-}
-
-static void
-update_m_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
-{
- if (tbl) {
- rb_id_table_foreach_with_replace(tbl, check_id_table_move, update_id_table, objspace);
- }
-}
-
-static enum rb_id_table_iterator_result
-update_const_table(VALUE value, void *data)
-{
- rb_const_entry_t *ce = (rb_const_entry_t *)value;
- rb_objspace_t * objspace = (rb_objspace_t *)data;
-
- if (gc_object_moved_p(objspace, ce->value)) {
- ce->value = rb_gc_new_location(ce->value);
- }
-
- if (gc_object_moved_p(objspace, ce->file)) {
- ce->file = rb_gc_new_location(ce->file);
- }
-
- return ID_TABLE_CONTINUE;
-}
-
-static void
-update_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
-{
- if (!tbl) return;
- rb_id_table_foreach_values(tbl, update_const_table, objspace);
-}
-
-static void
-update_subclass_entries(rb_objspace_t *objspace, rb_subclass_entry_t *entry)
-{
- while (entry) {
- UPDATE_IF_MOVED(objspace, entry->klass);
- entry = entry->next;
- }
-}
-
-static void
-update_class_ext(rb_objspace_t *objspace, rb_classext_t *ext)
-{
- UPDATE_IF_MOVED(objspace, ext->origin_);
- UPDATE_IF_MOVED(objspace, ext->refined_class);
- update_subclass_entries(objspace, ext->subclasses);
-}
-
-static void
-gc_update_object_references(rb_objspace_t *objspace, VALUE obj)
-{
- RVALUE *any = RANY(obj);
-
- gc_report(4, objspace, "update-refs: %s ->", obj_info(obj));
-
- switch(BUILTIN_TYPE(obj)) {
- case T_CLASS:
- case T_MODULE:
- update_m_tbl(objspace, RCLASS_M_TBL(obj));
- if (!RCLASS_EXT(obj)) break;
- if (RCLASS_IV_TBL(obj)) {
- gc_update_table_refs(objspace, RCLASS_IV_TBL(obj));
- }
- update_class_ext(objspace, RCLASS_EXT(obj));
- update_const_tbl(objspace, RCLASS_CONST_TBL(obj));
- UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
- break;
-
- case T_ICLASS:
- if (FL_TEST(obj, RICLASS_IS_ORIGIN)) {
- update_m_tbl(objspace, RCLASS_M_TBL(obj));
- }
- if (!RCLASS_EXT(obj)) break;
- if (RCLASS_IV_TBL(obj)) {
- gc_update_table_refs(objspace, RCLASS_IV_TBL(obj));
- }
- update_class_ext(objspace, RCLASS_EXT(obj));
- update_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
- UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
- break;
-
- case T_IMEMO:
- gc_ref_update_imemo(objspace, obj);
- break;
-
- case T_NIL:
- case T_FIXNUM:
- case T_NODE:
- case T_MOVED:
- case T_NONE:
- /* These can't move */
- return;
-
- case T_ARRAY:
- if (FL_TEST(obj, ELTS_SHARED)) {
- UPDATE_IF_MOVED(objspace, any->as.array.as.heap.aux.shared);
- }
- else {
- gc_ref_update_array(objspace, obj);
- }
- break;
-
- case T_HASH:
- gc_ref_update_hash(objspace, obj);
- UPDATE_IF_MOVED(objspace, any->as.hash.ifnone);
- break;
-
- case T_STRING:
- if (STR_SHARED_P(obj)) {
- UPDATE_IF_MOVED(objspace, any->as.string.as.heap.aux.shared);
- }
- break;
-
- case T_DATA:
- /* Call the compaction callback, if it exists */
- {
- void *const ptr = DATA_PTR(obj);
- if (ptr) {
- if (RTYPEDDATA_P(obj)) {
- RUBY_DATA_FUNC compact_func = any->as.typeddata.type->function.dcompact;
- if (compact_func) (*compact_func)(ptr);
- }
- }
- }
- break;
-
- case T_OBJECT:
- gc_ref_update_object(objspace, obj);
- break;
-
- case T_FILE:
- if (any->as.file.fptr) {
- UPDATE_IF_MOVED(objspace, any->as.file.fptr->pathv);
- UPDATE_IF_MOVED(objspace, any->as.file.fptr->tied_io_for_writing);
- UPDATE_IF_MOVED(objspace, any->as.file.fptr->writeconv_asciicompat);
- UPDATE_IF_MOVED(objspace, any->as.file.fptr->writeconv_pre_ecopts);
- UPDATE_IF_MOVED(objspace, any->as.file.fptr->encs.ecopts);
- UPDATE_IF_MOVED(objspace, any->as.file.fptr->write_lock);
- }
- break;
- case T_REGEXP:
- UPDATE_IF_MOVED(objspace, any->as.regexp.src);
- break;
-
- case T_SYMBOL:
- if (DYNAMIC_SYM_P((VALUE)any)) {
- UPDATE_IF_MOVED(objspace, RSYMBOL(any)->fstr);
- }
- break;
-
- case T_FLOAT:
- case T_BIGNUM:
- break;
-
- case T_MATCH:
- UPDATE_IF_MOVED(objspace, any->as.match.regexp);
-
- if (any->as.match.str) {
- UPDATE_IF_MOVED(objspace, any->as.match.str);
- }
- break;
-
- case T_RATIONAL:
- UPDATE_IF_MOVED(objspace, any->as.rational.num);
- UPDATE_IF_MOVED(objspace, any->as.rational.den);
- break;
-
- case T_COMPLEX:
- UPDATE_IF_MOVED(objspace, any->as.complex.real);
- UPDATE_IF_MOVED(objspace, any->as.complex.imag);
-
- break;
-
- case T_STRUCT:
- {
- long i, len = RSTRUCT_LEN(obj);
- VALUE *ptr = (VALUE *)RSTRUCT_CONST_PTR(obj);
-
- for (i = 0; i < len; i++) {
- UPDATE_IF_MOVED(objspace, ptr[i]);
- }
- }
- break;
- default:
-#if GC_DEBUG
- rb_gcdebug_print_obj_condition((VALUE)obj);
- rb_obj_info_dump(obj);
- rb_bug("unreachable");
-#endif
- break;
-
- }
-
- UPDATE_IF_MOVED(objspace, RBASIC(obj)->klass);
-
- gc_report(4, objspace, "update-refs: %s <-", obj_info(obj));
-}
-static int
-gc_ref_update(void *vstart, void *vend, size_t stride, void * data)
-{
- rb_objspace_t * objspace;
- struct heap_page *page;
- short free_slots = 0;
-
- VALUE v = (VALUE)vstart;
- objspace = (rb_objspace_t *)data;
- page = GET_HEAP_PAGE(v);
- unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
- page->freelist = NULL;
- poison_memory_region(&page->freelist, sizeof(RVALUE*));
- page->flags.has_uncollectible_shady_objects = FALSE;
-
- /* For each object on the page */
- for (; v != (VALUE)vend; v += stride) {
- if (!SPECIAL_CONST_P(v)) {
- unpoison_object(v, false);
-
- if (BUILTIN_TYPE(v) == T_NONE) {
- heap_page_add_freeobj(objspace, page, v);
- free_slots++;
- }
- else {
- if (RVALUE_WB_UNPROTECTED(v)) {
- page->flags.has_uncollectible_shady_objects = TRUE;
- }
- gc_update_object_references(objspace, v);
- }
- }
- }
-
- page->free_slots = free_slots;
- return 0;
-}
-
-extern rb_symbols_t global_symbols;
-
-static void
-gc_update_references(rb_objspace_t * objspace)
-{
- rb_execution_context_t *ec = GET_EC();
- rb_vm_t *vm = rb_ec_vm_ptr(ec);
-
- rb_objspace_each_objects_without_setup(gc_ref_update, objspace);
- rb_vm_update_references(vm);
- rb_transient_heap_update_references();
- gc_update_table_refs(objspace, global_symbols.str_sym);
-}
-
-static VALUE type_sym(size_t type);
-
-static VALUE
-rb_gc_compact_stats(VALUE mod)
-{
- size_t i;
-
- rb_objspace_t *objspace = &rb_objspace;
- VALUE h = rb_hash_new();
- VALUE considered = rb_hash_new();
- VALUE moved = rb_hash_new();
-
- for (i=0; i<T_MASK; i++) {
- rb_hash_aset(considered, type_sym(i), SIZET2NUM(objspace->rcompactor.considered_count_table[i]));
- }
-
- for (i=0; i<T_MASK; i++) {
- rb_hash_aset(moved, type_sym(i), SIZET2NUM(objspace->rcompactor.moved_count_table[i]));
- }
-
- rb_hash_aset(h, ID2SYM(rb_intern("considered")), considered);
- rb_hash_aset(h, ID2SYM(rb_intern("moved")), moved);
-
- return h;
-}
-
-static VALUE
-rb_gc_compact(VALUE mod)
-{
- rb_objspace_t *objspace = &rb_objspace;
-
- /* Ensure objects are pinned */
- rb_gc();
-
- /* Drain interrupts so that THEAP has a chance to evacuate before
- * any possible compaction. */
- rb_thread_execute_interrupts(rb_thread_current());
-
- gc_compact_heap(objspace);
-
- heap_eden->freelist = NULL;
- gc_update_references(objspace);
-
- rb_clear_method_cache_by_class(rb_cObject);
- rb_clear_constant_cache();
- heap_eden->free_pages = NULL;
- heap_eden->using_page = NULL;
-
- /* GC after compaction to eliminate T_MOVED */
- rb_gc();
-
- return rb_gc_compact_stats(mod);
-}
-
-static void
-root_obj_check_moved_i(const char *category, VALUE obj, void *data)
-{
- if (gc_object_moved_p(&rb_objspace, obj)) {
- rb_bug("ROOT %s points to MOVED: %p -> %s\n", category, (void *)obj, obj_info(rb_gc_new_location(obj)));
- }
-}
-
-static void
-reachable_object_check_moved_i(VALUE ref, void *data)
-{
- VALUE parent = (VALUE)data;
- if (gc_object_moved_p(&rb_objspace, ref)) {
- rb_bug("Object %s points to MOVED: %p -> %s\n", obj_info(parent), (void *)ref, obj_info(rb_gc_new_location(ref)));
- }
-}
-
-static int
-heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data)
-{
- VALUE v = (VALUE)vstart;
- for (; v != (VALUE)vend; v += stride) {
- if (gc_object_moved_p(&rb_objspace, v)) {
- /* Moved object still on the heap, something may have a reference. */
- }
- else {
- void *poisoned = poisoned_object_p(v);
- unpoison_object(v, false);
-
- if (BUILTIN_TYPE(v) != T_NONE) {
- rb_objspace_reachable_objects_from(v, reachable_object_check_moved_i, (void *)v);
- }
-
- if (poisoned) {
- GC_ASSERT(BUILTIN_TYPE(v) == T_NONE);
- poison_object(v);
- }
- }
- }
-
- return 0;
-}
-
-static VALUE
-gc_check_references_for_moved(VALUE dummy)
-{
- rb_objspace_reachable_objects_from_root(root_obj_check_moved_i, NULL);
- rb_objspace_each_objects(heap_check_moved_i, NULL);
- return Qnil;
-}
-
-/*
- * call-seq:
- * GC.verify_compaction_references -> nil
- *
- * Verify compaction reference consistency.
- *
- * This method is implementation specific. During compaction, objects that
- * were moved are replaced with T_MOVED objects. No object should have a
- * reference to a T_MOVED object after compaction.
- *
- * This function doubles the heap to ensure room to move all objects,
- * compacts the heap to make sure everything moves, updates all references,
- * then performs a full GC. If any object contains a reference to a T_MOVED
- * object, that object should be pushed on the mark stack, and will
- * make a SEGV.
- */
-static VALUE
-gc_verify_compaction_references(VALUE dummy)
-{
- VALUE stats;
- rb_objspace_t *objspace = &rb_objspace;
-
- /* Double heap size */
- heap_add_pages(objspace, heap_eden, heap_allocated_pages);
-
- stats = rb_gc_compact(dummy);
-
- gc_check_references_for_moved(dummy);
- gc_verify_internal_consistency(dummy);
-
- return stats;
-}
-
VALUE
rb_gc_start(void)
{
@@ -8150,8 +6998,8 @@ gc_count_add_each_types(VALUE hash, const char *name, const size_t *types)
VALUE result = rb_hash_new_with_size(T_MASK);
int i;
for (i=0; i<T_MASK; i++) {
- const char *type = type_name(i, 0);
- rb_hash_aset(result, ID2SYM(rb_intern(type)), SIZET2NUM(types[i]));
+ const char *type = type_name(i, 0);
+ rb_hash_aset(result, ID2SYM(rb_intern(type)), SIZET2NUM(types[i]));
}
rb_hash_aset(hash, ID2SYM(rb_intern(name)), result);
}
@@ -8194,47 +7042,47 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const int orig_
VALUE flags = orig_flags ? orig_flags : objspace->profile.latest_gc_info;
if (SYMBOL_P(hash_or_key)) {
- key = hash_or_key;
+ key = hash_or_key;
}
else if (RB_TYPE_P(hash_or_key, T_HASH)) {
- hash = hash_or_key;
+ hash = hash_or_key;
}
else {
- rb_raise(rb_eTypeError, "non-hash or symbol given");
+ rb_raise(rb_eTypeError, "non-hash or symbol given");
}
if (sym_major_by == Qnil) {
#define S(s) sym_##s = ID2SYM(rb_intern_const(#s))
- S(major_by);
- S(gc_by);
- S(immediate_sweep);
- S(have_finalizer);
- S(state);
-
- S(stress);
- S(nofree);
- S(oldgen);
- S(shady);
- S(force);
+ S(major_by);
+ S(gc_by);
+ S(immediate_sweep);
+ S(have_finalizer);
+ S(state);
+
+ S(stress);
+ S(nofree);
+ S(oldgen);
+ S(shady);
+ S(force);
#if RGENGC_ESTIMATE_OLDMALLOC
- S(oldmalloc);
+ S(oldmalloc);
#endif
- S(newobj);
- S(malloc);
- S(method);
- S(capi);
+ S(newobj);
+ S(malloc);
+ S(method);
+ S(capi);
- S(none);
- S(marking);
- S(sweeping);
+ S(none);
+ S(marking);
+ S(sweeping);
#undef S
}
#define SET(name, attr) \
if (key == sym_##name) \
- return (attr); \
+ return (attr); \
else if (hash != Qnil) \
- rb_hash_aset(hash, sym_##name, (attr));
+ rb_hash_aset(hash, sym_##name, (attr));
major_by =
(flags & GPR_FLAG_MAJOR_BY_NOFREE) ? sym_nofree :
@@ -8248,25 +7096,25 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const int orig_
SET(major_by, major_by);
SET(gc_by,
- (flags & GPR_FLAG_NEWOBJ) ? sym_newobj :
- (flags & GPR_FLAG_MALLOC) ? sym_malloc :
- (flags & GPR_FLAG_METHOD) ? sym_method :
- (flags & GPR_FLAG_CAPI) ? sym_capi :
- (flags & GPR_FLAG_STRESS) ? sym_stress :
- Qnil
- );
+ (flags & GPR_FLAG_NEWOBJ) ? sym_newobj :
+ (flags & GPR_FLAG_MALLOC) ? sym_malloc :
+ (flags & GPR_FLAG_METHOD) ? sym_method :
+ (flags & GPR_FLAG_CAPI) ? sym_capi :
+ (flags & GPR_FLAG_STRESS) ? sym_stress :
+ Qnil
+ );
SET(have_finalizer, (flags & GPR_FLAG_HAVE_FINALIZE) ? Qtrue : Qfalse);
SET(immediate_sweep, (flags & GPR_FLAG_IMMEDIATE_SWEEP) ? Qtrue : Qfalse);
if (orig_flags == 0) {
- SET(state, gc_mode(objspace) == gc_mode_none ? sym_none :
- gc_mode(objspace) == gc_mode_marking ? sym_marking : sym_sweeping);
+ SET(state, gc_mode(objspace) == gc_mode_none ? sym_none :
+ gc_mode(objspace) == gc_mode_marking ? sym_marking : sym_sweeping);
}
#undef SET
if (!NIL_P(key)) {/* matched key should return above */
- rb_raise(rb_eArgError, "unknown key: %"PRIsVALUE, rb_sym2str(key));
+ rb_raise(rb_eArgError, "unknown key: %"PRIsVALUE, rb_sym2str(key));
}
return hash;
@@ -8296,12 +7144,12 @@ gc_latest_gc_info(int argc, VALUE *argv, VALUE self)
if (rb_check_arity(argc, 0, 1) == 1) {
arg = argv[0];
- if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) {
- rb_raise(rb_eTypeError, "non-hash or symbol given");
- }
+ if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) {
+ rb_raise(rb_eTypeError, "non-hash or symbol given");
+ }
}
else {
- arg = rb_hash_new();
+ arg = rb_hash_new();
}
return gc_info_decode(objspace, arg, 0);
@@ -8328,7 +7176,6 @@ enum gc_stat_sym {
#if USE_RGENGC
gc_stat_sym_minor_gc_count,
gc_stat_sym_major_gc_count,
- gc_stat_sym_object_id_collisions,
gc_stat_sym_remembered_wb_unprotected_objects,
gc_stat_sym_remembered_wb_unprotected_objects_limit,
gc_stat_sym_old_objects,
@@ -8404,7 +7251,6 @@ setup_gc_stat_symbols(void)
S(malloc_increase_bytes_limit);
#if USE_RGENGC
S(minor_gc_count);
- S(object_id_collisions);
S(major_gc_count);
S(remembered_wb_unprotected_objects);
S(remembered_wb_unprotected_objects_limit);
@@ -8577,7 +7423,6 @@ gc_stat_internal(VALUE hash_or_sym)
SET(malloc_increase_bytes_limit, malloc_limit);
#if USE_RGENGC
SET(minor_gc_count, objspace->profile.minor_gc_count);
- SET(object_id_collisions, objspace->profile.object_id_collisions);
SET(major_gc_count, objspace->profile.major_gc_count);
SET(remembered_wb_unprotected_objects, objspace->rgengc.uncollectible_wb_unprotected_objects);
SET(remembered_wb_unprotected_objects_limit, objspace->rgengc.uncollectible_wb_unprotected_objects_limit);
@@ -9783,25 +8628,10 @@ wmap_mark_map(st_data_t key, st_data_t val, st_data_t arg)
}
#endif
-static int
-wmap_pin_obj(st_data_t key, st_data_t val, st_data_t arg)
-{
- rb_objspace_t *objspace = (rb_objspace_t *)arg;
- VALUE obj = (VALUE)val;
- if (obj && is_live_object(objspace, obj)) {
- gc_pin(objspace, obj);
- }
- else {
- return ST_DELETE;
- }
- return ST_CONTINUE;
-}
-
static void
wmap_mark(void *ptr)
{
struct weakmap *w = ptr;
- if (w->wmap2obj) st_foreach(w->wmap2obj, wmap_pin_obj, (st_data_t)&rb_objspace);
#if WMAP_DELETE_DEAD_OBJECT_IN_MARK
if (w->obj2wmap) st_foreach(w->obj2wmap, wmap_mark_map, (st_data_t)&rb_objspace);
#endif
@@ -10801,7 +9631,6 @@ type_name(int type, VALUE obj)
TYPE_NAME(T_UNDEF);
TYPE_NAME(T_IMEMO);
TYPE_NAME(T_ICLASS);
- TYPE_NAME(T_MOVED);
TYPE_NAME(T_ZOMBIE);
case T_DATA:
if (obj && rb_objspace_data_type_name(obj)) {
@@ -10850,7 +9679,7 @@ method_type_name(rb_method_type_t type)
static void
rb_raw_iseq_info(char *buff, const int buff_size, const rb_iseq_t *iseq)
{
- if (iseq->body && iseq->body->location.label && !RB_TYPE_P(iseq->body->location.pathobj, T_MOVED)) {
+ if (iseq->body && iseq->body->location.label) {
VALUE path = rb_iseq_path(iseq);
VALUE n = iseq->body->location.first_lineno;
snprintf(buff, buff_size, "%s %s@%s:%d", buff,
@@ -10881,11 +9710,10 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
const int age = RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
if (is_pointer_to_heap(&rb_objspace, (void *)obj)) {
- snprintf(buff, buff_size, "%p [%d%s%s%s%s%s] %s",
+ snprintf(buff, buff_size, "%p [%d%s%s%s%s] %s",
(void *)obj, age,
C(RVALUE_UNCOLLECTIBLE_BITMAP(obj), "L"),
C(RVALUE_MARK_BITMAP(obj), "M"),
- C(RVALUE_PIN_BITMAP(obj), "P"),
C(RVALUE_MARKING_BITMAP(obj), "R"),
C(RVALUE_WB_UNPROTECTED_BITMAP(obj), "U"),
obj_type_name(obj));
@@ -10910,12 +9738,10 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
snprintf(buff, buff_size, "%s (temporary internal)", buff);
}
else {
- if (RTEST(RBASIC(obj)->klass)) {
VALUE class_path = rb_class_path_cached(RBASIC(obj)->klass);
if (!NIL_P(class_path)) {
snprintf(buff, buff_size, "%s (%s)", buff, RSTRING_PTR(class_path));
}
- }
}
#if GC_DEBUG
@@ -10951,10 +9777,6 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
snprintf(buff, buff_size, "%s %s", buff, RSTRING_PTR(obj));
break;
}
- case T_MOVED: {
- snprintf(buff, buff_size, "-> %p", (void*)rb_gc_new_location(obj));
- break;
- }
case T_HASH: {
snprintf(buff, buff_size, "%s [%c%c] %d", buff,
RHASH_AR_TABLE_P(obj) ? 'A' : 'S',
@@ -11116,12 +9938,6 @@ rb_gcdebug_print_obj_condition(VALUE obj)
fprintf(stderr, "created at: %s:%d\n", RANY(obj)->file, RANY(obj)->line);
- if (BUILTIN_TYPE(obj) == T_MOVED) {
- fprintf(stderr, "moved?: true\n");
- }
- else {
- fprintf(stderr, "moved?: false\n");
- }
if (is_pointer_to_heap(objspace, (void *)obj)) {
fprintf(stderr, "pointer to heap?: true\n");
}
@@ -11131,7 +9947,6 @@ rb_gcdebug_print_obj_condition(VALUE obj)
}
fprintf(stderr, "marked? : %s\n", MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(obj), obj) ? "true" : "false");
- fprintf(stderr, "pinned? : %s\n", MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj) ? "true" : "false");
#if USE_RGENGC
fprintf(stderr, "age? : %d\n", RVALUE_AGE(obj));
fprintf(stderr, "old? : %s\n", RVALUE_OLD_P(obj) ? "true" : "false");
@@ -11281,9 +10096,6 @@ Init_GC(void)
VALUE rb_mProfiler;
VALUE gc_constants;
- id_to_obj_tbl = st_init_numtable();
- obj_to_id_tbl = rb_init_identtable();
-
rb_mGC = rb_define_module("GC");
rb_define_singleton_method(rb_mGC, "start", gc_start_internal, -1);
rb_define_singleton_method(rb_mGC, "enable", rb_gc_enable, 0);
@@ -11293,7 +10105,6 @@ Init_GC(void)
rb_define_singleton_method(rb_mGC, "count", gc_count, 0);
rb_define_singleton_method(rb_mGC, "stat", gc_stat, -1);
rb_define_singleton_method(rb_mGC, "latest_gc_info", gc_latest_gc_info, -1);
- rb_define_singleton_method(rb_mGC, "compact", rb_gc_compact, 0);
rb_define_method(rb_mGC, "garbage_collect", gc_start_internal, -1);
gc_constants = rb_hash_new();
@@ -11354,7 +10165,6 @@ Init_GC(void)
/* internal methods */
rb_define_singleton_method(rb_mGC, "verify_internal_consistency", gc_verify_internal_consistency, 0);
- rb_define_singleton_method(rb_mGC, "verify_compaction_references", gc_verify_compaction_references, 0);
rb_define_singleton_method(rb_mGC, "verify_transient_heap_internal_consistency", gc_verify_transient_heap_internal_consistency, 0);
#if MALLOC_ALLOCATED_SIZE
rb_define_singleton_method(rb_mGC, "malloc_allocated_size", gc_malloc_allocated_size, 0);
diff --git a/gc.h b/gc.h
index 727890181a..2c91e06620 100644
--- a/gc.h
+++ b/gc.h
@@ -57,10 +57,6 @@ rb_gc_debug_body(const char *mode, const char *msg, int st, void *ptr)
#define RUBY_GC_INFO if(0)printf
#endif
-#define RUBY_MARK_NO_PIN_UNLESS_NULL(ptr) do { \
- VALUE markobj = (ptr); \
- if (RTEST(markobj)) {rb_gc_mark_no_pin(markobj);} \
-} while (0)
#define RUBY_MARK_UNLESS_NULL(ptr) do { \
VALUE markobj = (ptr); \
if (RTEST(markobj)) {rb_gc_mark(markobj);} \
diff --git a/hash.c b/hash.c
index 36d5a86760..658a105177 100644
--- a/hash.c
+++ b/hash.c
@@ -781,7 +781,7 @@ ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash
}
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 (*func)(ANYARGS), st_update_callback_func *re
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 (*func)(ANYARGS), st_update_callback_func *re
}
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)(ANYARGS), st_data_t arg,
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 (*func)(ANYARGS), st_data_t arg)
}
}
-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)
{
diff --git a/id_table.c b/id_table.c
index f566582479..74c9e756a0 100644
--- a/id_table.c
+++ b/id_table.c
@@ -267,28 +267,6 @@ rb_id_table_delete(struct rb_id_table *tbl, ID id)
}
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;
diff --git a/id_table.h b/id_table.h
index abd9eb5f38..b10b4ac164 100644
--- a/id_table.h
+++ b/id_table.h
@@ -9,7 +9,6 @@ enum rb_id_table_iterator_result {
ID_TABLE_CONTINUE = ST_CONTINUE,
ID_TABLE_STOP = ST_STOP,
ID_TABLE_DELETE = ST_DELETE,
- ID_TABLE_REPLACE = ST_REPLACE,
ID_TABLE_ITERATOR_RESULT_END
};
@@ -24,11 +23,9 @@ int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val);
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp);
int rb_id_table_delete(struct rb_id_table *tbl, ID id);
-typedef enum rb_id_table_iterator_result rb_id_table_update_callback_func_t(ID *id, VALUE *val, void *data, int existing);
typedef enum rb_id_table_iterator_result rb_id_table_foreach_func_t(ID id, VALUE val, void *data);
typedef enum rb_id_table_iterator_result rb_id_table_foreach_values_func_t(VALUE val, void *data);
void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data);
-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);
void rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, void *data);
#endif /* RUBY_ID_TABLE_H */
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 192347c8d5..17aafd7f8e 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -507,15 +507,10 @@ COLDFUNC NORETURN(void rb_memerror(void));
PUREFUNC(int rb_during_gc(void));
void rb_gc_mark_locations(const VALUE*, const VALUE*);
void rb_mark_tbl(struct st_table*);
-void rb_mark_tbl_no_pin(struct st_table*);
-void rb_gc_update_tbl_refs(st_table *ptr);
void rb_mark_set(struct st_table*);
void rb_mark_hash(struct st_table*);
-void rb_update_st_references(struct st_table *ht);
void rb_gc_mark_maybe(VALUE);
void rb_gc_mark(VALUE);
-void rb_gc_mark_no_pin(VALUE);
-VALUE rb_gc_new_location(VALUE);
void rb_gc_force_recycle(VALUE);
void rb_gc(void);
void rb_gc_copy_finalizer(VALUE,VALUE);
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index b5757a79ad..11387b540a 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -512,7 +512,6 @@ enum ruby_value_type {
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 {
#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)
@@ -885,7 +883,7 @@ enum ruby_fl_type {
struct RUBY_ALIGNAS(SIZEOF_VALUE) RBasic {
VALUE flags;
- VALUE klass;
+ const VALUE klass;
};
VALUE rb_obj_hide(VALUE obj);
@@ -1107,7 +1105,7 @@ struct RArray {
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)
@@ -1146,8 +1144,7 @@ struct rb_data_type_struct {
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;
@@ -1258,7 +1255,6 @@ int rb_big_sign(VALUE);
#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))
diff --git a/include/ruby/st.h b/include/ruby/st.h
index a7eb0c6d7c..149e0ebaef 100644
--- a/include/ruby/st.h
+++ b/include/ruby/st.h
@@ -96,7 +96,7 @@ struct st_table {
#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
-enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK, ST_REPLACE};
+enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
st_table *st_init_table(const struct st_hash_type *);
st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t);
@@ -118,7 +118,6 @@ typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t
* results of hash() are same and compare() returns 0, otherwise the
* behavior is undefined */
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
-int st_foreach_with_replace(st_table *tab, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg);
int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t, st_data_t);
st_index_t st_keys(st_table *table, st_data_t *keys, st_index_t size);
diff --git a/internal.h b/internal.h
index 46a25ff77f..a9b4cfb4d5 100644
--- a/internal.h
+++ b/internal.h
@@ -731,8 +731,8 @@ struct RBignum {
struct RRational {
struct RBasic basic;
- VALUE num;
- VALUE den;
+ const VALUE num;
+ const VALUE den;
};
#define RRATIONAL(obj) (R_CAST(RRational)(obj))
@@ -748,8 +748,8 @@ struct RFloat {
struct RComplex {
struct RBasic basic;
- VALUE real;
- VALUE imag;
+ const VALUE real;
+ const VALUE imag;
};
#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
@@ -816,8 +816,8 @@ struct RHash {
st_table *st;
struct ar_table_struct *ar; /* possibly 0 */
} as;
- int iter_lev;
- VALUE ifnone;
+ const int iter_lev;
+ const VALUE ifnone;
};
#ifdef RHASH_ITER_LEV
@@ -830,11 +830,6 @@ struct RHash {
# define RHASH_SIZE(h) (RHASH_AR_TABLE_P(h) ? RHASH_AR_TABLE_SIZE_RAW(h) : RHASH_ST_SIZE(h))
#endif /* #ifdef RHASH_ITER_LEV */
-struct RMoved {
- VALUE flags;
- VALUE destination;
-};
-
/* missing/setproctitle.c */
#ifndef HAVE_SETPROCTITLE
extern void ruby_init_setproctitle(int argc, char *argv[]);
@@ -952,7 +947,7 @@ struct rb_classext_struct {
*/
rb_subclass_entry_t **module_subclasses;
rb_serial_t class_serial;
- VALUE origin_;
+ const VALUE origin_;
VALUE refined_class;
rb_alloc_func_t allocator;
};
@@ -1070,10 +1065,10 @@ imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
/*! SVAR (Special VARiable) */
struct vm_svar {
VALUE flags;
- VALUE cref_or_me; /*!< class reference or rb_method_entry_t */
- VALUE lastline;
- VALUE backref;
- VALUE others;
+ const VALUE cref_or_me; /*!< class reference or rb_method_entry_t */
+ const VALUE lastline;
+ const VALUE backref;
+ const VALUE others;
};
@@ -1083,7 +1078,7 @@ struct vm_svar {
struct vm_throw_data {
VALUE flags;
VALUE reserved;
- VALUE throw_obj;
+ const VALUE throw_obj;
const struct rb_control_frame_struct *catch_frame;
VALUE throw_state;
};
@@ -1106,7 +1101,7 @@ struct vm_ifunc {
VALUE flags;
VALUE reserved;
VALUE (*func)(ANYARGS);
- void *data;
+ const void *data;
struct vm_ifunc_argc argc;
};
@@ -1163,12 +1158,12 @@ void rb_strterm_mark(VALUE obj);
struct MEMO {
VALUE flags;
VALUE reserved;
- VALUE v1;
- VALUE v2;
+ const VALUE v1;
+ const VALUE v2;
union {
long cnt;
long state;
- VALUE value;
+ const VALUE value;
VALUE (*func)(ANYARGS);
} u3;
};
@@ -1571,7 +1566,6 @@ void rb_hash_bulk_insert(long, const VALUE *, VALUE);
int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
int rb_hash_stlike_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg);
-int rb_hash_stlike_foreach_with_replace(VALUE hash, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg);
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg);
/* inits.c */
@@ -2336,7 +2330,6 @@ extern unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, si
/* variable.c (export) */
void rb_mark_generic_ivar(VALUE);
-void rb_mv_generic_ivar(VALUE src, VALUE dst);
VALUE rb_const_missing(VALUE klass, VALUE name);
int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
st_table *rb_st_copy(VALUE obj, struct st_table *orig_tbl);
@@ -2348,10 +2341,9 @@ VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE);
size_t rb_obj_memsize_of(VALUE);
void rb_gc_verify_internal_consistency(void);
-#define RB_OBJ_GC_FLAGS_MAX 6
+#define RB_OBJ_GC_FLAGS_MAX 5
size_t rb_obj_gc_flags(VALUE, ID[], size_t);
void rb_gc_mark_values(long n, const VALUE *values);
-void rb_gc_mark_stack_values(long n, const VALUE *values);
#if IMEMO_DEBUG
VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0, const char *file, int line);
diff --git a/io.c b/io.c
index 73108f7747..cd83f520af 100644
--- a/io.c
+++ b/io.c
@@ -10996,8 +10996,7 @@ nogvl_fcopyfile(struct copy_stream_struct *stp)
return 1;
}
}
- }
- else {
+ } else {
switch (errno) {
case ENOTSUP:
case EPERM:
diff --git a/iseq.c b/iseq.c
index 7c721d61b0..0ec48da585 100644
--- a/iseq.c
+++ b/iseq.c
@@ -136,11 +136,11 @@ rb_vm_insn_null_translator(const void *addr)
return (VALUE)addr;
}
-typedef VALUE iseq_value_itr_t(void *ctx, VALUE obj);
+typedef void iseq_value_itr_t(void *ctx, VALUE obj);
typedef VALUE rb_vm_insns_translator_t(const void *addr);
static int
-iseq_extract_values(VALUE *code, size_t pos, iseq_value_itr_t * func, void *data, rb_vm_insns_translator_t * translator)
+iseq_extract_values(const VALUE *code, size_t pos, iseq_value_itr_t * func, void *data, rb_vm_insns_translator_t * translator)
{
VALUE insn = translator((void *)code[pos]);
int len = insn_len(insn);
@@ -156,10 +156,7 @@ iseq_extract_values(VALUE *code, size_t pos, iseq_value_itr_t * func, void *data
{
VALUE op = code[pos + op_no + 1];
if (!SPECIAL_CONST_P(op)) {
- VALUE newop = func(data, op);
- if (newop != op) {
- code[pos + op_no + 1] = newop;
- }
+ func(data, op);
}
break;
}
@@ -167,10 +164,7 @@ iseq_extract_values(VALUE *code, size_t pos, iseq_value_itr_t * func, void *data
{
union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)code[pos + op_no + 1];
if (is->once.value) {
- VALUE nv = func(data, is->once.value);
- if (is->once.value != nv) {
- is->once.value = nv;
- }
+ func(data, is->once.value);
}
break;
}
@@ -186,7 +180,7 @@ static void
rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
{
unsigned int size;
- VALUE *code;
+ const VALUE *code;
size_t n;
rb_vm_insns_translator_t * translator;
const struct rb_iseq_constant_body *const body = iseq->body;
@@ -210,65 +204,10 @@ rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
}
}
-static VALUE
-update_each_insn_value(void *ctx, VALUE obj)
-{
- return rb_gc_new_location(obj);
-}
-
-void
-rb_iseq_update_references(rb_iseq_t *iseq)
-{
- if (iseq->body) {
- struct rb_iseq_constant_body *body = iseq->body;
-
- body->variable.coverage = rb_gc_new_location(body->variable.coverage);
- body->variable.pc2branchindex = rb_gc_new_location(body->variable.pc2branchindex);
- body->location.label = rb_gc_new_location(body->location.label);
- body->location.base_label = rb_gc_new_location(body->location.base_label);
- body->location.pathobj = rb_gc_new_location(body->location.pathobj);
- if (body->local_iseq) {
- body->local_iseq = (struct rb_iseq_struct *)rb_gc_new_location((VALUE)body->local_iseq);
- }
- if (body->parent_iseq) {
- body->parent_iseq = (struct rb_iseq_struct *)rb_gc_new_location((VALUE)body->parent_iseq);
- }
- if (FL_TEST(iseq, ISEQ_MARKABLE_ISEQ)) {
- rb_iseq_each_value(iseq, update_each_insn_value, NULL);
- }
-
- if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
- int i, j;
-
- i = body->param.keyword->required_num;
-
- for (j = 0; i < body->param.keyword->num; i++, j++) {
- VALUE obj = body->param.keyword->default_values[j];
- if (obj != Qundef) {
- body->param.keyword->default_values[j] = rb_gc_new_location(obj);
- }
- }
- }
-
- if (body->catch_table) {
- struct iseq_catch_table *table = body->catch_table;
- unsigned int i;
- for(i = 0; i < table->size; i++) {
- struct iseq_catch_table_entry *entry;
- entry = &table->entries[i];
- if (entry->iseq) {
- entry->iseq = (rb_iseq_t *)rb_gc_new_location((VALUE)entry->iseq);
- }
- }
- }
- }
-}
-
-static VALUE
+static void
each_insn_value(void *ctx, VALUE obj)
{
- rb_gc_mark_no_pin(obj);
- return obj;
+ rb_gc_mark(obj);
}
void
@@ -285,12 +224,12 @@ rb_iseq_mark(const rb_iseq_t *iseq)
rb_iseq_each_value(iseq, each_insn_value, NULL);
}
- rb_gc_mark_no_pin(body->variable.coverage);
- rb_gc_mark_no_pin(body->variable.pc2branchindex);
- rb_gc_mark_no_pin(body->location.label);
- rb_gc_mark_no_pin(body->location.base_label);
- rb_gc_mark_no_pin(body->location.pathobj);
- RUBY_MARK_NO_PIN_UNLESS_NULL((VALUE)body->parent_iseq);
+ rb_gc_mark(body->variable.coverage);
+ rb_gc_mark(body->variable.pc2branchindex);
+ rb_gc_mark(body->location.label);
+ rb_gc_mark(body->location.base_label);
+ rb_gc_mark(body->location.pathobj);
+ RUBY_MARK_UNLESS_NULL((VALUE)body->parent_iseq);
if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
const struct rb_iseq_param_keyword *const keyword = body->param.keyword;
@@ -313,7 +252,7 @@ rb_iseq_mark(const rb_iseq_t *iseq)
const struct iseq_catch_table_entry *entry;
entry = &table->entries[i];
if (entry->iseq) {
- rb_gc_mark_no_pin((VALUE)entry->iseq);
+ rb_gc_mark((VALUE)entry->iseq);
}
}
}
@@ -324,16 +263,11 @@ rb_iseq_mark(const rb_iseq_t *iseq)
}
else if (FL_TEST_RAW(iseq, ISEQ_USE_COMPILE_DATA)) {
const struct iseq_compile_data *const compile_data = ISEQ_COMPILE_DATA(iseq);
- if (RTEST(compile_data->mark_ary)) {
- rb_gc_mark(compile_data->mark_ary);
- rb_gc_mark_values(RARRAY_LEN(compile_data->mark_ary), RARRAY_CONST_PTR(compile_data->mark_ary));
- }
- RUBY_MARK_UNLESS_NULL(compile_data->err_info);
- if (RTEST(compile_data->catch_table_ary)) {
- rb_gc_mark(compile_data->catch_table_ary);
- rb_gc_mark_values(RARRAY_LEN(compile_data->catch_table_ary), RARRAY_CONST_PTR(compile_data->catch_table_ary));
- }
VM_ASSERT(compile_data != NULL);
+
+ RUBY_MARK_UNLESS_NULL(compile_data->mark_ary);
+ RUBY_MARK_UNLESS_NULL(compile_data->err_info);
+ RUBY_MARK_UNLESS_NULL(compile_data->catch_table_ary);
}
else {
/* executable */
diff --git a/iseq.h b/iseq.h
index 9681d16f5f..feb73a82ae 100644
--- a/iseq.h
+++ b/iseq.h
@@ -234,7 +234,7 @@ struct iseq_catch_table_entry {
* CATCH_TYPE_REDO, CATCH_TYPE_NEXT:
* NULL.
*/
- rb_iseq_t *iseq;
+ const rb_iseq_t *iseq;
unsigned int start;
unsigned int end;
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index 1c7e89ba14..fa9b19071a 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -1530,7 +1530,6 @@ module Net
end
@sock = SSLSocket.new(@sock, context)
@sock.sync_close = true
- @sock.hostname = @host if @sock.respond_to? :hostname=
ssl_socket_connect(@sock, @open_timeout)
if context.verify_mode != VERIFY_NONE
@sock.post_connection_check(@host)
diff --git a/method.h b/method.h
index 2a6d85a2dd..65ea9dd0c2 100644
--- a/method.h
+++ b/method.h
@@ -40,9 +40,9 @@ typedef struct rb_scope_visi_struct {
/*! 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 {
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;
#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 {
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;
diff --git a/mjit_worker.c b/mjit_worker.c
index 205082f7a9..a85e7e8eae 100644
--- a/mjit_worker.c
+++ b/mjit_worker.c
@@ -1180,8 +1180,7 @@ mjit_copy_cache_from_main_thread(const rb_iseq_t *iseq, struct rb_call_cache *cc
if (UNLIKELY(mjit_opts.wait)) {
mjit_copy_job_handler((void *)job);
- }
- else if (rb_workqueue_register(0, mjit_copy_job_handler, (void *)job)) {
+ } else if (rb_workqueue_register(0, mjit_copy_job_handler, (void *)job)) {
CRITICAL_SECTION_START(3, "in MJIT copy job wait");
// checking `stop_worker_p` too because `RUBY_VM_CHECK_INTS(ec)` may not
// lush mjit_copy_job_handler when EC_EXEC_TAG() is not TAG_NONE, and then
diff --git a/parse.y b/parse.y
index 90652686db..ff4fe986fe 100644
--- a/parse.y
+++ b/parse.y
@@ -9307,7 +9307,7 @@ void
rb_parser_fatal(struct parser_params *p, const char *fmt, ...)
{
va_list ap;
- VALUE mesg = rb_str_new_cstr("internal parser error: ");
+ VALUE mesg = rb_str_new_cstr("internal p error: ");
va_start(ap, fmt);
rb_str_vcatf(mesg, fmt, ap);
@@ -9317,13 +9317,13 @@ rb_parser_fatal(struct parser_params *p, const char *fmt, ...)
mesg = rb_str_new(0, 0);
append_lex_state_name(p->lex.state, mesg);
- compile_error(p, "lex.state: %"PRIsVALUE, mesg);
+ compile_error(p, "p->lex.state: %"PRIsVALUE, mesg);
rb_str_resize(mesg, 0);
append_bitstack_value(p->cond_stack, mesg);
- compile_error(p, "cond_stack: %"PRIsVALUE, mesg);
+ compile_error(p, "p->cond_stack: %"PRIsVALUE, mesg);
rb_str_resize(mesg, 0);
append_bitstack_value(p->cmdarg_stack, mesg);
- compile_error(p, "cmdarg_stack: %"PRIsVALUE, mesg);
+ compile_error(p, "p->cmdarg_stack: %"PRIsVALUE, mesg);
if (p->debug_output == rb_stdout)
p->debug_output = rb_stderr;
p->debug = TRUE;
diff --git a/st.c b/st.c
index cecc2ac67f..ed235c674e 100644
--- a/st.c
+++ b/st.c
@@ -1548,7 +1548,7 @@ st_update(st_table *tab, st_data_t key,
different for ST_CHECK and when the current element is removed
during traversing. */
static inline int
-st_general_foreach(st_table *tab, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg,
+st_general_foreach(st_table *tab, int (*func)(ANYARGS), st_data_t arg,
int check_p)
{
st_index_t bin;
@@ -1572,15 +1572,6 @@ st_general_foreach(st_table *tab, int (*func)(ANYARGS), st_update_callback_func
rebuilds_num = tab->rebuilds_num;
hash = curr_entry_ptr->hash;
retval = (*func)(key, curr_entry_ptr->record, arg, 0);
-
- if (retval == ST_REPLACE && replace) {
- st_data_t value;
- value = curr_entry_ptr->record;
- retval = (*replace)(&key, &value, arg, TRUE);
- curr_entry_ptr->key = key;
- curr_entry_ptr->record = value;
- }
-
if (rebuilds_num != tab->rebuilds_num) {
retry:
entries = tab->entries;
@@ -1609,8 +1600,6 @@ st_general_foreach(st_table *tab, int (*func)(ANYARGS), st_update_callback_func
curr_entry_ptr = &entries[i];
}
switch (retval) {
- case ST_REPLACE:
- break;
case ST_CONTINUE:
break;
case ST_CHECK:
@@ -1659,15 +1648,9 @@ st_general_foreach(st_table *tab, int (*func)(ANYARGS), st_update_callback_func
}
int
-st_foreach_with_replace(st_table *tab, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg)
-{
- return st_general_foreach(tab, func, replace, arg, TRUE);
-}
-
-int
st_foreach(st_table *tab, int (*func)(ANYARGS), st_data_t arg)
{
- return st_general_foreach(tab, func, NULL, arg, FALSE);
+ return st_general_foreach(tab, func, arg, FALSE);
}
/* See comments for function st_delete_safe. */
@@ -1675,7 +1658,7 @@ int
st_foreach_check(st_table *tab, int (*func)(ANYARGS), st_data_t arg,
st_data_t never ATTRIBUTE_UNUSED)
{
- return st_general_foreach(tab, func, NULL, arg, TRUE);
+ return st_general_foreach(tab, func, arg, TRUE);
}
/* Set up array KEYS by at most SIZE keys of head table TAB entries.
diff --git a/symbol.c b/symbol.c
index a3422501a8..09fe7ecb33 100644
--- a/symbol.c
+++ b/symbol.c
@@ -60,7 +60,12 @@ enum id_entry_type {
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,
diff --git a/symbol.h b/symbol.h
index 3b9866d80f..56568a91fc 100644
--- a/symbol.h
+++ b/symbol.h
@@ -54,13 +54,6 @@ id_type(ID id)
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)
{
diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index 0b5cd84241..274afba3bb 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -272,11 +272,6 @@ class OpenSSL::TestBN < OpenSSL::TestCase
assert_equal(0, @e1.ucmp(-999))
assert_instance_of(String, @e1.hash.to_s)
end
-
- def test_type_error
- bug15760 = '[ruby-core:92231] [Bug #15760]'
- assert_raise(TypeError, bug15760) { OpenSSL::BN.new(nil, 2) }
- end
end
end
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb
index 52ab9fc54a..3e17344bbc 100644
--- a/test/ruby/test_gc.rb
+++ b/test/ruby/test_gc.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: false
require 'test/unit'
-require 'fiddle'
class TestGc < Test::Unit::TestCase
class S
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
deleted file mode 100644
index 0b2acacdc9..0000000000
--- a/test/ruby/test_gc_compact.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-# frozen_string_literal: true
-require 'test/unit'
-require 'fiddle'
-
-class TestGCCompact < Test::Unit::TestCase
- if Fiddle::SIZEOF_LONG == Fiddle::SIZEOF_VOIDP
- def memory_location(obj)
- (Fiddle.dlwrap(obj) >> 1)
- end
- elsif Fiddle::SIZEOF_LONG_LONG == Fiddle::SIZEOF_VOIDP
- def memory_location(obj)
- (Fiddle.dlwrap(obj) >> 1) / 2
- end
- else
- raise "Not supported"
- 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)
-
- # All object ids should be equal
- assert_equal 0, assert_object_ids(list_of_objects) # should be 0
-
- GC.compact
-
- # 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.compact
-
- 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
diff --git a/timev.h b/timev.h
index 6f124aa6bf..d9d84b6d1c 100644
--- a/timev.h
+++ b/timev.h
@@ -1,9 +1,6 @@
#ifndef RUBY_TIMEV_H
#define RUBY_TIMEV_H
-#if 0
-struct vtm {/* dummy for TAGS */};
-#endif
PACKED_STRUCT_UNALIGNED(struct vtm {
VALUE year; /* 2000 for example. Integer. */
VALUE subsecx; /* 0 <= subsecx < TIME_SCALE. possibly Rational. */
diff --git a/transient_heap.c b/transient_heap.c
index c89d705fa9..55a796325f 100644
--- a/transient_heap.c
+++ b/transient_heap.c
@@ -796,56 +796,6 @@ blocks_clear_marked_index(struct transient_heap_block* block)
}
}
-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);
- n++;
- }
-}
-
-static void
-transient_heap_blocks_update_refs(struct transient_heap* theap, struct transient_heap_block *block, const char *type_str)
-{
- while (block) {
- transient_heap_block_update_refs(theap, block);
- block = block->info.next_block;
- }
-}
-
-void
-rb_transient_heap_update_references(void)
-{
- struct transient_heap* theap = transient_heap_get();
- int i;
-
- transient_heap_blocks_update_refs(theap, theap->using_blocks, "using_blocks");
- transient_heap_blocks_update_refs(theap, theap->marked_blocks, "marked_blocks");
-
- for (i=0; i<theap->promoted_objects_index; i++) {
- VALUE obj = theap->promoted_objects[i];
- theap->promoted_objects[i] == rb_gc_new_location(obj);
- }
-}
-
void
rb_transient_heap_start_marking(int full_marking)
{
diff --git a/transient_heap.h b/transient_heap.h
index 7b5c42ca8e..a34aa1e4f8 100644
--- a/transient_heap.h
+++ b/transient_heap.h
@@ -30,7 +30,6 @@ void rb_transient_heap_mark(VALUE obj, const void *ptr);
void rb_transient_heap_promote(VALUE obj);
void rb_transient_heap_start_marking(int full_marking);
void rb_transient_heap_finish_marking(void);
-void rb_transient_heap_update_references(void);
/* for debug API */
void rb_transient_heap_dump(void);
@@ -49,7 +48,6 @@ void rb_struct_transient_heap_evacuate(VALUE st, int promote);
#define rb_transient_heap_verify() ((void)0)
#define rb_transient_heap_promote(obj) ((void)0)
#define rb_transient_heap_start_marking(full_marking) ((void)0)
-#define rb_transient_heap_update_references() ((void)0)
#define rb_transient_heap_finish_marking() ((void)0)
#define rb_transient_heap_mark(obj, ptr) ((void)0)
diff --git a/variable.c b/variable.c
index 2c69e2169c..f4988b699d 100644
--- a/variable.c
+++ b/variable.c
@@ -1201,16 +1201,6 @@ rb_mark_generic_ivar(VALUE obj)
}
void
-rb_mv_generic_ivar(VALUE rsrc, VALUE dst)
-{
- st_data_t key = (st_data_t)rsrc;
- struct gen_ivtbl *ivtbl;
-
- if (st_delete(generic_iv_tbl, &key, (st_data_t *)&ivtbl))
- st_insert(generic_iv_tbl, (st_data_t)dst, (st_data_t)ivtbl);
-}
-
-void
rb_free_generic_ivar(VALUE obj)
{
st_data_t key = (st_data_t)obj;
@@ -1960,7 +1950,7 @@ rb_mod_const_missing(VALUE klass, VALUE name)
static void
autoload_mark(void *ptr)
{
- rb_mark_tbl_no_pin((st_table *)ptr);
+ rb_mark_tbl((st_table *)ptr);
}
static void
@@ -1976,15 +1966,9 @@ autoload_memsize(const void *ptr)
return st_memsize(tbl);
}
-static void
-autoload_compact(void *ptr)
-{
- rb_gc_update_tbl_refs((st_table *)ptr);
-}
-
static const rb_data_type_t autoload_data_type = {
"autoload",
- {autoload_mark, autoload_free, autoload_memsize, autoload_compact,},
+ {autoload_mark, autoload_free, autoload_memsize,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -2031,18 +2015,11 @@ struct autoload_data_i {
};
static void
-autoload_i_compact(void *ptr)
-{
- struct autoload_data_i *p = ptr;
- p->feature = rb_gc_new_location(p->feature);
-}
-
-static void
autoload_i_mark(void *ptr)
{
struct autoload_data_i *p = ptr;
- rb_gc_mark_no_pin(p->feature);
+ rb_gc_mark(p->feature);
/* allow GC to free us if no modules refer to this via autoload_const.ad */
if (list_empty(&p->constants)) {
@@ -2069,7 +2046,7 @@ autoload_i_memsize(const void *ptr)
static const rb_data_type_t autoload_data_i_type = {
"autoload_i",
- {autoload_i_mark, autoload_i_free, autoload_i_memsize, autoload_i_compact},
+ {autoload_i_mark, autoload_i_free, autoload_i_memsize,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -2994,7 +2971,6 @@ rb_define_const(VALUE klass, const char *name, VALUE val)
if (!rb_is_const_id(id)) {
rb_warn("rb_define_const: invalid name `%s' for constant", name);
}
- rb_gc_register_mark_object(val);
rb_const_set(klass, id, val);
}
diff --git a/version.h b/version.h
index 25d44bcdf9..d12834f815 100644
--- a/version.h
+++ b/version.h
@@ -6,7 +6,7 @@
#define RUBY_RELEASE_YEAR 2019
#define RUBY_RELEASE_MONTH 4
-#define RUBY_RELEASE_DAY 10
+#define RUBY_RELEASE_DAY 9
#include "ruby/version.h"
diff --git a/vm.c b/vm.c
index dcbce6c172..142573929a 100644
--- a/vm.c
+++ b/vm.c
@@ -2203,15 +2203,6 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
/* 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)
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)
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_execution_context_t *ec)
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;
diff --git a/vm_args.c b/vm_args.c
index e9a1a8c580..932c3b75b5 100644
--- a/vm_args.c
+++ b/vm_args.c
@@ -36,7 +36,7 @@ enum arg_setup_type {
static inline void
arg_rest_dup(struct args_info *args)
{
- if (!args->rest_dupped) {
+ if(!args->rest_dupped) {
args->rest = rb_ary_dup(args->rest);
args->rest_dupped = TRUE;
}
diff --git a/vm_core.h b/vm_core.h
index 2e8ddfe37f..d0d4d72c3d 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -346,7 +346,7 @@ struct rb_iseq_constant_body {
} 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 {
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 {
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 {
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;
diff --git a/vm_eval.c b/vm_eval.c
index fc271415a6..f05621e2b4 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -484,7 +484,6 @@ rb_type_str(enum ruby_value_type type)
case type_case(T_NODE);
case type_case(T_ICLASS);
case type_case(T_ZOMBIE);
- case type_case(T_MOVED);
case T_MASK: break;
}
#undef type_case
diff --git a/vm_method.c b/vm_method.c
index 672fac0462..c5ca644230 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -670,8 +670,13 @@ rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_
MJIT_FUNC_EXPORTED void
rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
{
- rb_method_iseq_t iseq_body = {(rb_iseq_t *)iseq, cref};
+ struct { /* should be same fields with rb_method_iseq_struct */
+ const rb_iseq_t *iseqptr;
+ rb_cref_t *cref;
+ } iseq_body;
+ iseq_body.iseqptr = iseq;
+ iseq_body.cref = cref;
rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi);
}