Commit 24bd8dad authored by Chris Toshok's avatar Chris Toshok

add libunwind_patch for binary search

parent 3ebd2551
......@@ -78,7 +78,8 @@ add_custom_target(llvm_up DEPENDS llvm_gotorev clang_gotorev)
set(LIBUNWIND_PATCHES
${CMAKE_SOURCE_DIR}/libunwind_patches/0001-pyston-add-lots-of-comments.patch
${CMAKE_SOURCE_DIR}/libunwind_patches/0002-pyston-stop-x86_64-setcontext-restoring-uninitialize.patch)
${CMAKE_SOURCE_DIR}/libunwind_patches/0002-pyston-stop-x86_64-setcontext-restoring-uninitialize.patch
${CMAKE_SOURCE_DIR}/libunwind_patches/0003-use-a-sorted-array-for-registered-objects-and-do-a-b.patch)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/gitmodules
COMMAND git submodule update --init
......
From 02b71ed234a7b41af25e55a317f71b5f68a7851d Mon Sep 17 00:00:00 2001
From: Chris Toshok <toshok@dropbox.com>
Date: Tue, 26 May 2015 19:40:27 +0000
Subject: [PATCH] use a sorted array for registered objects and do a binary
search
---
include/libunwind_i.h | 4 +++-
src/mi/Gfind_dynamic_proc_info.c | 23 ++++++++++++++++-------
src/mi/dyn-cancel.c | 20 +++++++++-----------
src/mi/dyn-info-list.c | 4 +++-
src/mi/dyn-register.c | 29 ++++++++++++++++++++++-------
src/x86_64/Ginit.c | 2 +-
6 files changed, 54 insertions(+), 28 deletions(-)
diff --git a/include/libunwind_i.h b/include/libunwind_i.h
index 892e39c..fee3a6e 100644
--- a/include/libunwind_i.h
+++ b/include/libunwind_i.h
@@ -254,7 +254,9 @@ extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as,
void *arg);
extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg);
-extern unw_dyn_info_list_t _U_dyn_info_list;
+extern unw_dyn_info_t** _U_dyn_info_list;
+extern int _U_dyn_info_list_size;
+extern int _U_dyn_info_list_alloc;
extern pthread_mutex_t _U_dyn_info_list_lock;
#if UNW_DEBUG
diff --git a/src/mi/Gfind_dynamic_proc_info.c b/src/mi/Gfind_dynamic_proc_info.c
index 6cf3b42..a3b8ee0 100644
--- a/src/mi/Gfind_dynamic_proc_info.c
+++ b/src/mi/Gfind_dynamic_proc_info.c
@@ -40,8 +40,7 @@ static inline int
local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
int need_unwind_info, void *arg)
{
- unw_dyn_info_list_t *list;
- unw_dyn_info_t *di;
+ unw_dyn_info_t **list;
#ifndef UNW_LOCAL_ONLY
# pragma weak _U_dyn_info_list_addr
@@ -49,11 +48,21 @@ local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
return -UNW_ENOINFO;
#endif
- list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr ();
- for (di = list->first; di; di = di->next)
- if (ip >= di->start_ip && ip < di->end_ip)
- return unwi_extract_dynamic_proc_info (as, ip, pi, di, need_unwind_info,
- arg);
+ list = _U_dyn_info_list;
+
+ int l = 0, r = _U_dyn_info_list_size - 1;
+ while (l <= r) {
+ size_t mid = l + (r - l) / 2;
+ unw_dyn_info_t *di = list[mid];
+ if (ip < di->start_ip)
+ r = mid - 1;
+ else if (ip >= di->end_ip)
+ l = mid + 1;
+ else {
+ return unwi_extract_dynamic_proc_info (as, ip, pi, di, need_unwind_info,
+ arg);
+ }
+ }
return -UNW_ENOINFO;
}
diff --git a/src/mi/dyn-cancel.c b/src/mi/dyn-cancel.c
index e784317..fedba3e 100644
--- a/src/mi/dyn-cancel.c
+++ b/src/mi/dyn-cancel.c
@@ -30,17 +30,15 @@ _U_dyn_cancel (unw_dyn_info_t *di)
{
mutex_lock (&_U_dyn_info_list_lock);
{
- ++_U_dyn_info_list.generation;
-
- if (di->prev)
- di->prev->next = di->next;
- else
- _U_dyn_info_list.first = di->next;
-
- if (di->next)
- di->next->prev = di->prev;
+ int i;
+ for (i = 0; i < _U_dyn_info_list_size; i ++) {
+ if (di == _U_dyn_info_list[i] && i < _U_dyn_info_list_size - 1) {
+ memmove(_U_dyn_info_list[i], _U_dyn_info_list[i+1],
+ sizeof(unw_dyn_info_t*) * (_U_dyn_info_list_size - i - 1));
+ break;
+ }
+ }
+ _U_dyn_info_list_size --;
}
mutex_unlock (&_U_dyn_info_list_lock);
-
- di->next = di->prev = NULL;
}
diff --git a/src/mi/dyn-info-list.c b/src/mi/dyn-info-list.c
index 5a5e30e..b7a927e 100644
--- a/src/mi/dyn-info-list.c
+++ b/src/mi/dyn-info-list.c
@@ -25,7 +25,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "libunwind_i.h"
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
+HIDDEN unw_dyn_info_t** _U_dyn_info_list = NULL;
+int _U_dyn_info_list_size = 0;
+int _U_dyn_info_list_alloc = 0;
PROTECTED unw_word_t
_U_dyn_info_list_addr (void)
diff --git a/src/mi/dyn-register.c b/src/mi/dyn-register.c
index c28954a..c4f88b1 100644
--- a/src/mi/dyn-register.c
+++ b/src/mi/dyn-register.c
@@ -32,13 +32,28 @@ _U_dyn_register (unw_dyn_info_t *di)
{
mutex_lock (&_U_dyn_info_list_lock);
{
- ++_U_dyn_info_list.generation;
-
- di->next = _U_dyn_info_list.first;
- di->prev = NULL;
- if (di->next)
- di->next->prev = di;
- _U_dyn_info_list.first = di;
+ int i;
+
+ if (_U_dyn_info_list_size >= _U_dyn_info_list_alloc) {
+ unw_dyn_info_t** new_list;
+ _U_dyn_info_list_alloc = _U_dyn_info_list_alloc * 2 + 1;
+ new_list = malloc(sizeof(unw_dyn_info_t*) * _U_dyn_info_list_alloc);
+ memmove(new_list, _U_dyn_info_list, sizeof(unw_dyn_info_t*) * _U_dyn_info_list_size);
+ free (_U_dyn_info_list);
+ _U_dyn_info_list = new_list;
+ }
+
+ for (i = 0; i < _U_dyn_info_list_size; i ++) {
+ unw_dyn_info_t* ldi = _U_dyn_info_list[i];
+ if (di->start_ip > ldi->start_ip)
+ continue;
+ break;
+ }
+
+ if (_U_dyn_info_list_size > 1)
+ memmove(&_U_dyn_info_list[i+1], &_U_dyn_info_list[i], (_U_dyn_info_list_size - i) * sizeof(unw_dyn_info_t*));
+ _U_dyn_info_list[i] = di;
+ _U_dyn_info_list_size ++;
}
mutex_unlock (&_U_dyn_info_list_lock);
}
diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c
index daea078..0feebbe 100644
--- a/src/x86_64/Ginit.c
+++ b/src/x86_64/Ginit.c
@@ -47,7 +47,7 @@ static struct unw_addr_space local_addr_space;
PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space;
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
+HIDDEN unw_dyn_info_t** _U_dyn_info_list;
/* XXX fix me: there is currently no way to locate the dyn-info list
by a remote unwinder. On ia64, this is done via a special
--
1.9.1
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment