| 185 | } |
| 186 | |
| 187 | void DecodedOpCache::iterateOps(U32 address, U32 len, OpCacheCallback callback, void* pData) { |
| 188 | U32 previousOpAddress = 0; |
| 189 | DecodedOpPageCache* prevPage = nullptr; |
| 190 | DecodedOp* previousOp = getPreviousOp(address, &previousOpAddress, &prevPage); |
| 191 | |
| 192 | if (previousOp) { |
| 193 | // does previousOp span into address |
| 194 | if (previousOpAddress + previousOp->len > address) { |
| 195 | callback(previousOpAddress, previousOp, pData); |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | while (len) { |
| 200 | U32 pageIndex = address >> K_PAGE_SHIFT; |
| 201 | U32 offset = address & K_PAGE_MASK; |
| 202 | U32 todo = len; |
| 203 | if (todo > K_PAGE_SIZE - offset) { |
| 204 | todo = K_PAGE_SIZE - offset; |
| 205 | } |
| 206 | DecodedOpPageCache* page = getPageCache(pageIndex, false); |
| 207 | if (page) { |
| 208 | for (U32 i = offset; i < offset + todo; i++) { |
| 209 | if (page->ops[i]) { |
| 210 | callback((pageIndex << K_PAGE_SHIFT) + i, page->ops[i], pData); |
| 211 | } |
| 212 | } |
| 213 | } |
| 214 | address += todo; |
| 215 | len -= todo; |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | void DecodedOpCache::remove(U32 address, U32 len, bool becauseOfWrite) { |
| 220 | DecodedOp* prev = getPreviousOpAndRemoveIfOverlapping(address); |