Bug #9584 ยป rgengc-bitmap-promoted-wip.diff
.gdbinit | ||
---|---|---|
end
|
||
else
|
||
set $flags = ((struct RBasic*)($arg0))->flags
|
||
if ($flags & RUBY_FL_PROMOTED)
|
||
printf "[PROMOTED] "
|
||
end
|
||
if ($flags & RUBY_T_MASK) == RUBY_T_NONE
|
||
printf "%sT_NONE%s: ", $color_type, $color_end
|
||
print (struct RBasic *)($arg0)
|
debug.c | ||
---|---|---|
RUBY_ENC_CODERANGE_VALID = ENC_CODERANGE_VALID,
|
||
RUBY_ENC_CODERANGE_BROKEN = ENC_CODERANGE_BROKEN,
|
||
RUBY_FL_WB_PROTECTED = FL_WB_PROTECTED,
|
||
RUBY_FL_PROMOTED = FL_PROMOTED,
|
||
RUBY_FL_FINALIZE = FL_FINALIZE,
|
||
RUBY_FL_TAINT = FL_TAINT,
|
||
RUBY_FL_EXIVAR = FL_EXIVAR,
|
gc.c | ||
---|---|---|
#if USE_RGENGC
|
||
bits_t rememberset_bits[HEAP_BITMAP_LIMIT];
|
||
bits_t oldgen_bits[HEAP_BITMAP_LIMIT];
|
||
bits_t promoted_bits[HEAP_BITMAP_LIMIT];
|
||
#endif
|
||
};
|
||
... | ... | |
#define GET_HEAP_MARK_BITS(x) (&GET_HEAP_PAGE(x)->mark_bits[0])
|
||
#define GET_HEAP_REMEMBERSET_BITS(x) (&GET_HEAP_PAGE(x)->rememberset_bits[0])
|
||
#define GET_HEAP_OLDGEN_BITS(x) (&GET_HEAP_PAGE(x)->oldgen_bits[0])
|
||
#define GET_HEAP_PROMOTED_BITS(x) (&GET_HEAP_PAGE(x)->promoted_bits[0])
|
||
#define NUM_IN_PAGE(p) (((bits_t)(p) & HEAP_ALIGN_MASK)/sizeof(RVALUE))
|
||
#define BITMAP_INDEX(p) (NUM_IN_PAGE(p) / BITS_BITLENGTH )
|
||
#define BITMAP_OFFSET(p) (NUM_IN_PAGE(p) & (BITS_BITLENGTH-1))
|
||
... | ... | |
static inline int is_pointer_to_heap(rb_objspace_t *objspace, void *ptr);
|
||
static inline int gc_marked(rb_objspace_t *objspace, VALUE ptr);
|
||
static inline int
|
||
rb_promoted_test(VALUE obj)
|
||
{
|
||
return MARKED_IN_BITMAP(GET_HEAP_PROMOTED_BITS(obj), obj);
|
||
}
|
||
int
|
||
rb_promoted_p_internal(VALUE obj)
|
||
{
|
||
if (is_pointer_to_heap(&rb_objspace, (void *)obj)) {
|
||
return rb_promoted_test(obj);
|
||
}
|
||
return 1;
|
||
}
|
||
static inline void
|
||
rb_promoted_set(VALUE obj)
|
||
{
|
||
MARK_IN_BITMAP(GET_HEAP_PROMOTED_BITS(obj), obj);
|
||
}
|
||
static inline void
|
||
rb_promoted_clear(VALUE obj)
|
||
{
|
||
CLEAR_IN_BITMAP(GET_HEAP_PROMOTED_BITS(obj), obj);
|
||
}
|
||
static inline int
|
||
rb_promoted_test_checked(VALUE obj)
|
||
{
|
||
if (RGENGC_CHECK_MODE && SPECIAL_CONST_P(obj))
|
||
rb_bug("rb_promoted_test_checked: SPECIAL_CONST");
|
||
return rb_promoted_test(obj);
|
||
}
|
||
static inline void
|
||
rb_promoted_set_checked(VALUE obj)
|
||
{
|
||
if (RGENGC_CHECK_MODE && SPECIAL_CONST_P(obj))
|
||
rb_bug("rb_promoted_set_checked: SPECIAL_CONST");
|
||
rb_promoted_set(obj);
|
||
}
|
||
static inline void
|
||
rb_promoted_clear_checked(VALUE obj)
|
||
{
|
||
if (RGENGC_CHECK_MODE && SPECIAL_CONST_P(obj))
|
||
rb_bug("rb_promoted_clear_checked: SPECIAL_CONST");
|
||
rb_promoted_clear(obj);
|
||
}
|
||
static inline VALUE
|
||
check_gen_consistency(VALUE obj)
|
||
{
|
||
if (RGENGC_CHECK_MODE > 0) {
|
||
int old_flag = RVALUE_OLDGEN_BITMAP(obj) != 0;
|
||
int promoted_flag = FL_TEST2(obj, FL_PROMOTED);
|
||
int promoted_flag = rb_promoted_test_checked(obj);
|
||
rb_objspace_t *objspace = &rb_objspace;
|
||
obj_memsize_of((VALUE)obj, FALSE);
|
||
... | ... | |
RVALUE_INFANT_P(VALUE obj)
|
||
{
|
||
check_gen_consistency(obj);
|
||
return !FL_TEST2(obj, FL_PROMOTED);
|
||
return !rb_promoted_test_checked(obj);
|
||
}
|
||
static inline VALUE
|
||
... | ... | |
{
|
||
check_gen_consistency(obj);
|
||
#if RGENGC_THREEGEN
|
||
return FL_TEST2(obj, FL_PROMOTED) && RVALUE_OLD_BITMAP_P(obj);
|
||
return rb_promoted_test_checked(obj) && RVALUE_OLD_BITMAP_P(obj);
|
||
#else
|
||
return FL_TEST2(obj, FL_PROMOTED);
|
||
return rb_promoted_test_checked(obj);
|
||
#endif
|
||
}
|
||
... | ... | |
RVALUE_PROMOTED_P(VALUE obj)
|
||
{
|
||
check_gen_consistency(obj);
|
||
return FL_TEST2(obj, FL_PROMOTED);
|
||
return rb_promoted_test_checked(obj);
|
||
}
|
||
static inline void
|
||
... | ... | |
{
|
||
check_gen_consistency(obj);
|
||
if (RGENGC_CHECK_MODE && !RVALUE_INFANT_P(obj)) rb_bug("RVALUE_PROMOTE_INFANT: %p (%s) is not infant object.", (void *)obj, obj_type_name(obj));
|
||
FL_SET2(obj, FL_PROMOTED);
|
||
rb_promoted_set_checked(obj);
|
||
#if !RGENGC_THREEGEN
|
||
MARK_IN_BITMAP(GET_HEAP_OLDGEN_BITS(obj), obj);
|
||
#endif
|
||
... | ... | |
RVALUE_YOUNG_P(VALUE obj)
|
||
{
|
||
check_gen_consistency(obj);
|
||
return FL_TEST2(obj, FL_PROMOTED) && (RVALUE_OLDGEN_BITMAP(obj) == 0);
|
||
return rb_promoted_test_checked(obj) && (RVALUE_OLDGEN_BITMAP(obj) == 0);
|
||
}
|
||
static inline void
|
||
... | ... | |
rb_bug("RVALUE_DEMOTE_FROM_YOUNG: %p (%s) is not young object.", (void *)obj, obj_type_name(obj));
|
||
check_gen_consistency(obj);
|
||
FL_UNSET2(obj, FL_PROMOTED);
|
||
rb_promoted_clear_checked(obj);
|
||
check_gen_consistency(obj);
|
||
}
|
||
#endif
|
||
... | ... | |
rb_bug("RVALUE_DEMOTE_FROM_OLD: %p (%s) is not old object.", (void *)obj, obj_type_name(obj));
|
||
check_gen_consistency(obj);
|
||
FL_UNSET2(obj, FL_PROMOTED);
|
||
rb_promoted_clear_checked(obj);
|
||
CLEAR_IN_BITMAP(GET_HEAP_OLDGEN_BITS(obj), obj);
|
||
check_gen_consistency(obj);
|
||
}
|
include/ruby/ruby.h | ||
---|---|---|
#define FL_SINGLETON FL_USER0
|
||
#define FL_WB_PROTECTED (((VALUE)1)<<5)
|
||
#define FL_PROMOTED (((VALUE)1)<<6)
|
||
#define FL_PERMANENT (((VALUE)1)<<6)
|
||
#define FL_FINALIZE (((VALUE)1)<<7)
|
||
#define FL_TAINT (((VALUE)1)<<8)
|
||
#define FL_UNTRUSTED FL_TAINT
|
||
... | ... | |
#define OBJ_FROZEN(x) (!!(FL_ABLE(x)?(RBASIC(x)->flags&(FL_FREEZE)):(FIXNUM_P(x)||FLONUM_P(x)||SYMBOL_P(x))))
|
||
#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
|
||
#define OBJ_PERMANENT(x) (!!FL_TEST((x), FL_PERMANENT))
|
||
#if USE_RGENGC
|
||
#define OBJ_PROMOTED(x) (SPECIAL_CONST_P(x) ? 0 : FL_TEST_RAW((x), FL_PROMOTED))
|
||
int rb_promoted_p_internal(VALUE); /* should be internal, do not use directly */
|
||
static inline int
|
||
rb_promoted_p(VALUE obj)
|
||
{
|
||
/* if (OBJ_PERMANENT(obj)) return 0; */
|
||
return rb_promoted_p_internal(obj);
|
||
}
|
||
#define OBJ_PROMOTED(x) (SPECIAL_CONST_P(x) ? 0 : rb_promoted_p((x)))
|
||
#define OBJ_WB_PROTECTED(x) (SPECIAL_CONST_P(x) ? 1 : FL_TEST_RAW((x), FL_WB_PROTECTED))
|
||
#define OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)
|
||
... | ... | |
#if USE_RGENGC
|
||
/* `x' should be an RVALUE object */
|
||
if (FL_TEST_RAW((x), FL_WB_PROTECTED)) {
|
||
if (FL_TEST_RAW((x), FL_PROMOTED)) {
|
||
if (rb_promoted_p(x)) {
|
||
rb_gc_writebarrier_unprotect_promoted(x);
|
||
}
|
||
RBASIC(x)->flags &= ~FL_WB_PROTECTED;
|
||
... | ... | |
#if USE_RGENGC
|
||
/* `a' should be an RVALUE object */
|
||
if (FL_TEST_RAW((a), FL_PROMOTED) && !SPECIAL_CONST_P(b)) {
|
||
if (rb_promoted_p(a) && !SPECIAL_CONST_P(b)) {
|
||
rb_gc_writebarrier(a, b);
|
||
}
|
||
#endif
|
load.c | ||
---|---|---|
feature_indexes[0] = this_feature_index;
|
||
feature_indexes[1] = offset;
|
||
this_feature_index = (VALUE)xcalloc(1, sizeof(struct RArray));
|
||
RBASIC(this_feature_index)->flags = T_ARRAY; /* fake VALUE, do not mark/sweep */
|
||
/* fake VALUE, do not mark/sweep */
|
||
RBASIC(this_feature_index)->flags = T_ARRAY | FL_PERMANENT;
|
||
rb_ary_cat(this_feature_index, feature_indexes, numberof(feature_indexes));
|
||
st_insert(features_index, (st_data_t)short_feature_cstr, (st_data_t)this_feature_index);
|
||
}
|
object.c | ||
---|---|---|
rb_raise(rb_eTypeError, "can't clone %s", rb_obj_classname(obj));
|
||
}
|
||
clone = rb_obj_alloc(rb_obj_class(obj));
|
||
RBASIC(clone)->flags &= (FL_TAINT|FL_PROMOTED|FL_WB_PROTECTED);
|
||
RBASIC(clone)->flags |= RBASIC(obj)->flags & ~(FL_PROMOTED|FL_FREEZE|FL_FINALIZE|FL_WB_PROTECTED);
|
||
RBASIC(clone)->flags &= (FL_TAINT|FL_WB_PROTECTED);
|
||
RBASIC(clone)->flags |= RBASIC(obj)->flags & ~(FL_FREEZE|FL_FINALIZE|FL_WB_PROTECTED);
|
||
singleton = rb_singleton_class_clone_and_attach(obj, clone);
|
||
RBASIC_SET_CLASS(clone, singleton);
|
parse.y | ||
---|---|---|
static VALUE
|
||
setup_fake_str(struct RString *fake_str, const char *name, long len)
|
||
{
|
||
fake_str->basic.flags = T_STRING|RSTRING_NOEMBED;
|
||
fake_str->basic.flags = T_STRING|RSTRING_NOEMBED|FL_PERMANENT;
|
||
RBASIC_SET_CLASS((VALUE)fake_str, rb_cString);
|
||
fake_str->as.heap.len = len;
|
||
fake_str->as.heap.ptr = (char *)name;
|