nsprpub/pr/src/misc/prthinfo.c

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     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/. */
     6 #include "prlog.h"
     7 #include "prthread.h"
     8 #include "private/pprthred.h"
     9 #include "primpl.h"
    11 PR_IMPLEMENT(PRWord *)
    12 PR_GetGCRegisters(PRThread *t, int isCurrent, int *np)
    13 {
    14     return _MD_HomeGCRegisters(t, isCurrent, np);
    15 }
    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;
    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;
    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;
    50         PR_ASSERT(sp <= esp);
    51     } else {
    52         sp  = (PRWord*) PR_GetSP(t);
    53         esp = (PRWord*) t->stack->stackTop;
    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 */
    85 #if defined(WIN16)
    86     {
    87         prword_t scan;
    88         prword_t limit;
    90         scan = (prword_t) sp;
    91         limit = (prword_t) esp;
    92         while (scan < limit) {
    93             prword_t *test;
    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
   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;
   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     }
   128     return PR_SUCCESS;
   129 }
   131 /* transducer for PR_EnumerateThreads */
   132 typedef struct PRScanStackData {
   133     PRScanStackFun      scanFun;
   134     void*               scanClosure;
   135 } PRScanStackData;
   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 }
   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 }
   153 PR_IMPLEMENT(PRUword)
   154 PR_GetStackSpaceLeft(PRThread* t)
   155 {
   156     PRThread *current = PR_GetCurrentThread();
   157     PRWord *sp, *esp;
   158     int stack_end;
   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;
   171         PR_ASSERT(sp <= esp);
   172     } else {
   173         sp  = (PRWord*) PR_GetSP(t);
   174         esp = (PRWord*) t->stack->stackTop;
   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 }

mercurial