diff options
Diffstat (limited to 'package/mpatrol/mpatrol-unwindcache.patch')
-rw-r--r-- | package/mpatrol/mpatrol-unwindcache.patch | 208 |
1 files changed, 0 insertions, 208 deletions
diff --git a/package/mpatrol/mpatrol-unwindcache.patch b/package/mpatrol/mpatrol-unwindcache.patch deleted file mode 100644 index 3234d5c81..000000000 --- a/package/mpatrol/mpatrol-unwindcache.patch +++ /dev/null @@ -1,208 +0,0 @@ -Patch to improve MIPS call stack unwind performance by caching the results -of code reading. -by Dan Howell <dahowell@directv.com> - -diff -urN mpatrol-uclibc/src/stack.c mpatrol-unwindcache/src/stack.c ---- mpatrol-uclibc/src/stack.c 2006-06-22 15:39:04.000000000 -0700 -+++ mpatrol-unwindcache/src/stack.c 2006-06-22 15:42:20.000000000 -0700 -@@ -68,6 +68,7 @@ - #define ucontext asm_ucontext - #include <asm/ucontext.h> - #undef ucontext -+#include "heap.h" - #endif /* ARCH */ - #endif /* SYSTEM */ - #endif /* TARGET */ -@@ -280,6 +281,136 @@ - - #if !MP_BUILTINSTACK_SUPPORT && !MP_LIBRARYSTACK_SUPPORT - #if TARGET == TARGET_UNIX && ARCH == ARCH_MIPS -+/* Set up a tree to cache the results of code searching to determine the -+ location of the return address for each code point encountered. */ -+ -+/* An unwind node belongs to a binary search tree of nodes, ordered by -+ * code address, and contains call stack unwinding details for a given -+ * code address. An internal index node stores details of a single memory -+ * block allocated for unwind node slots. -+ */ -+typedef union unwindnode -+{ -+ struct -+ { -+ treenode node; /* internal tree node */ -+ void *block; /* pointer to block of memory */ -+ size_t size; /* size of block of memory */ -+ } -+ index; -+ struct -+ { -+ treenode node; /* tree node */ -+ long p; /* return address offset in the stack */ -+ long m; /* frame pointer offset in stack */ -+ long s; /* stack pointer offset from previous frame */ -+ unsigned long a; /* flags */ -+ } -+ data; -+} -+unwindnode; -+ -+/* An unwindhead holds the table of address node slots as well as the -+ * internal list of memory blocks allocated for address node slots. -+ */ -+typedef struct unwindhead -+{ -+ heaphead heap; /* pointer to heap */ -+ slottable table; /* table of address nodes */ -+ treeroot itree; /* internal list of memory blocks */ -+ treeroot dtree; /* tree for sorting */ -+ size_t size; /* memory used by internal blocks */ -+ char init; /* initialization flag */ -+} -+unwindhead; -+ -+static unwindhead unwindcache; -+ -+/* Initialise the fields of an unwindhead so that there are no allocated, -+ * freed or free blocks. -+ */ -+ -+static -+void -+newunwindcache(void) -+{ -+ struct { char x; unwindnode y; } z; -+ long n; -+ -+ __mp_newheap(&unwindcache.heap); -+ /* Determine the minimum alignment for an unwind node on this -+ * system and force the alignment to be a power of two. This -+ * information is used when initialising the slot table. -+ */ -+ n = (char *) &z.y - &z.x; -+ __mp_newslots(&unwindcache.table, sizeof(unwindnode), __mp_poweroftwo(n)); -+ __mp_newtree(&unwindcache.itree); -+ __mp_newtree(&unwindcache.dtree); -+ unwindcache.size = 0; -+ unwindcache.init = 1; -+} -+ -+ -+/* Forget all unwind information. -+ */ -+ -+static -+void -+deleteunwindcache(void) -+{ -+ /* We don't need to explicitly free any memory as this is dealt with -+ * at a lower level by the heap manager. -+ */ -+ __mp_deleteheap(&unwindcache.heap); -+ unwindcache.table.free = NULL; -+ unwindcache.table.size = 0; -+ __mp_newtree(&unwindcache.itree); -+ __mp_newtree(&unwindcache.dtree); -+ unwindcache.size = 0; -+ unwindcache.init = 0; -+} -+ -+ -+/* Allocate a new unwind node. -+ */ -+ -+static -+unwindnode * -+getunwindnode(void) -+{ -+ unwindnode *n; -+ heapnode *p; -+ -+ /* If we have no more allocation node slots left then we must allocate -+ * some more memory for them. An extra MP_ALLOCFACTOR pages of memory -+ * should suffice. -+ */ -+ if ((n = (unwindnode *) __mp_getslot(&unwindcache.table)) == NULL) -+ { -+ if ((p = __mp_heapalloc(&unwindcache.heap, unwindcache.heap.memory.page * MP_ALLOCFACTOR, -+ unwindcache.table.entalign, 1)) == NULL) -+ return NULL; -+ __mp_initslots(&unwindcache.table, p->block, p->size); -+ n = (unwindnode *) __mp_getslot(&unwindcache.table); -+ __mp_treeinsert(&unwindcache.itree, &n->index.node, (unsigned long) p->block); -+ n->index.block = p->block; -+ n->index.size = p->size; -+ unwindcache.size += p->size; -+ n = (unwindnode *) __mp_getslot(&unwindcache.table); -+ } -+ return n; -+} -+ -+/* Search for the unwind node associated with a given address. -+ */ -+static -+unwindnode * -+findunwindnode(unsigned long p) -+{ -+ return (unwindnode *) __mp_search(unwindcache.dtree.root, p); -+} -+ -+ - /* Determine the stack pointer and return address of the previous stack frame - * by performing code reading. - */ -@@ -289,8 +420,9 @@ - unwind(frameinfo *f) - { - long p, m, s; -- unsigned long a, i, q, t, b, r; -+ unsigned long a, i, q, t, b, r, k; - unsigned short l, u; -+ unwindnode *n = NULL; - - s = -1; - p = m = 0; -@@ -322,7 +454,23 @@ - #endif - /* Save initial code-reading starting point. - */ -- r = f->ra; -+ r = k = f->ra; -+ /* Create the cache if not yet created. -+ */ -+ if (!unwindcache.init) -+ { -+ newunwindcache(); -+ __mp_atexit(deleteunwindcache); -+ } -+ if ((n = findunwindnode(f->ra)) != NULL) -+ { -+ /* We've been here before, so get the cached information. -+ */ -+ p = n->data.p; -+ m = n->data.m; -+ s = n->data.s; -+ a = n->data.a; -+ } - /* Search for the return address offset in the stack frame. - */ - while (!((a & RA_OFFSET) && (a & SP_OFFSET)) && (f->ra < q)) -@@ -478,6 +626,19 @@ - return 1; - } - #endif -+ if (n == NULL) -+ { -+ if ((n = getunwindnode()) != NULL) -+ { -+ /* Cache the information we just got in the tree. -+ */ -+ n->data.p = p; -+ n->data.m = m; -+ n->data.s = s; -+ n->data.a = a; -+ __mp_treeinsert(&unwindcache.dtree, &n->data.node, k); -+ } -+ } - if (a & SP_IN_FP) - f->sp = f->fp; - if (m > 0) |