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

Reply via email to