| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |  | 
| 2 /* This Source Code Form is subject to the terms of the Mozilla Public |  | 
| 3  * License, v. 2.0. If a copy of the MPL was not distributed with this |  | 
| 4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |  | 
| 5 |  | 
| 6 #include "prlog.h" |  | 
| 7 #include "prthread.h" |  | 
| 8 #include "private/pprthred.h" |  | 
| 9 #include "primpl.h" |  | 
| 10 |  | 
| 11 PR_IMPLEMENT(PRWord *) |  | 
| 12 PR_GetGCRegisters(PRThread *t, int isCurrent, int *np) |  | 
| 13 { |  | 
| 14     return _MD_HomeGCRegisters(t, isCurrent, np); |  | 
| 15 } |  | 
| 16 |  | 
| 17 PR_IMPLEMENT(PRStatus) |  | 
| 18 PR_ThreadScanStackPointers(PRThread* t, |  | 
| 19                            PRScanStackFun scanFun, void* scanClosure) |  | 
| 20 { |  | 
| 21     PRThread* current = PR_GetCurrentThread(); |  | 
| 22     PRWord *sp, *esp, *p0; |  | 
| 23     int n; |  | 
| 24     void **ptd; |  | 
| 25     PRStatus status; |  | 
| 26     PRUint32 index; |  | 
| 27     int stack_end; |  | 
| 28 |  | 
| 29     /* |  | 
| 30     ** Store the thread's registers in the thread structure so the GC |  | 
| 31     ** can scan them. Then scan them. |  | 
| 32     */ |  | 
| 33     p0 = _MD_HomeGCRegisters(t, t == current, &n); |  | 
| 34     status = scanFun(t, (void**)p0, n, scanClosure); |  | 
| 35     if (status != PR_SUCCESS) |  | 
| 36         return status; |  | 
| 37 |  | 
| 38     /* Scan the C stack for pointers into the GC heap */ |  | 
| 39 #if defined(XP_PC) && defined(WIN16) |  | 
| 40     /* |  | 
| 41     ** Under WIN16, the stack of the current thread is always mapped into |  | 
| 42     ** the "task stack" (at SS:xxxx).  So, if t is the current thread, scan |  | 
| 43     ** the "task stack".  Otherwise, scan the "cached stack" of the inactive |  | 
| 44     ** thread... |  | 
| 45     */ |  | 
| 46     if (t == current) { |  | 
| 47         sp  = (PRWord*) &stack_end; |  | 
| 48         esp = (PRWord*) _pr_top_of_task_stack; |  | 
| 49 |  | 
| 50         PR_ASSERT(sp <= esp); |  | 
| 51     } else { |  | 
| 52         sp  = (PRWord*) PR_GetSP(t); |  | 
| 53         esp = (PRWord*) t->stack->stackTop; |  | 
| 54 |  | 
| 55         PR_ASSERT((t->stack->stackSize == 0) || |  | 
| 56                   ((sp >  (PRWord*)t->stack->stackBottom) && |  | 
| 57                    (sp <= (PRWord*)t->stack->stackTop))); |  | 
| 58     } |  | 
| 59 #else   /* ! WIN16 */ |  | 
| 60 #ifdef HAVE_STACK_GROWING_UP |  | 
| 61     if (t == current) { |  | 
| 62         esp = (PRWord*) &stack_end; |  | 
| 63     } else { |  | 
| 64         esp = (PRWord*) PR_GetSP(t); |  | 
| 65     } |  | 
| 66     sp = (PRWord*) t->stack->stackTop; |  | 
| 67     if (t->stack->stackSize) { |  | 
| 68         PR_ASSERT((esp > (PRWord*)t->stack->stackTop) && |  | 
| 69                   (esp < (PRWord*)t->stack->stackBottom)); |  | 
| 70     } |  | 
| 71 #else   /* ! HAVE_STACK_GROWING_UP */ |  | 
| 72     if (t == current) { |  | 
| 73         sp = (PRWord*) &stack_end; |  | 
| 74     } else { |  | 
| 75         sp = (PRWord*) PR_GetSP(t); |  | 
| 76     } |  | 
| 77     esp = (PRWord*) t->stack->stackTop; |  | 
| 78     if (t->stack->stackSize) { |  | 
| 79         PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) && |  | 
| 80                   (sp < (PRWord*)t->stack->stackTop)); |  | 
| 81     } |  | 
| 82 #endif  /* ! HAVE_STACK_GROWING_UP */ |  | 
| 83 #endif  /* ! WIN16 */ |  | 
| 84 |  | 
| 85 #if defined(WIN16) |  | 
| 86     { |  | 
| 87         prword_t scan; |  | 
| 88         prword_t limit; |  | 
| 89 |  | 
| 90         scan = (prword_t) sp; |  | 
| 91         limit = (prword_t) esp; |  | 
| 92         while (scan < limit) { |  | 
| 93             prword_t *test; |  | 
| 94 |  | 
| 95             test = *((prword_t **)scan); |  | 
| 96             status = scanFun(t, (void**)&test, 1, scanClosure); |  | 
| 97             if (status != PR_SUCCESS) |  | 
| 98                 return status; |  | 
| 99             scan += sizeof(char); |  | 
| 100         } |  | 
| 101     } |  | 
| 102 #else |  | 
| 103     if (sp < esp) { |  | 
| 104         status = scanFun(t, (void**)sp, esp - sp, scanClosure); |  | 
| 105         if (status != PR_SUCCESS) |  | 
| 106             return status; |  | 
| 107     } |  | 
| 108 #endif |  | 
| 109 |  | 
| 110     /* |  | 
| 111     ** Mark all of the per-thread-data items attached to this thread |  | 
| 112     ** |  | 
| 113     ** The execution environment better be accounted for otherwise it |  | 
| 114     ** will be collected |  | 
| 115     */ |  | 
| 116     status = scanFun(t, (void**)&t->environment, 1, scanClosure); |  | 
| 117     if (status != PR_SUCCESS) |  | 
| 118         return status; |  | 
| 119 |  | 
| 120     /* if thread is not allocated on stack, this is redundant. */ |  | 
| 121     ptd = t->privateData; |  | 
| 122     for (index = 0; index < t->tpdLength; index++, ptd++) { |  | 
| 123         status = scanFun(t, (void**)ptd, 1, scanClosure); |  | 
| 124         if (status != PR_SUCCESS) |  | 
| 125             return status; |  | 
| 126     } |  | 
| 127 |  | 
| 128     return PR_SUCCESS; |  | 
| 129 } |  | 
| 130 |  | 
| 131 /* transducer for PR_EnumerateThreads */ |  | 
| 132 typedef struct PRScanStackData { |  | 
| 133     PRScanStackFun      scanFun; |  | 
| 134     void*               scanClosure; |  | 
| 135 } PRScanStackData; |  | 
| 136 |  | 
| 137 static PRStatus PR_CALLBACK |  | 
| 138 pr_ScanStack(PRThread* t, int i, void* arg) |  | 
| 139 { |  | 
| 140     PRScanStackData* data = (PRScanStackData*)arg; |  | 
| 141     return PR_ThreadScanStackPointers(t, data->scanFun, data->scanClosure); |  | 
| 142 } |  | 
| 143 |  | 
| 144 PR_IMPLEMENT(PRStatus) |  | 
| 145 PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure) |  | 
| 146 { |  | 
| 147     PRScanStackData data; |  | 
| 148     data.scanFun = scanFun; |  | 
| 149     data.scanClosure = scanClosure; |  | 
| 150     return PR_EnumerateThreads(pr_ScanStack, &data); |  | 
| 151 } |  | 
| 152 |  | 
| 153 PR_IMPLEMENT(PRUword) |  | 
| 154 PR_GetStackSpaceLeft(PRThread* t) |  | 
| 155 { |  | 
| 156     PRThread *current = PR_GetCurrentThread(); |  | 
| 157     PRWord *sp, *esp; |  | 
| 158     int stack_end; |  | 
| 159 |  | 
| 160 #if defined(WIN16) |  | 
| 161     /* |  | 
| 162     ** Under WIN16, the stack of the current thread is always mapped into |  | 
| 163     ** the "task stack" (at SS:xxxx).  So, if t is the current thread, scan |  | 
| 164     ** the "task stack".  Otherwise, scan the "cached stack" of the inactive |  | 
| 165     ** thread... |  | 
| 166     */ |  | 
| 167     if (t == current) { |  | 
| 168         sp  = (PRWord*) &stack_end; |  | 
| 169         esp = (PRWord*) _pr_top_of_task_stack; |  | 
| 170 |  | 
| 171         PR_ASSERT(sp <= esp); |  | 
| 172     } else { |  | 
| 173         sp  = (PRWord*) PR_GetSP(t); |  | 
| 174         esp = (PRWord*) t->stack->stackTop; |  | 
| 175 |  | 
| 176         PR_ASSERT((t->stack->stackSize == 0) || |  | 
| 177                  ((sp >  (PRWord*)t->stack->stackBottom) && |  | 
| 178                   (sp <= (PRWord*)t->stack->stackTop))); |  | 
| 179     } |  | 
| 180 #else   /* ! WIN16 */ |  | 
| 181 #ifdef HAVE_STACK_GROWING_UP |  | 
| 182     if (t == current) { |  | 
| 183         esp = (PRWord*) &stack_end; |  | 
| 184     } else { |  | 
| 185         esp = (PRWord*) PR_GetSP(t); |  | 
| 186     } |  | 
| 187     sp = (PRWord*) t->stack->stackTop; |  | 
| 188     if (t->stack->stackSize) { |  | 
| 189         PR_ASSERT((esp > (PRWord*)t->stack->stackTop) && |  | 
| 190                   (esp < (PRWord*)t->stack->stackBottom)); |  | 
| 191     } |  | 
| 192 #else   /* ! HAVE_STACK_GROWING_UP */ |  | 
| 193     if (t == current) { |  | 
| 194         sp = (PRWord*) &stack_end; |  | 
| 195     } else { |  | 
| 196         sp = (PRWord*) PR_GetSP(t); |  | 
| 197     } |  | 
| 198     esp = (PRWord*) t->stack->stackTop; |  | 
| 199     if (t->stack->stackSize) { |  | 
| 200         PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) && |  | 
| 201                   (sp < (PRWord*)t->stack->stackTop)); |  | 
| 202     } |  | 
| 203 #endif  /* ! HAVE_STACK_GROWING_UP */ |  | 
| 204 #endif  /* ! WIN16 */ |  | 
| 205     return (PRUword)t->stack->stackSize - ((PRWord)esp - (PRWord)sp); |  | 
| 206 } |  | 
| OLD | NEW | 
|---|