With this patch, the LowerGC transformation becomes the

ShadowStackCollector, which additionally has reduced overhead with
no sacrifice in portability.

Considering a function @fun with 8 loop-local roots,
ShadowStackCollector introduces the following overhead
(x86):

; shadowstack prologue
        movl    L_llvm_gc_root_chain$non_lazy_ptr, %eax
        movl    (%eax), %ecx
        movl    $___gc_fun, 20(%esp)
        movl    $0, 24(%esp)
        movl    $0, 28(%esp)
        movl    $0, 32(%esp)
        movl    $0, 36(%esp)
        movl    $0, 40(%esp)
        movl    $0, 44(%esp)
        movl    $0, 48(%esp)
        movl    $0, 52(%esp)
        movl    %ecx, 16(%esp)
        leal    16(%esp), %ecx
        movl    %ecx, (%eax)

; shadowstack loop overhead
        (none)

; shadowstack epilogue
        movl    48(%esp), %edx
        movl    %edx, (%ecx)

; shadowstack metadata
        .align  3
___gc_fun:                              # __gc_fun
        .long   8
        .space  4

In comparison to LowerGC:

; lowergc prologue
        movl    L_llvm_gc_root_chain$non_lazy_ptr, %eax
        movl    (%eax), %ecx
        movl    %ecx, 48(%esp)
        movl    $8, 52(%esp)
        movl    $0, 60(%esp)
        movl    $0, 56(%esp)
        movl    $0, 68(%esp)
        movl    $0, 64(%esp)
        movl    $0, 76(%esp)
        movl    $0, 72(%esp)
        movl    $0, 84(%esp)
        movl    $0, 80(%esp)
        movl    $0, 92(%esp)
        movl    $0, 88(%esp)
        movl    $0, 100(%esp)
        movl    $0, 96(%esp)
        movl    $0, 108(%esp)
        movl    $0, 104(%esp)
        movl    $0, 116(%esp)
        movl    $0, 112(%esp)

; lowergc loop overhead
        leal    44(%esp), %eax
        movl    %eax, 56(%esp)
        leal    40(%esp), %eax
        movl    %eax, 64(%esp)
        leal    36(%esp), %eax
        movl    %eax, 72(%esp)
        leal    32(%esp), %eax
        movl    %eax, 80(%esp)
        leal    28(%esp), %eax
        movl    %eax, 88(%esp)
        leal    24(%esp), %eax
        movl    %eax, 96(%esp)
        leal    20(%esp), %eax
        movl    %eax, 104(%esp)
        leal    16(%esp), %eax
        movl    %eax, 112(%esp)

; lowergc epilogue
        movl    48(%esp), %edx
        movl    %edx, (%ecx)

; lowergc metadata
        (none)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45670 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Gordon Henriksen
2008-01-07 01:30:53 +00:00
parent ce2247755e
commit 8fa8929177
7 changed files with 477 additions and 372 deletions

View File

@@ -97,24 +97,26 @@ void llvm_gc_write(void *V, void *ObjPtr, void **FieldPtr) { *FieldPtr = V; }
* FIXME: This should be in a code-generator specific library, but for now this
* will work for all code generators.
*/
typedef struct GCRoot {
void **RootPtr;
void *Meta;
} GCRoot;
struct FrameMap {
int32_t NumRoots; // Number of roots in stack frame.
int32_t NumMeta; // Number of metadata descriptors. May be < NumRoots.
void *Meta[]; // May be absent for roots without metadata.
};
typedef struct GCRoots {
struct GCRoots *Next;
unsigned NumRoots;
GCRoot RootRecords[];
} GCRoots;
GCRoots *llvm_gc_root_chain;
struct StackEntry {
ShadowStackEntry *Next; // Caller's stack entry.
const FrameMap *Map; // Pointer to constant FrameMap.
void *Roots[]; // Stack roots (in-place array).
};
StackEntry *llvm_gc_root_chain;
void llvm_cg_walk_gcroots(void (*FP)(void **Root, void *Meta)) {
GCRoots *R = llvm_gc_root_chain;
for (; R; R = R->Next) {
for (StackEntry *R; R; R = R->Next) {
unsigned i, e;
for (i = 0, e = R->NumRoots; i != e; ++i)
FP(R->RootRecords[i].RootPtr, R->RootRecords[i].Meta);
for (i = 0, e = R->NumMeta; i != e; ++i)
FP(&R->Roots[i], R->Map->Meta[i]);
for (e = R->NumRoots; i != e; ++i)
FP(&R->Roots[i], NULL);
}
}
/* END FIXME! */