tools/trace-malloc/tmreader.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 *
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6 #ifndef tmreader_h___
michael@0 7 #define tmreader_h___
michael@0 8
michael@0 9 #include "plhash.h"
michael@0 10 #include "nsTraceMalloc.h"
michael@0 11 #include "plarena.h"
michael@0 12
michael@0 13 #ifdef __cplusplus
michael@0 14 extern "C" {
michael@0 15 #endif
michael@0 16
michael@0 17 typedef struct tmreader tmreader;
michael@0 18 typedef struct tmevent tmevent;
michael@0 19 typedef struct tmcounts tmcounts;
michael@0 20 typedef struct tmallcounts tmallcounts;
michael@0 21 typedef struct tmgraphlink tmgraphlink;
michael@0 22 typedef struct tmgraphedge tmgraphedge;
michael@0 23 typedef struct tmgraphnode tmgraphnode;
michael@0 24 typedef struct tmcallsite tmcallsite;
michael@0 25 typedef struct tmmethodnode tmmethodnode;
michael@0 26
michael@0 27 struct tmevent {
michael@0 28 char type;
michael@0 29 uint32_t serial;
michael@0 30 union {
michael@0 31 char *libname;
michael@0 32 char *srcname;
michael@0 33 struct {
michael@0 34 uint32_t library;
michael@0 35 uint32_t filename;
michael@0 36 uint32_t linenumber;
michael@0 37 char *name;
michael@0 38 } method;
michael@0 39 struct {
michael@0 40 uint32_t parent;
michael@0 41 uint32_t method;
michael@0 42 uint32_t offset;
michael@0 43 } site;
michael@0 44 struct {
michael@0 45 uint32_t interval; /* in ticks */
michael@0 46 uint32_t ptr;
michael@0 47 uint32_t size;
michael@0 48 uint32_t oldserial;
michael@0 49 uint32_t oldptr;
michael@0 50 uint32_t oldsize;
michael@0 51 uint32_t cost; /* in ticks */
michael@0 52 } alloc;
michael@0 53 struct {
michael@0 54 nsTMStats tmstats;
michael@0 55 uint32_t calltree_maxkids_parent;
michael@0 56 uint32_t calltree_maxstack_top;
michael@0 57 } stats;
michael@0 58 } u;
michael@0 59 };
michael@0 60
michael@0 61 struct tmcounts {
michael@0 62 uint32_t direct; /* things allocated by this node's code */
michael@0 63 uint32_t total; /* direct + things from all descendents */
michael@0 64 };
michael@0 65
michael@0 66 struct tmallcounts {
michael@0 67 tmcounts bytes;
michael@0 68 tmcounts calls;
michael@0 69 };
michael@0 70
michael@0 71 struct tmgraphnode {
michael@0 72 PLHashEntry entry; /* key is serial or name, value must be name */
michael@0 73 tmgraphlink *in;
michael@0 74 tmgraphlink *out;
michael@0 75 tmgraphnode *up; /* parent in supergraph, e.g., JS for JS_*() */
michael@0 76 tmgraphnode *down; /* subgraph kids, declining bytes.total order */
michael@0 77 tmgraphnode *next; /* next kid in supergraph node's down list */
michael@0 78 int low; /* 0 or lowest current tree walk level */
michael@0 79 tmallcounts allocs;
michael@0 80 tmallcounts frees;
michael@0 81 double sqsum; /* sum of squared bytes.direct */
michael@0 82 int sort; /* sorted index in node table, -1 if no table */
michael@0 83 };
michael@0 84
michael@0 85 struct tmmethodnode {
michael@0 86 tmgraphnode graphnode;
michael@0 87 char *sourcefile;
michael@0 88 uint32_t linenumber;
michael@0 89 };
michael@0 90
michael@0 91 #define tmgraphnode_name(node) ((char*) (node)->entry.value)
michael@0 92 #define tmmethodnode_name(node) ((char*) (node)->graphnode.entry.value)
michael@0 93
michael@0 94 #define tmlibrary_serial(lib) ((uint32_t) (lib)->entry.key)
michael@0 95 #define tmcomponent_name(comp) ((const char*) (comp)->entry.key)
michael@0 96 #define filename_name(hashentry) ((char*)hashentry->value)
michael@0 97
michael@0 98 /* Half a graphedge, not including per-edge allocation stats. */
michael@0 99 struct tmgraphlink {
michael@0 100 tmgraphlink *next; /* next fanning out from or into a node */
michael@0 101 tmgraphnode *node; /* the other node (to if OUT, from if IN) */
michael@0 102 };
michael@0 103
michael@0 104 /*
michael@0 105 * It's safe to downcast a "from" tmgraphlink (one linked from a node's out
michael@0 106 * pointer) to tmgraphedge. To go from an "out" (linked via tmgraphedge.from)
michael@0 107 * or "in" (linked via tmgraphedge.to) list link to its containing edge, use
michael@0 108 * TM_LINK_TO_EDGE(link, which).
michael@0 109 */
michael@0 110 struct tmgraphedge {
michael@0 111 tmgraphlink links[2];
michael@0 112 tmallcounts allocs;
michael@0 113 tmallcounts frees;
michael@0 114 };
michael@0 115
michael@0 116 /* Indices into tmgraphedge.links -- out must come first. */
michael@0 117 #define TM_EDGE_OUT_LINK 0
michael@0 118 #define TM_EDGE_IN_LINK 1
michael@0 119
michael@0 120 #define TM_LINK_TO_EDGE(link,which) ((tmgraphedge*) &(link)[-(which)])
michael@0 121
michael@0 122 struct tmcallsite {
michael@0 123 PLHashEntry entry; /* key is site serial number */
michael@0 124 tmcallsite *parent; /* calling site */
michael@0 125 tmcallsite *siblings; /* other sites reached from parent */
michael@0 126 tmcallsite *kids; /* sites reached from here */
michael@0 127 tmmethodnode *method; /* method node in tmr->methods graph */
michael@0 128 uint32_t offset; /* pc offset from start of method */
michael@0 129 tmallcounts allocs;
michael@0 130 tmallcounts frees;
michael@0 131 void *data; /* tmreader clients can stick arbitrary
michael@0 132 * data onto a callsite.
michael@0 133 */
michael@0 134 };
michael@0 135
michael@0 136 struct tmreader {
michael@0 137 const char *program;
michael@0 138 void *data;
michael@0 139 PLHashTable *libraries;
michael@0 140 PLHashTable *filenames;
michael@0 141 PLHashTable *components;
michael@0 142 PLHashTable *methods;
michael@0 143 PLHashTable *callsites;
michael@0 144 PLArenaPool arena;
michael@0 145 tmcallsite calltree_root;
michael@0 146 uint32_t ticksPerSec;
michael@0 147 };
michael@0 148
michael@0 149 typedef void (*tmeventhandler)(tmreader *tmr, tmevent *event);
michael@0 150
michael@0 151 /* The tmreader constructor and destructor. */
michael@0 152 extern tmreader *tmreader_new(const char *program, void *data);
michael@0 153 extern void tmreader_destroy(tmreader *tmr);
michael@0 154
michael@0 155 /*
michael@0 156 * Return -1 on permanent fatal error, 0 if filename can't be opened or is not
michael@0 157 * a trace-malloc logfile, and 1 on success.
michael@0 158 */
michael@0 159 extern int tmreader_eventloop(tmreader *tmr, const char *filename,
michael@0 160 tmeventhandler eventhandler);
michael@0 161
michael@0 162 /* Map serial number or name to graphnode or callsite. */
michael@0 163 extern tmgraphnode *tmreader_library(tmreader *tmr, uint32_t serial);
michael@0 164 extern tmgraphnode *tmreader_filename(tmreader *tmr, uint32_t serial);
michael@0 165 extern tmgraphnode *tmreader_component(tmreader *tmr, const char *name);
michael@0 166 extern tmmethodnode *tmreader_method(tmreader *tmr, uint32_t serial);
michael@0 167 extern tmcallsite *tmreader_callsite(tmreader *tmr, uint32_t serial);
michael@0 168
michael@0 169 /*
michael@0 170 * Connect node 'from' to node 'to' with an edge, if there isn't one already
michael@0 171 * connecting the nodes. Add site's allocation stats to the edge only if we
michael@0 172 * create the edge, or if we find that it exists, but that to->low is zero or
michael@0 173 * less than from->low.
michael@0 174 *
michael@0 175 * If the callsite tree already totals allocation costs (tmcounts.total for
michael@0 176 * each site includes tmcounts.direct for that site, plus tmcounts.total for
michael@0 177 * all kid sites), then the node->low watermarks should be set from the tree
michael@0 178 * level when walking the callsite tree, and should be set to non-zero values
michael@0 179 * only if zero (the root is at level 0). A low watermark should be cleared
michael@0 180 * when the tree walk unwinds past the level at which it was set non-zero.
michael@0 181 *
michael@0 182 * Return 0 on error (malloc failure) and 1 on success.
michael@0 183 */
michael@0 184 extern int tmgraphnode_connect(tmgraphnode *from, tmgraphnode *to,
michael@0 185 tmcallsite *site);
michael@0 186
michael@0 187 #ifdef __cplusplus
michael@0 188 }
michael@0 189 #endif
michael@0 190
michael@0 191 #endif /* tmreader_h___ */

mercurial