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
