summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJUNG DONG-HEON <dheon.jung@samsung.com>2020-01-09 16:38:00 +0900
committerGleb Balykov <g.balykov@samsung.com>2020-03-25 15:29:41 +0300
commite27f1498b675f8615ed9def15dc8538635f6439b (patch)
treee83fd885fb21eed343087559ea2222c858bea7f0
parent3387802e68dae56c17b07a52ffb282ad330b9213 (diff)
downloadcoreclr-e27f1498b675f8615ed9def15dc8538635f6439b.tar.gz
coreclr-e27f1498b675f8615ed9def15dc8538635f6439b.tar.bz2
coreclr-e27f1498b675f8615ed9def15dc8538635f6439b.zip
[Tizen] Reduce arm_phdr_cb call overhead
- Too many calls to arm_phdr_cb even though it get the same data. - It caches an ARM_CB_DATA for libcoreclr.so, then reuse.
-rw-r--r--src/pal/src/libunwind/include/tdep-arm/libunwind_i.h3
-rw-r--r--src/pal/src/libunwind/src/arm/Gex_tables.c45
-rw-r--r--src/pal/src/libunwind/src/arm/Gglobal.c1
3 files changed, 48 insertions, 1 deletions
diff --git a/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h b/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h
index 2602f41c4f..608107bfd3 100644
--- a/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h
+++ b/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h
@@ -254,6 +254,8 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
#define tdep_init UNW_OBJ(init)
#define arm_find_proc_info UNW_OBJ(find_proc_info)
#define arm_put_unwind_info UNW_OBJ(put_unwind_info)
+#define arm_cb_cache_data_init UNW_OBJ(cb_cache_data_init)
+
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */
#define tdep_search_unwind_table UNW_OBJ(search_unwind_table)
@@ -296,6 +298,7 @@ extern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
void *arg);
extern void arm_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg);
+extern void arm_cb_cache_data_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg);
diff --git a/src/pal/src/libunwind/src/arm/Gex_tables.c b/src/pal/src/libunwind/src/arm/Gex_tables.c
index d6573a65e0..1e7b0044b9 100644
--- a/src/pal/src/libunwind/src/arm/Gex_tables.c
+++ b/src/pal/src/libunwind/src/arm/Gex_tables.c
@@ -463,6 +463,16 @@ tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
/**
* Callback to dl_iterate_phdr to find infos about the ARM exidx segment.
*/
+struct arm_cb_cache_data
+{
+ unw_word_t start_ip;
+ unw_word_t end_ip;
+ unw_word_t name_ptr;
+ unw_word_t table_data;
+ unw_word_t table_len;
+};
+static struct arm_cb_cache_data g_cache_data = {0, 0, 0, 0, 0};
+
static int
arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data)
{
@@ -527,7 +537,20 @@ arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
cb_data.di.format = -1;
SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask);
- ret = dl_iterate_phdr (arm_phdr_cb, &cb_data);
+ if (ip >= g_cache_data.start_ip && ip < g_cache_data.end_ip)
+ {
+ cb_data.di.format = UNW_INFO_FORMAT_ARM_EXIDX;
+ cb_data.di.start_ip = g_cache_data.start_ip;
+ cb_data.di.end_ip = g_cache_data.end_ip;
+ cb_data.di.u.rti.name_ptr = g_cache_data.name_ptr;
+ cb_data.di.u.rti.table_data = g_cache_data.table_data;
+ cb_data.di.u.rti.table_len = g_cache_data.table_len;
+ }
+ else
+ {
+ ret = dl_iterate_phdr (arm_phdr_cb, &cb_data);
+ }
+
SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
if (cb_data.di.format != -1)
@@ -545,5 +568,25 @@ arm_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
/* it's a no-op */
}
+
+HIDDEN void
+arm_cb_cache_data_init(void)
+{
+ struct arm_cb_data cb_data;
+ memset (&cb_data, 0, sizeof (cb_data));
+ cb_data.ip = (unw_word_t)arm_cb_cache_data_init;
+ cb_data.pi = 0;
+ cb_data.di.format = -1;
+
+ int ret = dl_iterate_phdr (arm_phdr_cb, &cb_data);
+ if (ret > 0)
+ {
+ g_cache_data.start_ip = cb_data.di.start_ip;
+ g_cache_data.end_ip = cb_data.di.end_ip;
+ g_cache_data.name_ptr = cb_data.di.u.rti.name_ptr;
+ g_cache_data.table_data = cb_data.di.u.rti.table_data;
+ g_cache_data.table_len = cb_data.di.u.rti.table_len;
+ }
+}
#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/pal/src/libunwind/src/arm/Gglobal.c b/src/pal/src/libunwind/src/arm/Gglobal.c
index 7b93fbd89a..82428e31cd 100644
--- a/src/pal/src/libunwind/src/arm/Gglobal.c
+++ b/src/pal/src/libunwind/src/arm/Gglobal.c
@@ -55,6 +55,7 @@ tdep_init (void)
dwarf_init ();
+ arm_cb_cache_data_init ();
#ifndef UNW_REMOTE_ONLY
arm_local_addr_space_init ();
#endif