зеркало из https://github.com/github/ruby.git
check liveness of cc->klass and cc->cme_
`cc->klass` and `cc->cme_` can be free'ed while last marking so that it should be checked bofore updating the pointers. Note that `T_MOVED` is living, but `is_live_object()` returns false.
This commit is contained in:
Родитель
b0f44cfa5d
Коммит
7a7aba755d
22
gc.c
22
gc.c
|
@ -10128,16 +10128,20 @@ gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj)
|
|||
case imemo_callcache:
|
||||
{
|
||||
const struct rb_callcache *cc = (const struct rb_callcache *)obj;
|
||||
if (cc->klass) {
|
||||
UPDATE_IF_MOVED(objspace, cc->klass);
|
||||
if (!is_live_object(objspace, cc->klass)) {
|
||||
vm_cc_invalidate(cc);
|
||||
}
|
||||
else if (cc->cme_) { // cc->cme_ is available if cc->klass is given
|
||||
|
||||
if (!cc->klass) {
|
||||
// already invalidated
|
||||
}
|
||||
else {
|
||||
if ( // cc->klass is living
|
||||
(BUILTIN_TYPE(cc->klass) == T_MOVED || is_live_object(objspace, cc->klass)) &&
|
||||
// cc->cme_ is living
|
||||
(cc->cme_ && ((BUILTIN_TYPE((VALUE)cc->cme_) == T_MOVED) || is_live_object(objspace, (VALUE)cc->cme_)))) {
|
||||
UPDATE_IF_MOVED(objspace, cc->klass);
|
||||
TYPED_UPDATE_IF_MOVED(objspace, struct rb_callable_method_entry_struct *, cc->cme_);
|
||||
if (!is_live_object(objspace, (VALUE)cc->cme_)) {
|
||||
vm_cc_invalidate(cc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
vm_cc_invalidate(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче