tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

prthinfo.c (3923B)


      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  return _MD_HomeGCRegisters(t, isCurrent, np);
     14 }
     15 
     16 PR_IMPLEMENT(PRStatus)
     17 PR_ThreadScanStackPointers(PRThread* t, PRScanStackFun scanFun,
     18                           void* scanClosure) {
     19  PRThread* current = PR_GetCurrentThread();
     20  PRWord *sp, *esp, *p0;
     21  int n;
     22  void** ptd;
     23  PRStatus status;
     24  PRUint32 index;
     25  int stack_end;
     26 
     27  /*
     28  ** Store the thread's registers in the thread structure so the GC
     29  ** can scan them. Then scan them.
     30  */
     31  p0 = _MD_HomeGCRegisters(t, t == current, &n);
     32  status = scanFun(t, (void**)p0, n, scanClosure);
     33  if (status != PR_SUCCESS) {
     34    return status;
     35  }
     36 
     37  /* Scan the C stack for pointers into the GC heap */
     38 #ifdef HAVE_STACK_GROWING_UP
     39  if (t == current) {
     40    esp = (PRWord*)&stack_end;
     41  } else {
     42    esp = (PRWord*)PR_GetSP(t);
     43  }
     44  sp = (PRWord*)t->stack->stackTop;
     45  if (t->stack->stackSize) {
     46    PR_ASSERT((esp > (PRWord*)t->stack->stackTop) &&
     47              (esp < (PRWord*)t->stack->stackBottom));
     48  }
     49 #else  /* ! HAVE_STACK_GROWING_UP */
     50  if (t == current) {
     51    sp = (PRWord*)&stack_end;
     52  } else {
     53    sp = (PRWord*)PR_GetSP(t);
     54  }
     55  esp = (PRWord*)t->stack->stackTop;
     56  if (t->stack->stackSize) {
     57    PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) &&
     58              (sp < (PRWord*)t->stack->stackTop));
     59  }
     60 #endif /* ! HAVE_STACK_GROWING_UP */
     61 
     62  if (sp < esp) {
     63    status = scanFun(t, (void**)sp, esp - sp, scanClosure);
     64    if (status != PR_SUCCESS) {
     65      return status;
     66    }
     67  }
     68 
     69  /*
     70  ** Mark all of the per-thread-data items attached to this thread
     71  **
     72  ** The execution environment better be accounted for otherwise it
     73  ** will be collected
     74  */
     75  status = scanFun(t, (void**)&t->environment, 1, scanClosure);
     76  if (status != PR_SUCCESS) {
     77    return status;
     78  }
     79 
     80  /* if thread is not allocated on stack, this is redundant. */
     81  ptd = t->privateData;
     82  for (index = 0; index < t->tpdLength; index++, ptd++) {
     83    status = scanFun(t, (void**)ptd, 1, scanClosure);
     84    if (status != PR_SUCCESS) {
     85      return status;
     86    }
     87  }
     88 
     89  return PR_SUCCESS;
     90 }
     91 
     92 /* transducer for PR_EnumerateThreads */
     93 typedef struct PRScanStackData {
     94  PRScanStackFun scanFun;
     95  void* scanClosure;
     96 } PRScanStackData;
     97 
     98 static PRStatus PR_CALLBACK pr_ScanStack(PRThread* t, int i, void* arg) {
     99  PRScanStackData* data = (PRScanStackData*)arg;
    100  return PR_ThreadScanStackPointers(t, data->scanFun, data->scanClosure);
    101 }
    102 
    103 PR_IMPLEMENT(PRStatus)
    104 PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure) {
    105  PRScanStackData data;
    106  data.scanFun = scanFun;
    107  data.scanClosure = scanClosure;
    108  return PR_EnumerateThreads(pr_ScanStack, &data);
    109 }
    110 
    111 PR_IMPLEMENT(PRUword)
    112 PR_GetStackSpaceLeft(PRThread* t) {
    113  PRThread* current = PR_GetCurrentThread();
    114  PRWord *sp, *esp;
    115  int stack_end;
    116 
    117 #ifdef HAVE_STACK_GROWING_UP
    118  if (t == current) {
    119    esp = (PRWord*)&stack_end;
    120  } else {
    121    esp = (PRWord*)PR_GetSP(t);
    122  }
    123  sp = (PRWord*)t->stack->stackTop;
    124  if (t->stack->stackSize) {
    125    PR_ASSERT((esp > (PRWord*)t->stack->stackTop) &&
    126              (esp < (PRWord*)t->stack->stackBottom));
    127  }
    128 #else  /* ! HAVE_STACK_GROWING_UP */
    129  if (t == current) {
    130    sp = (PRWord*)&stack_end;
    131  } else {
    132    sp = (PRWord*)PR_GetSP(t);
    133  }
    134  esp = (PRWord*)t->stack->stackTop;
    135  if (t->stack->stackSize) {
    136    PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) &&
    137              (sp < (PRWord*)t->stack->stackTop));
    138  }
    139 #endif /* ! HAVE_STACK_GROWING_UP */
    140  return (PRUword)t->stack->stackSize - ((PRWord)esp - (PRWord)sp);
    141 }