Pinned objects fall into two categories.  First, all arguments passed
via P/Invoke (also called NDirect) are implicitly pinned.  Second,
objects can be explicitly allocated as pinned via the managed
System.Runtime.InteropServices.GCHandle.Alloc(Object, GCHandleType)
method, which adds entries to the objecthandle table.  In both cases,
pinning doesn't incur runtime overhead until the GC runs, and the GC
isn't involved with pinning until GCHeap::Promote() is called, with
GC_CALL_PINNED set in its 'flags' parameter.


In the case of P/Invoke, this is the sequence of events as the stack is
being crawled during a GC and an NDirectMethodFrame is encountered:
  gcscan.cpp's GcStackCrawlCallback() calls a pFrame->GcScanRoots.  For
P/Invoke, pFrame is an NDirectMethodFrame.
  frames.h's NDirectMethodFrame::GcScanRoots() calls
  frames.h's FrameMethodFrame::PromoteCallerStackWithPinning() calls
  frames.cpp's FramedMethodFrame::PromoteCallerStackWorker() calls
  frames.cpp's FrameMethodFrame::PromoteCallerStackHelper() takes an
fPinArgs parameter which is TRUE in this code path.  For each object
pointer in a jitted method's stack frame, it calls GCHeap::Promote(...,
GC_CALL_PINNED)


In the case of objecthandle table, the table itself contains a separate
list of handles corresponding to pinned objects:  the
_TableSegmentHeader in handletablepriv.h has an rgTail[] array of
pointers to allocated objects, indexed by HNDTYPE_*, so
_TableSegmentHeader.rgTail[HNDTYPE_PINNED] is the head of the list of
pinned objects.  Here is the sequence of events:

  gcscan.cpp's CNameSpace::GcScanHandles() calls
  objecthandle.cpp's Ref_TracePinningRoots().  For each handle in each
handle table, it calls
  handletable.cpp's HndScanHandlesForGC(..., HNDTYPE_PINNED, ...).  It
calls
  handletablescan.cpp's TableScanHandles().  It calls 
  handletablescan.cpp's SegmentScanByTypeChain(), which scans the
segment starting at pSegment->rgTail[HNDTYPE_PINNED], which contains the
list of all pinned objects pointed to by the segment.  For each of
those, it calls objecthandle.cpp's PinObject(), which calls
GCHeap::Promote(..., GC_CALL_PINNED)


These two call stacks were derived by examining all references to
GC_CALL_PINNED in the source tree and working backwards.

Barry

This posting is provided "AS IS" with no warranties, and confers no
rights.

-----Original Message-----
From: Archana [mailto:[EMAIL PROTECTED]] 
Sent: Monday, January 20, 2003 3:46 AM
To: [EMAIL PROTECTED]
Subject: [DOTNET-ROTOR] implementation of pinning objects


Hi,
 How is Pinning implemented in rotor? Does rotor treat the attribute
pinned as a separate type? what is the relation between pinned objects
and the objecthandle table? would be of immense help if someone could
explain these points.

thank you,
archana

Reply via email to