nsprpub/pr/src/misc/prthinfo.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/nsprpub/pr/src/misc/prthinfo.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,206 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "prlog.h"
    1.10 +#include "prthread.h"
    1.11 +#include "private/pprthred.h"
    1.12 +#include "primpl.h"
    1.13 +
    1.14 +PR_IMPLEMENT(PRWord *)
    1.15 +PR_GetGCRegisters(PRThread *t, int isCurrent, int *np)
    1.16 +{
    1.17 +    return _MD_HomeGCRegisters(t, isCurrent, np);
    1.18 +}
    1.19 +
    1.20 +PR_IMPLEMENT(PRStatus)
    1.21 +PR_ThreadScanStackPointers(PRThread* t,
    1.22 +                           PRScanStackFun scanFun, void* scanClosure)
    1.23 +{
    1.24 +    PRThread* current = PR_GetCurrentThread();
    1.25 +    PRWord *sp, *esp, *p0;
    1.26 +    int n;
    1.27 +    void **ptd;
    1.28 +    PRStatus status;
    1.29 +    PRUint32 index;
    1.30 +    int stack_end;
    1.31 +
    1.32 +    /*
    1.33 +    ** Store the thread's registers in the thread structure so the GC
    1.34 +    ** can scan them. Then scan them.
    1.35 +    */
    1.36 +    p0 = _MD_HomeGCRegisters(t, t == current, &n);
    1.37 +    status = scanFun(t, (void**)p0, n, scanClosure);
    1.38 +    if (status != PR_SUCCESS)
    1.39 +        return status;
    1.40 +
    1.41 +    /* Scan the C stack for pointers into the GC heap */
    1.42 +#if defined(XP_PC) && defined(WIN16)
    1.43 +    /*
    1.44 +    ** Under WIN16, the stack of the current thread is always mapped into
    1.45 +    ** the "task stack" (at SS:xxxx).  So, if t is the current thread, scan
    1.46 +    ** the "task stack".  Otherwise, scan the "cached stack" of the inactive
    1.47 +    ** thread...
    1.48 +    */
    1.49 +    if (t == current) {
    1.50 +        sp  = (PRWord*) &stack_end;
    1.51 +        esp = (PRWord*) _pr_top_of_task_stack;
    1.52 +
    1.53 +        PR_ASSERT(sp <= esp);
    1.54 +    } else {
    1.55 +        sp  = (PRWord*) PR_GetSP(t);
    1.56 +        esp = (PRWord*) t->stack->stackTop;
    1.57 +
    1.58 +        PR_ASSERT((t->stack->stackSize == 0) ||
    1.59 +                  ((sp >  (PRWord*)t->stack->stackBottom) &&
    1.60 +                   (sp <= (PRWord*)t->stack->stackTop)));
    1.61 +    }
    1.62 +#else   /* ! WIN16 */
    1.63 +#ifdef HAVE_STACK_GROWING_UP
    1.64 +    if (t == current) {
    1.65 +        esp = (PRWord*) &stack_end;
    1.66 +    } else {
    1.67 +        esp = (PRWord*) PR_GetSP(t);
    1.68 +    }
    1.69 +    sp = (PRWord*) t->stack->stackTop;
    1.70 +    if (t->stack->stackSize) {
    1.71 +        PR_ASSERT((esp > (PRWord*)t->stack->stackTop) &&
    1.72 +                  (esp < (PRWord*)t->stack->stackBottom));
    1.73 +    }
    1.74 +#else   /* ! HAVE_STACK_GROWING_UP */
    1.75 +    if (t == current) {
    1.76 +        sp = (PRWord*) &stack_end;
    1.77 +    } else {
    1.78 +        sp = (PRWord*) PR_GetSP(t);
    1.79 +    }
    1.80 +    esp = (PRWord*) t->stack->stackTop;
    1.81 +    if (t->stack->stackSize) {
    1.82 +        PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) &&
    1.83 +                  (sp < (PRWord*)t->stack->stackTop));
    1.84 +    }
    1.85 +#endif  /* ! HAVE_STACK_GROWING_UP */
    1.86 +#endif  /* ! WIN16 */
    1.87 +
    1.88 +#if defined(WIN16)
    1.89 +    {
    1.90 +        prword_t scan;
    1.91 +        prword_t limit;
    1.92 +        
    1.93 +        scan = (prword_t) sp;
    1.94 +        limit = (prword_t) esp;
    1.95 +        while (scan < limit) {
    1.96 +            prword_t *test;
    1.97 +
    1.98 +            test = *((prword_t **)scan);
    1.99 +            status = scanFun(t, (void**)&test, 1, scanClosure);
   1.100 +            if (status != PR_SUCCESS)
   1.101 +                return status;
   1.102 +            scan += sizeof(char);
   1.103 +        }
   1.104 +    }
   1.105 +#else
   1.106 +    if (sp < esp) {
   1.107 +        status = scanFun(t, (void**)sp, esp - sp, scanClosure);
   1.108 +        if (status != PR_SUCCESS)
   1.109 +            return status;
   1.110 +    }
   1.111 +#endif
   1.112 +
   1.113 +    /*
   1.114 +    ** Mark all of the per-thread-data items attached to this thread
   1.115 +    **
   1.116 +    ** The execution environment better be accounted for otherwise it
   1.117 +    ** will be collected
   1.118 +    */
   1.119 +    status = scanFun(t, (void**)&t->environment, 1, scanClosure);
   1.120 +    if (status != PR_SUCCESS)
   1.121 +        return status;
   1.122 +
   1.123 +    /* if thread is not allocated on stack, this is redundant. */
   1.124 +    ptd = t->privateData;
   1.125 +    for (index = 0; index < t->tpdLength; index++, ptd++) {
   1.126 +        status = scanFun(t, (void**)ptd, 1, scanClosure);
   1.127 +        if (status != PR_SUCCESS)
   1.128 +            return status;
   1.129 +    }
   1.130 +    
   1.131 +    return PR_SUCCESS;
   1.132 +}
   1.133 +
   1.134 +/* transducer for PR_EnumerateThreads */
   1.135 +typedef struct PRScanStackData {
   1.136 +    PRScanStackFun      scanFun;
   1.137 +    void*               scanClosure;
   1.138 +} PRScanStackData;
   1.139 +
   1.140 +static PRStatus PR_CALLBACK
   1.141 +pr_ScanStack(PRThread* t, int i, void* arg)
   1.142 +{
   1.143 +    PRScanStackData* data = (PRScanStackData*)arg;
   1.144 +    return PR_ThreadScanStackPointers(t, data->scanFun, data->scanClosure);
   1.145 +}
   1.146 +
   1.147 +PR_IMPLEMENT(PRStatus)
   1.148 +PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure)
   1.149 +{
   1.150 +    PRScanStackData data;
   1.151 +    data.scanFun = scanFun;
   1.152 +    data.scanClosure = scanClosure;
   1.153 +    return PR_EnumerateThreads(pr_ScanStack, &data);
   1.154 +}
   1.155 +
   1.156 +PR_IMPLEMENT(PRUword)
   1.157 +PR_GetStackSpaceLeft(PRThread* t)
   1.158 +{
   1.159 +    PRThread *current = PR_GetCurrentThread();
   1.160 +    PRWord *sp, *esp;
   1.161 +    int stack_end;
   1.162 +
   1.163 +#if defined(WIN16)
   1.164 +    /*
   1.165 +    ** Under WIN16, the stack of the current thread is always mapped into
   1.166 +    ** the "task stack" (at SS:xxxx).  So, if t is the current thread, scan
   1.167 +    ** the "task stack".  Otherwise, scan the "cached stack" of the inactive
   1.168 +    ** thread...
   1.169 +    */
   1.170 +    if (t == current) {
   1.171 +        sp  = (PRWord*) &stack_end;
   1.172 +        esp = (PRWord*) _pr_top_of_task_stack;
   1.173 +
   1.174 +        PR_ASSERT(sp <= esp);
   1.175 +    } else {
   1.176 +        sp  = (PRWord*) PR_GetSP(t);
   1.177 +        esp = (PRWord*) t->stack->stackTop;
   1.178 +
   1.179 +	PR_ASSERT((t->stack->stackSize == 0) ||
   1.180 +                 ((sp >  (PRWord*)t->stack->stackBottom) &&
   1.181 +		  (sp <= (PRWord*)t->stack->stackTop)));
   1.182 +    }
   1.183 +#else   /* ! WIN16 */
   1.184 +#ifdef HAVE_STACK_GROWING_UP
   1.185 +    if (t == current) {
   1.186 +        esp = (PRWord*) &stack_end;
   1.187 +    } else {
   1.188 +        esp = (PRWord*) PR_GetSP(t);
   1.189 +    }
   1.190 +    sp = (PRWord*) t->stack->stackTop;
   1.191 +    if (t->stack->stackSize) {
   1.192 +        PR_ASSERT((esp > (PRWord*)t->stack->stackTop) &&
   1.193 +                  (esp < (PRWord*)t->stack->stackBottom));
   1.194 +    }
   1.195 +#else   /* ! HAVE_STACK_GROWING_UP */
   1.196 +    if (t == current) {
   1.197 +        sp = (PRWord*) &stack_end;
   1.198 +    } else {
   1.199 +        sp = (PRWord*) PR_GetSP(t);
   1.200 +    }
   1.201 +    esp = (PRWord*) t->stack->stackTop;
   1.202 +    if (t->stack->stackSize) {
   1.203 +	PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) &&
   1.204 +		  (sp < (PRWord*)t->stack->stackTop));
   1.205 +    }
   1.206 +#endif  /* ! HAVE_STACK_GROWING_UP */
   1.207 +#endif  /* ! WIN16 */
   1.208 +    return (PRUword)t->stack->stackSize - ((PRWord)esp - (PRWord)sp);
   1.209 +}

mercurial