1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-12-23 20:03:43 +01:00

dwarf: Cleanup dwarf cache hint

0-valued hints are used when they are just initial values with no use as
hints. And I think there were some other problems as well.
This patch cleans up and stores hint values with 1 added, so that 0-valued
hints can be ignored.
This commit is contained in:
Doug Moore 2017-04-14 08:00:00 -07:00 committed by Dave Watson
parent f819f1b87c
commit 0f24c6dec8

View file

@ -613,33 +613,27 @@ cache_match (dwarf_reg_state_t *rs, unw_word_t ip)
static dwarf_reg_state_t * static dwarf_reg_state_t *
rs_lookup (struct dwarf_rs_cache *cache, struct dwarf_cursor *c) rs_lookup (struct dwarf_rs_cache *cache, struct dwarf_cursor *c)
{ {
dwarf_reg_state_t *rs = cache->buckets + c->hint; dwarf_reg_state_t *rs;
unsigned short index; unsigned short index;
unw_word_t ip; unw_word_t ip = c->ip;
ip = c->ip;
if (cache_match (rs, ip))
return rs;
index = cache->hash[hash (ip, cache->log_size)];
if (index >= DWARF_UNW_CACHE_SIZE(cache->log_size))
return NULL;
if (c->hint > 0)
{
index = c->hint - 1;
rs = cache->buckets + index; rs = cache->buckets + index;
while (1)
{
if (cache_match (rs, ip)) if (cache_match (rs, ip))
{
/* update hint; no locking needed: single-word writes are atomic */
c->hint = cache->buckets[c->prev_rs].hint =
(rs - cache->buckets);
return rs; return rs;
} }
if (rs->coll_chain >= DWARF_UNW_HASH_SIZE(cache->log_size))
return NULL; for (index = cache->hash[hash (ip, cache->log_size)];
rs = cache->buckets + rs->coll_chain; index < DWARF_UNW_CACHE_SIZE(cache->log_size);
index = rs->coll_chain)
{
rs = cache->buckets + index;
if (cache_match (rs, ip))
return rs;
} }
return NULL;
} }
static inline dwarf_reg_state_t * static inline dwarf_reg_state_t *
@ -687,7 +681,6 @@ rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c)
rs->coll_chain = cache->hash[index]; rs->coll_chain = cache->hash[index];
cache->hash[index] = rs - cache->buckets; cache->hash[index] = rs - cache->buckets;
rs->hint = 0;
rs->ip = c->ip; rs->ip = c->ip;
rs->valid = 1; rs->valid = 1;
rs->ret_addr_column = c->ret_addr_column; rs->ret_addr_column = c->ret_addr_column;
@ -907,6 +900,10 @@ dwarf_find_save_locs (struct dwarf_cursor *c)
if (rs) if (rs)
{ {
/* update hint; no locking needed: single-word writes are atomic */
cache->buckets[c->prev_rs].hint = rs - cache->buckets + 1;
c->prev_rs = rs - cache->buckets;
c->hint = rs->hint;
c->ret_addr_column = rs->ret_addr_column; c->ret_addr_column = rs->ret_addr_column;
c->use_prev_instr = ! rs->signal_frame; c->use_prev_instr = ! rs->signal_frame;
} }
@ -923,9 +920,8 @@ dwarf_find_save_locs (struct dwarf_cursor *c)
rs = rs_new (cache, c); rs = rs_new (cache, c);
memcpy(rs, &sr.rs_current, offsetof(struct dwarf_reg_state, ip)); memcpy(rs, &sr.rs_current, offsetof(struct dwarf_reg_state, ip));
cache->buckets[c->prev_rs].hint = rs - cache->buckets; cache->buckets[c->prev_rs].hint = rs - cache->buckets;
c->hint = rs->hint;
c->prev_rs = rs - cache->buckets; c->prev_rs = rs - cache->buckets;
c->hint = rs->hint = 0;
put_unwind_info (c, &c->pi); put_unwind_info (c, &c->pi);
} }