Ticket #362 (closed todo: done)
optimize freeze_size
| Reported by: | rurban | Owned by: | plobsing |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | core | Version: | |
| Severity: | medium | Keywords: | |
| Cc: | Language: | ||
| Patch status: | Platform: |
Description
Currently creating a pbc involves freeze malloc/free for every registered pmc, just to calculate the size of the pmc, just to help PackFile_Constant_pack_size()
"Determines the size of the buffer needed in order to pack the PackFile Constant into a contiguous region of memory."
The action VISIT_FREEZE_SIZE was invented a long time ago, but never implemented.
I've added a Parrot_freeze_size() function, which should use VISIT_FREEZE_SIZE.
Only the packfile API has _packed_size methods, the pmc's not yet.
Cooperative pmc's can also implement this action by returning the simulated size without actual amlloc, others still do the malloc/free, and Parrot_freeze_size will count the strlen then.
We might need a fallback scenario for old pmc's (e.g. languages) which did not implement this interface.
And a more general architectural comment:
We have no pmc registration interface which handles the available methods between the clients and core,
- to be able to handle missing methods in core,
- or use proxies for missing methods in older or newer packfiles.
A cross-version compatible packfile solution would need that.
e.g. we have only (void)info->visit_action and not (int)info->visit_action to be able to fallback to the parent.
case VISIT_FREEZE_NORMAL:
freeze_pmc(interp, pmc, info, seen, id);
if (pmc)
info->visit_action = pmc->vtable->freeze;
break;
case VISIT_FREEZE_SIZE: /* do not actually freeze */
if (pmc && have_pmc(interp, pmc, "freeze_size", seen, id))
info->visit_action = pmc->vtable->freeze_size;
else {
freeze_pmc(interp, pmc, info, seen, id);
if (pmc)
info->visit_action = pmc->vtable->freeze;
}
break;
