| 261 | |
| 262 | private: |
| 263 | void CacheBlockMapping(uint64_t Address, uintptr_t HostCode) { |
| 264 | // Do L1 |
| 265 | auto& L1Entry = reinterpret_cast<LookupCacheEntry*>(L1Pointer)[Address & L1_ENTRIES_MASK]; |
| 266 | L1Entry.GuestCode = Address; |
| 267 | L1Entry.HostCode = HostCode; |
| 268 | |
| 269 | // Do ful map |
| 270 | auto FullAddress = Address; |
| 271 | Address = Address & (VirtualMemSize - 1); |
| 272 | |
| 273 | uint64_t PageOffset = Address & (0x0FFF); |
| 274 | Address >>= 12; |
| 275 | uintptr_t* Pointers = reinterpret_cast<uintptr_t*>(PagePointer); |
| 276 | uint64_t LocalPagePointer = Pointers[Address]; |
| 277 | if (!LocalPagePointer) { |
| 278 | // We don't have a page pointer for this address |
| 279 | // Allocate one now if we can |
| 280 | uintptr_t NewPageBacking = AllocateBackingForPage(); |
| 281 | if (!NewPageBacking) { |
| 282 | // Couldn't allocate, clear L2 and retry |
| 283 | ClearL2Cache(); |
| 284 | CacheBlockMapping(Address, HostCode); |
| 285 | return; |
| 286 | } |
| 287 | Pointers[Address] = NewPageBacking; |
| 288 | LocalPagePointer = NewPageBacking; |
| 289 | } |
| 290 | |
| 291 | // Add the new pointer to the page block |
| 292 | auto BlockPointers = reinterpret_cast<LookupCacheEntry*>(LocalPagePointer); |
| 293 | |
| 294 | // This silently replaces existing mappings |
| 295 | BlockPointers[PageOffset].GuestCode = FullAddress; |
| 296 | BlockPointers[PageOffset].HostCode = HostCode; |
| 297 | } |
| 298 | |
| 299 | uintptr_t AllocateBackingForPage() { |
| 300 | uintptr_t NewBase = AllocateOffset; |
nothing calls this directly
no outgoing calls
no test coverage detected