vm: deallocate old PIC after allocating the new one to avoid having the code heap potentially point to a free block during compaction
parent
bfd4cce364
commit
b09d6ef586
|
@ -79,10 +79,8 @@ void *factor_vm::get_rel_symbol(array *literals, cell index)
|
||||||
if(sym)
|
if(sym)
|
||||||
return sym;
|
return sym;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return (void *)factor::undefined_symbol;
|
return (void *)factor::undefined_symbol;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
case ARRAY_TYPE:
|
case ARRAY_TYPE:
|
||||||
{
|
{
|
||||||
array *names = untag<array>(symbol);
|
array *names = untag<array>(symbol);
|
||||||
|
|
|
@ -183,23 +183,18 @@ void *factor_vm::inline_cache_miss(cell return_address_)
|
||||||
|
|
||||||
check_code_pointer(return_address.value);
|
check_code_pointer(return_address.value);
|
||||||
|
|
||||||
/* Since each PIC is only referenced from a single call site,
|
|
||||||
if the old call target was a PIC, we can deallocate it immediately,
|
|
||||||
instead of leaving dead PICs around until the next GC. */
|
|
||||||
deallocate_inline_cache(return_address.value);
|
|
||||||
|
|
||||||
data_root<array> cache_entries(dpop(),this);
|
data_root<array> cache_entries(dpop(),this);
|
||||||
fixnum index = untag_fixnum(dpop());
|
fixnum index = untag_fixnum(dpop());
|
||||||
data_root<array> methods(dpop(),this);
|
data_root<array> methods(dpop(),this);
|
||||||
data_root<word> generic_word(dpop(),this);
|
data_root<word> generic_word(dpop(),this);
|
||||||
data_root<object> object(((cell *)ds)[-index],this);
|
data_root<object> object(((cell *)ds)[-index],this);
|
||||||
|
|
||||||
void *xt;
|
|
||||||
|
|
||||||
cell pic_size = inline_cache_size(cache_entries.value());
|
cell pic_size = inline_cache_size(cache_entries.value());
|
||||||
|
|
||||||
update_pic_transitions(pic_size);
|
update_pic_transitions(pic_size);
|
||||||
|
|
||||||
|
void *xt;
|
||||||
|
|
||||||
if(pic_size >= max_pic_size)
|
if(pic_size >= max_pic_size)
|
||||||
xt = megamorphic_call_stub(generic_word.value());
|
xt = megamorphic_call_stub(generic_word.value());
|
||||||
else
|
else
|
||||||
|
@ -221,13 +216,17 @@ void *factor_vm::inline_cache_miss(cell return_address_)
|
||||||
/* Install the new stub. */
|
/* Install the new stub. */
|
||||||
if(return_address.valid)
|
if(return_address.valid)
|
||||||
{
|
{
|
||||||
|
/* Since each PIC is only referenced from a single call site,
|
||||||
|
if the old call target was a PIC, we can deallocate it immediately,
|
||||||
|
instead of leaving dead PICs around until the next GC. */
|
||||||
|
deallocate_inline_cache(return_address.value);
|
||||||
set_call_target(return_address.value,xt);
|
set_call_target(return_address.value,xt);
|
||||||
|
|
||||||
#ifdef PIC_DEBUG
|
#ifdef PIC_DEBUG
|
||||||
std::cout << "Updated "
|
std::cout << "Updated "
|
||||||
<< (tail_call_site_p(return_address) ? "tail" : "non-tail")
|
<< (tail_call_site_p(return_address.value) ? "tail" : "non-tail")
|
||||||
<< " call site 0x" << std::hex << return_address << std::dec
|
<< " call site 0x" << std::hex << return_address.value << std::dec
|
||||||
<< " with " << std::hex << (cell)xt << std::dec;
|
<< " with " << std::hex << (cell)xt << std::dec << "\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue