static int uncached_find_save_locs (struct cursor *c) { struct ia64_script script; int ret = 0; if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0) return ret; script_init (&script, c->ip); if ((ret = build_script (c, &script)) < 0) { if (ret != -UNW_ESTOPUNWIND) Dprintf ("%s: failed to build unwind script for ip %lx\n", __FUNCTION__, (long) c->ip); return ret; } return run_script (&script, c); }
/* Report the differences of two files. */ void diff_2_files (struct file_data filevec[], add_change_callback callback, void* userData) { int diags; int i; /* Allocate vectors for the results of comparison: a flag for each line of each file, saying whether that line is an insertion or deletion. Allocate an extra element, always zero, at each end of each vector. */ size_t s = filevec[0].buffered_lines + filevec[1].buffered_lines + 4; filevec[0].changed_flag = (char *)malloc (s); bzero (filevec[0].changed_flag, s); filevec[0].changed_flag++; filevec[1].changed_flag = filevec[0].changed_flag + filevec[0].buffered_lines + 2; /* Some lines are obviously insertions or deletions because they don't match anything. Detect them now, and avoid even thinking about them in the main comparison algorithm. */ discard_confusing_lines (filevec); /* Now do the main comparison algorithm, considering just the undiscarded lines. */ xvec = filevec[0].undiscarded; yvec = filevec[1].undiscarded; diags = filevec[0].nondiscarded_lines + filevec[1].nondiscarded_lines + 3; fdiag = (int *) malloc (diags * (2 * sizeof (int))); bdiag = fdiag + diags; fdiag += filevec[1].nondiscarded_lines + 1; bdiag += filevec[1].nondiscarded_lines + 1; /* Set TOO_EXPENSIVE to be approximate square root of input size, bounded below by 256. */ too_expensive = 1; for (i = filevec[0].nondiscarded_lines + filevec[1].nondiscarded_lines; i != 0; i >>= 2) too_expensive <<= 1; too_expensive = max (256, too_expensive); files[0] = filevec[0]; files[1] = filevec[1]; compareseq (0, filevec[0].nondiscarded_lines, 0, filevec[1].nondiscarded_lines, no_discards); free (fdiag - (filevec[1].nondiscarded_lines + 1)); /* Modify the results slightly to make them prettier in cases where that can validly be done. */ shift_boundaries (filevec); /* Get the results of comparison in the form of a chain of `struct change's -- an edit script. */ build_script (filevec, callback, userData); free (filevec[0].undiscarded); free (filevec[0].changed_flag - 1); }
HIDDEN int ia64_find_save_locs (struct cursor *c) { struct ia64_script_cache *cache = NULL; struct ia64_script *script = NULL; intrmask_t saved_mask; int ret = 0; if (c->as->caching_policy == UNW_CACHE_NONE) return uncached_find_save_locs (c); cache = get_script_cache (c->as, &saved_mask); if (!cache) { Debug (1, "contention on script-cache; doing uncached lookup\n"); return uncached_find_save_locs (c); } { script = script_lookup (cache, c); Debug (8, "ip %lx %s in script cache\n", (long) c->ip, script ? "hit" : "missed"); if (!script || (script->count == 0 && !script->pi.unwind_info)) { if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0) goto out; } if (!script) { script = script_new (cache, c->ip); if (!script) { Dprintf ("%s: failed to create unwind script\n", __FUNCTION__); ret = -UNW_EUNSPEC; goto out; } } cache->buckets[c->prev_script].hint = script - cache->buckets; if (script->count == 0) ret = build_script (c, script); assert (script->count > 0); c->hint = script->hint; c->prev_script = script - cache->buckets; if (ret < 0) { if (ret != -UNW_ESTOPUNWIND) Dprintf ("%s: failed to locate/build unwind script for ip %lx\n", __FUNCTION__, (long) c->ip); goto out; } ret = run_script (script, c); } out: put_script_cache (c->as, cache, &saved_mask); return ret; }