def update(self): addr_ivals = alloc_state.addr_ivals_sorted() if not addr_ivals: return # Use the first address being tracked as the base of the image baseva = addr_ivals[0].begin # Just how big is this image, anyway? # Assume 16-byte alignment, so one pixel per 16 bytes. topva = baseva + self._geom[0] * self._geom[1] * 16 # OK, now slice, so we don't spend all our time considering things # that are off the map anyway. addr_ivals = alloc_state.addr_ivals_sorted(begin=baseva, end=topva) now = run.timestamp_ns img = Image.new('RGB', self._geom) # Extract Z order from image width zo = img.width.bit_length() << 1 renderSpansZ(img, zo, (((i.begin - baseva) >> 4, (i.end - i.begin) >> 4, self.st2color[i.value]) for i in addr_ivals)) img.save("%s/%s.png" % (self._dir, now))
def render(self, img): from common.render import renderSpansZ from PIL import ImageDraw zo = img.width.bit_length() << 1 basebix = next(loc for (loc, _, _) in self._bix2state) # Paint most of the buckets; exclude AHWM since that's big renderSpansZ( img, zo, ((loc - basebix, sz, bst2color[st]) for (loc, sz, st) in self._bix2state if st != BuckSt.AHWM)) # Paint over small WAIT buckets with some occupancy information renderSpansZ(img, zo, ((bix - basebix, 1, self.occshade(self._bix2szbm[bix])) for (loc, sz, st) in self._bix2state if st == BuckSt.WAIT for bix in range(loc, loc + sz) if self._bix2szbm.get(bix, None) is not None if self._issmall(self._bix2szbm[bix][0]))) # Paint over the largest revokable span (which may hide some TIDY # blocks, but that's fine) brss = self._find_largest_revokable_spans(n=1) if brss != [] and brss[0][1] is not None: renderSpansZ(img, zo, [(brss[0][1] - basebix, brss[0][2], cBRS)]) # Paint over the oldest JUNK span oldestj = self._junklru.first if oldestj is not None: (qbix, qsz, _) = self._bix2state.get(oldestj.value[0], coalesce_with_values=st_tj) renderSpansZ(img, zo, [(qbix - basebix, qsz, cOJS)])
def rendszbm(bio, ap, sz, bm): ep = self._maxoix(sz) if ap is None: ap = ep for oix in range(0, ap): renderSpansZ( img, zo, [(expand(bio, oix * sz), expand(0, sz * (oix + 1) - 1) - expand(0, sz * oix), bst2color[BuckSt.JUNK] if bm & 1 == 1 else bst2color[BuckSt.WAIT])]) bm >>= 1 renderSpansZ(img, zo, [(expand(bio, ap * sz), expand(0, sz * ep) - expand(0, sz * ap), bst2color[BuckSt.TIDY])])
def render(self, img): from common.render import renderSpansZ from PIL import ImageDraw sst2color = { SegSt.TIDY: 0xFFFFFF, SegSt.WAIT: 0x00FF00, SegSt.JUNK: 0xFF0000, } baseva = self._basepg * 2**self._pagelog zo = img.width.bit_length() << 1 renderSpansZ( img, zo, (((loc - baseva) >> self._alignlog, sz >> self._alignlog, sst2color[st]) for (loc, sz, st) in self._eva2sst.irange(baseva, self._wildern))) # Paint over the oldest JUNK span oldestj = self._junklru.first if oldestj is not None: (qb, qsz) = oldestj.value qb -= baseva renderSpansZ( img, zo, [(qb >> self._alignlog, qsz >> self._alignlog, 0xFF00FF)]) # Paint over the oldest TIDY span oldestt = self._tidylst.eldest() if oldestt is not None: (qb, qsz) = oldestt qb -= baseva renderSpansZ( img, zo, [(qb >> self._alignlog, qsz >> self._alignlog, 0x00FFFF)])
def _render_expanded(self, img): from common.render import renderSpansZ from PIL import ImageDraw zo = img.width.bit_length() << 1 basebix = next(loc for (loc, _, _) in self._bix2state) # bix and offset to pixel index def expand(bix, off): return (bix * 2**self._bucklog + off + 15) >> 4 # render a bitmap bucket at block index offset (relative to basebix) def rendszbm(bio, ap, sz, bm): ep = self._maxoix(sz) if ap is None: ap = ep for oix in range(0, ap): renderSpansZ( img, zo, [(expand(bio, oix * sz), expand(0, sz * (oix + 1) - 1) - expand(0, sz * oix), bst2color[BuckSt.JUNK] if bm & 1 == 1 else bst2color[BuckSt.WAIT])]) bm >>= 1 renderSpansZ(img, zo, [(expand(bio, ap * sz), expand(0, sz * ep) - expand(0, sz * ap), bst2color[BuckSt.TIDY])]) # Paint most of the buckets; exclude AHWM since that's big for (loc, sz, st) in self._bix2state: # skip AHWM if st == BuckSt.AHWM: continue # JUNK, and TIDY are entirely uniform elif st == BuckSt.JUNK: renderSpansZ( img, zo, [(expand(loc - basebix, 0), expand(sz, 0), bst2color[st])]) elif st == BuckSt.TIDY: renderSpansZ( img, zo, [(expand(loc - basebix, 0), expand(sz, 0), bst2color[st])]) # BUMP states are backed at every bix with a bitmap elif st == BuckSt.BUMP: for bix in range(loc, loc + sz): (asz, bm) = self._bix2szbm[bix] rendszbm(bix - basebix, self._szbix2ap[asz].get(bix, None), asz, bm) # WAIT states are complicated: they are either backed with a bitmap # or by a large value, indicating the uniform occupancy of one or # more buckets. We don't have better resolution than that, so just # render those uniformly. elif st == BuckSt.WAIT: bix = loc while bix < loc + sz: (asz, bm) = self._bix2szbm[bix] if self._issmall(asz): # bitmap, one bucket rendszbm(bix - basebix, self._szbix2ap[asz].get(bix, None), asz, bm) bix += 1 else: # large object nsz = self._sz2nbucks(asz) renderSpansZ(img, zo, [(expand(bix - basebix, 0), expand( nsz, 0), bst2color[st])]) bix += nsz