On Tuesday 13 November 2001 06:37 pm, James Mastros wrote: > On Tue, Nov 13, 2001 at 06:14:30PM -0500, Michael L Maraist wrote: > > Extending mem-mngr data-structures (like the linked-list) to the > > definition of a PMC is what I'm worried about; not exposing a function to > > say GC-me-more-often. (I appologize for the LISP mneumonic :) > > Hm. I think that the problem is that the definition of a PMC is, I think, > what we say it is in perlpmc.pod, and not what we say it is in pmc.h. > > This means that we need to recomple XSes to change PMCs, but I think that's > possibly OK. If not, why do we need to keep the linked-list inside the > PMCs, instead of sepperatly?
Again, this is only speculation about possible algorithms. The only reason to expose linked-list structures is if a collection algorithm was used that assumed it contained a list of ALL PMCs. If the newPMC() / newPMCext() were exclusively used, then this isn't a problem, but if PMC's could be externally allocated and then registered within "foreign access", then there'd potentially be a data-type mismatch. Namely using header = (gc_object_header*)((int*)pmc_ptr - 2 ) header->next =... header->prev=... would be a failed assumption. I'm in favor of requiring newXX() since this is more portable between memory managers. It's equivalent to assuming that you could determine the size of a malloc'd object by doing: *((int*)ptr - 1) simply because your current mem-mngr stores the value there. Obviously it's best to pass the pointer to the associated mem-mngr API and let it do things like fetching size. Here the potential problem is static allocations generated by XS-code. In theory our API would allow: // desirable API functions PMC_t* newPMC(); // assumes it'll be attached to the root-set PMC_t* newPMCext(); // auto-ataches to "foreign access" portion of root-set. void PL_registerForeignAccess(PMC_t*); // questionable API function void PL_unregisterForeignAccess(PMC_t*); void PL_initPMC(PMC_t*); And an XS coder could have: void fooExtension(..) { PMC_t my_pmc; PL_initPMC( &my_pmc ); PL_registerForeignAccess( &my_pmc ); ... // my_pmc falls out of scope. // coder forgot to call PL_unregisterFA( &my_pmc ); memory leak.. } How PL_registerFA works isn't yet determined. If newPMCext() called PL_regFA(), then there'd have to be some additional data-structure or allocated memory. But if newPMCext() simply used the GC-exclusive region of the linked-list, then the PMC could be placed on the appropriate list, and thus avoid additional flags or memory allocations. It's state / type is implicit based on the associated list as far as GCing is concerned. It's just that this doesn't work with the above code.. The GC-hidden data-structure could also have a ref-count of the number of times it's been marked with PL_regFA, that way an intial reg-stack PMC could be grabbed by XS-code and cached for what-ever evil purposes safely. Thus my current idea of PMC handles is: struct gc_handle_header_t { struct gc_handle_header_t *prev, *next; int fa_cnt; char data[0]; // gcc-specific code for demonstration purposes }; Again, this is just the weeding out stage. -Michael