vm: deallocate old PIC after allocating the new one to avoid having the code heap potentially point to a free block during compaction

db4
Slava Pestov 2009-11-24 21:20:23 -06:00
parent bfd4cce364
commit b09d6ef586
2 changed files with 9 additions and 12 deletions

View File

@ -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);

View File

@ -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
} }