diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2018-07-03 17:10:26 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2018-07-03 17:10:26 +0300 |
commit | da3178cf1417dd300b306796c3cc73eceb8e32a3 (patch) | |
tree | 6579e1d4d3754fdea20b88c457fa9be4a3eea99b /backgraph.c | |
parent | 502b31f7f060ac230090573481aff890af364def (diff) | |
download | bdwgc-da3178cf1417dd300b306796c3cc73eceb8e32a3.tar.gz |
Remove multi-line macro (FOR_EACH_PRED) in backgraph
(code refactoring)
This change simplifies stepping thru backgraph code in gdb.
* backgraph.c (FOR_EACH_PRED): Remove macro.
* backgraph.c (add_edge): Rename old_back_ptr local variable to pred.
* backgraph.c (add_edge, backwards_height, update_max_height): Expand
FOR_EACH_PRED macro.
* backgraph.c (backwards_height): Rename back_ptr local variable to
pred.
* backgraph.c (backwards_height, update_max_height): Rename q local
variable to pred.
* backgraph.c (update_max_height): Rename q_height local variable to
this_height.
Diffstat (limited to 'backgraph.c')
-rw-r--r-- | backgraph.c | 169 |
1 files changed, 113 insertions, 56 deletions
diff --git a/backgraph.c b/backgraph.c index f52ed144..e178c7b4 100644 --- a/backgraph.c +++ b/backgraph.c @@ -181,30 +181,6 @@ GC_INLINE void pop_in_progress(ptr_t p GC_ATTR_UNUSED) (ptr_t)GC_REVEAL_POINTER(((oh *)(p)) -> oh_bg_ptr) #define SET_OH_BG_PTR(p,q) (((oh *)(p)) -> oh_bg_ptr = GC_HIDE_POINTER(q)) -/* Execute s once for each predecessor q of p in the points-to graph. */ -/* s should be a bracketed statement. We declare q. */ -#define FOR_EACH_PRED(q, p, s) \ - do { \ - ptr_t q = GET_OH_BG_PTR(p); \ - if (!((word)q & FLAG_MANY)) { \ - if (q && !((word)q & 1)) s \ - /* !((word)q & 1) checks for a misinterpreted freelist link */ \ - } else { \ - back_edges *orig_be_ = (back_edges *)((word)q & ~FLAG_MANY); \ - back_edges *be_ = orig_be_; \ - int local_; \ - word total_; \ - word n_edges_ = be_ -> n_edges; \ - for (total_ = 0, local_ = 0; total_ < n_edges_; ++local_, ++total_) { \ - if (local_ == MAX_IN) { \ - be_ = be_ -> cont; \ - local_ = 0; \ - } \ - q = be_ -> edges[local_]; s \ - } \ - } \ - } while (0) - /* Ensure that p has a back_edges structure associated with it. */ static void ensure_struct(ptr_t p) { @@ -230,7 +206,7 @@ static void ensure_struct(ptr_t p) /* q are pointers to the object base, i.e. pointers to an oh. */ static void add_edge(ptr_t p, ptr_t q) { - ptr_t old_back_ptr = GET_OH_BG_PTR(q); + ptr_t pred = GET_OH_BG_PTR(q); back_edges * be, *be_cont; word i; @@ -240,7 +216,7 @@ static void add_edge(ptr_t p, ptr_t q) /* a pointer to a free list. Don't overwrite it! */ return; } - if (0 == old_back_ptr) { + if (NULL == pred) { static unsigned random_number = 13; # define GOT_LUCKY_NUMBER (((++random_number) & 0x7f) == 0) /* A not very random number we use to occasionally allocate a */ @@ -253,11 +229,37 @@ static void add_edge(ptr_t p, ptr_t q) if (GOT_LUCKY_NUMBER) ensure_struct(q); return; } + /* Check whether it was already in the list of predecessors. */ - FOR_EACH_PRED(pred, q, { if (p == pred) return; }); + { + back_edges *e = (back_edges *)((word)pred & ~FLAG_MANY); + word n_edges; + word total; + int local = 0; + + if (((word)pred & FLAG_MANY) != 0) { + n_edges = e -> n_edges; + } else if (pred != NULL && ((word)pred & 1) == 0) { + /* A misinterpreted freelist link. */ + n_edges = 1; + local = -1; + } else { + n_edges = 0; + } + for (total = 0; total < n_edges; ++total) { + if (local == MAX_IN) { + e = e -> cont; + local = 0; + } + if (local >= 0) + pred = e -> edges[local++]; + if (pred == p) + return; + } + } + ensure_struct(q); - old_back_ptr = GET_OH_BG_PTR(q); - be = (back_edges *)((word)old_back_ptr & ~FLAG_MANY); + be = (back_edges *)((word)GET_OH_BG_PTR(q) & ~FLAG_MANY); for (i = be -> n_edges, be_cont = be; i > MAX_IN; i -= MAX_IN) be_cont = be_cont -> cont; if (i == MAX_IN) { @@ -367,39 +369,68 @@ GC_INNER void GC_build_back_graph(void) static word backwards_height(ptr_t p) { word result; - ptr_t back_ptr = GET_OH_BG_PTR(p); + ptr_t pred = GET_OH_BG_PTR(p); back_edges *be; - if (0 == back_ptr) return 1; - if (!((word)back_ptr & FLAG_MANY)) { + if (NULL == pred) + return 1; + if (((word)pred & FLAG_MANY) == 0) { if (is_in_progress(p)) return 0; /* DFS back edge, i.e. we followed */ /* an edge to an object already */ /* on our stack: ignore */ push_in_progress(p); - result = backwards_height(back_ptr)+1; + result = backwards_height(pred) + 1; pop_in_progress(p); return result; } - be = (back_edges *)((word)back_ptr & ~FLAG_MANY); + be = (back_edges *)((word)pred & ~FLAG_MANY); if (be -> height >= 0 && be -> height_gc_no == (unsigned short)GC_gc_no) return be -> height; /* Ignore back edges in DFS */ if (be -> height == HEIGHT_IN_PROGRESS) return 0; result = (be -> height > 0? be -> height : 1); be -> height = HEIGHT_IN_PROGRESS; - FOR_EACH_PRED(q, p, { - word this_height; - if (GC_is_marked(q) && !(FLAG_MANY & (word)GET_OH_BG_PTR(p))) { - GC_COND_LOG_PRINTF("Found bogus pointer from %p to %p\n", - (void *)q, (void *)p); - /* Reachable object "points to" unreachable one. */ - /* Could be caused by our lax treatment of GC descriptors. */ - this_height = 1; - } else { - this_height = backwards_height(q); - } - if (this_height >= result) result = this_height + 1; - }); + + { + back_edges *e = be; + word n_edges; + word total; + int local = 0; + + if (((word)pred & FLAG_MANY) != 0) { + n_edges = e -> n_edges; + } else if (pred != NULL && ((word)pred & 1) == 0) { + /* A misinterpreted freelist link. */ + n_edges = 1; + local = -1; + } else { + n_edges = 0; + } + for (total = 0; total < n_edges; ++total) { + word this_height; + if (local == MAX_IN) { + e = e -> cont; + local = 0; + } + if (local >= 0) + pred = e -> edges[local++]; + + /* Execute the following once for each predecessor pred of p */ + /* in the points-to graph. */ + if (GC_is_marked(pred) && ((word)GET_OH_BG_PTR(p) & FLAG_MANY) == 0) { + GC_COND_LOG_PRINTF("Found bogus pointer from %p to %p\n", + (void *)pred, (void *)p); + /* Reachable object "points to" unreachable one. */ + /* Could be caused by our lax treatment of GC descriptors. */ + this_height = 1; + } else { + this_height = backwards_height(pred); + } + if (this_height >= result) + result = this_height + 1; + } + } + be -> height = result; be -> height_gc_no = (unsigned short)GC_gc_no; return result; @@ -431,17 +462,43 @@ static void update_max_height(ptr_t p, size_t n_bytes GC_ATTR_UNUSED, be = (back_edges *)((word)back_ptr & ~FLAG_MANY); if (be -> height != HEIGHT_UNKNOWN) p_height = be -> height; } - FOR_EACH_PRED(q, p, { - if (!GC_is_marked(q) && GC_HAS_DEBUG_INFO(q)) { - word q_height; - - q_height = backwards_height(q); - if (q_height > p_height) { - p_height = q_height; - p_deepest_obj = q; + + { + ptr_t pred = GET_OH_BG_PTR(p); + back_edges *e = (back_edges *)((word)pred & ~FLAG_MANY); + word n_edges; + word total; + int local = 0; + + if (((word)pred & FLAG_MANY) != 0) { + n_edges = e -> n_edges; + } else if (pred != NULL && ((word)pred & 1) == 0) { + /* A misinterpreted freelist link. */ + n_edges = 1; + local = -1; + } else { + n_edges = 0; + } + for (total = 0; total < n_edges; ++total) { + if (local == MAX_IN) { + e = e -> cont; + local = 0; + } + if (local >= 0) + pred = e -> edges[local++]; + + /* Execute the following once for each predecessor pred of p */ + /* in the points-to graph. */ + if (!GC_is_marked(pred) && GC_HAS_DEBUG_INFO(pred)) { + word this_height = backwards_height(pred); + if (this_height > p_height) { + p_height = this_height; + p_deepest_obj = pred; + } } } - }); + } + if (p_height > 0) { /* Remember the height for next time. */ if (be == 0) { |