mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
sync check_rvalue_consistency_force()
check_rvalue_consistency_force() uses is_pointer_to_heap() and it should be synchronized with other ractors. [Bug #17636]
This commit is contained in:
parent
100e464bee
commit
07ab172ebe
Notes:
git
2021-02-18 17:05:20 +09:00
1 changed files with 78 additions and 75 deletions
153
gc.c
153
gc.c
|
@ -1241,99 +1241,102 @@ RVALUE_FLAGS_AGE(VALUE flags)
|
|||
static int
|
||||
check_rvalue_consistency_force(const VALUE obj, int terminate)
|
||||
{
|
||||
rb_objspace_t *objspace = &rb_objspace;
|
||||
int err = 0;
|
||||
rb_objspace_t *objspace = &rb_objspace;
|
||||
|
||||
if (SPECIAL_CONST_P(obj)) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %p is a special const.\n", (void *)obj);
|
||||
err++;
|
||||
}
|
||||
else if (!is_pointer_to_heap(objspace, (void *)obj)) {
|
||||
/* check if it is in tomb_pages */
|
||||
struct heap_page *page = NULL;
|
||||
list_for_each(&heap_tomb->pages, page, page_node) {
|
||||
if (&page->start[0] <= (RVALUE *)obj &&
|
||||
(RVALUE *)obj < &page->start[page->total_slots]) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %p is in a tomb_heap (%p).\n",
|
||||
(void *)obj, (void *)page);
|
||||
err++;
|
||||
goto skip;
|
||||
RB_VM_LOCK_ENTER_NO_BARRIER();
|
||||
{
|
||||
if (SPECIAL_CONST_P(obj)) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %p is a special const.\n", (void *)obj);
|
||||
err++;
|
||||
}
|
||||
else if (!is_pointer_to_heap(objspace, (void *)obj)) {
|
||||
/* check if it is in tomb_pages */
|
||||
struct heap_page *page = NULL;
|
||||
list_for_each(&heap_tomb->pages, page, page_node) {
|
||||
if (&page->start[0] <= (RVALUE *)obj &&
|
||||
(RVALUE *)obj < &page->start[page->total_slots]) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %p is in a tomb_heap (%p).\n",
|
||||
(void *)obj, (void *)page);
|
||||
err++;
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
bp();
|
||||
fprintf(stderr, "check_rvalue_consistency: %p is not a Ruby object.\n", (void *)obj);
|
||||
err++;
|
||||
skip:
|
||||
;
|
||||
}
|
||||
else {
|
||||
const int wb_unprotected_bit = RVALUE_WB_UNPROTECTED_BITMAP(obj) != 0;
|
||||
const int uncollectible_bit = RVALUE_UNCOLLECTIBLE_BITMAP(obj) != 0;
|
||||
const int mark_bit = RVALUE_MARK_BITMAP(obj) != 0;
|
||||
const int marking_bit = RVALUE_MARKING_BITMAP(obj) != 0, remembered_bit = marking_bit;
|
||||
const int age = RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
|
||||
|
||||
if (GET_HEAP_PAGE(obj)->flags.in_tomb) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is in tomb page.\n", obj_info(obj));
|
||||
err++;
|
||||
}
|
||||
if (BUILTIN_TYPE(obj) == T_NONE) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is T_NONE.\n", obj_info(obj));
|
||||
err++;
|
||||
}
|
||||
if (BUILTIN_TYPE(obj) == T_ZOMBIE) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is T_ZOMBIE.\n", obj_info(obj));
|
||||
bp();
|
||||
fprintf(stderr, "check_rvalue_consistency: %p is not a Ruby object.\n", (void *)obj);
|
||||
err++;
|
||||
skip:
|
||||
;
|
||||
}
|
||||
else {
|
||||
const int wb_unprotected_bit = RVALUE_WB_UNPROTECTED_BITMAP(obj) != 0;
|
||||
const int uncollectible_bit = RVALUE_UNCOLLECTIBLE_BITMAP(obj) != 0;
|
||||
const int mark_bit = RVALUE_MARK_BITMAP(obj) != 0;
|
||||
const int marking_bit = RVALUE_MARKING_BITMAP(obj) != 0, remembered_bit = marking_bit;
|
||||
const int age = RVALUE_FLAGS_AGE(RBASIC(obj)->flags);
|
||||
|
||||
obj_memsize_of((VALUE)obj, FALSE);
|
||||
|
||||
/* check generation
|
||||
*
|
||||
* OLD == age == 3 && old-bitmap && mark-bit (except incremental marking)
|
||||
*/
|
||||
if (age > 0 && wb_unprotected_bit) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is not WB protected, but age is %d > 0.\n", obj_info(obj), age);
|
||||
err++;
|
||||
}
|
||||
|
||||
if (!is_marking(objspace) && uncollectible_bit && !mark_bit) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is uncollectible, but is not marked while !gc.\n", obj_info(obj));
|
||||
err++;
|
||||
}
|
||||
|
||||
if (!is_full_marking(objspace)) {
|
||||
if (uncollectible_bit && age != RVALUE_OLD_AGE && !wb_unprotected_bit) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is uncollectible, but not old (age: %d) and not WB unprotected.\n",
|
||||
obj_info(obj), age);
|
||||
if (GET_HEAP_PAGE(obj)->flags.in_tomb) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is in tomb page.\n", obj_info(obj));
|
||||
err++;
|
||||
}
|
||||
if (remembered_bit && age != RVALUE_OLD_AGE) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is remembered, but not old (age: %d).\n",
|
||||
obj_info(obj), age);
|
||||
if (BUILTIN_TYPE(obj) == T_NONE) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is T_NONE.\n", obj_info(obj));
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check coloring
|
||||
*
|
||||
* marking:false marking:true
|
||||
* marked:false white *invalid*
|
||||
* marked:true black grey
|
||||
*/
|
||||
if (is_incremental_marking(objspace) && marking_bit) {
|
||||
if (!is_marking(objspace) && !mark_bit) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is marking, but not marked.\n", obj_info(obj));
|
||||
if (BUILTIN_TYPE(obj) == T_ZOMBIE) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is T_ZOMBIE.\n", obj_info(obj));
|
||||
err++;
|
||||
}
|
||||
|
||||
obj_memsize_of((VALUE)obj, FALSE);
|
||||
|
||||
/* check generation
|
||||
*
|
||||
* OLD == age == 3 && old-bitmap && mark-bit (except incremental marking)
|
||||
*/
|
||||
if (age > 0 && wb_unprotected_bit) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is not WB protected, but age is %d > 0.\n", obj_info(obj), age);
|
||||
err++;
|
||||
}
|
||||
|
||||
if (!is_marking(objspace) && uncollectible_bit && !mark_bit) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is uncollectible, but is not marked while !gc.\n", obj_info(obj));
|
||||
err++;
|
||||
}
|
||||
|
||||
if (!is_full_marking(objspace)) {
|
||||
if (uncollectible_bit && age != RVALUE_OLD_AGE && !wb_unprotected_bit) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is uncollectible, but not old (age: %d) and not WB unprotected.\n",
|
||||
obj_info(obj), age);
|
||||
err++;
|
||||
}
|
||||
if (remembered_bit && age != RVALUE_OLD_AGE) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is remembered, but not old (age: %d).\n",
|
||||
obj_info(obj), age);
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check coloring
|
||||
*
|
||||
* marking:false marking:true
|
||||
* marked:false white *invalid*
|
||||
* marked:true black grey
|
||||
*/
|
||||
if (is_incremental_marking(objspace) && marking_bit) {
|
||||
if (!is_marking(objspace) && !mark_bit) {
|
||||
fprintf(stderr, "check_rvalue_consistency: %s is marking, but not marked.\n", obj_info(obj));
|
||||
err++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RB_VM_LOCK_LEAVE_NO_BARRIER();
|
||||
|
||||
if (err > 0 && terminate) {
|
||||
rb_bug("check_rvalue_consistency_force: there is %d errors.", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue