| 158 | } |
| 159 | |
| 160 | void TracePC::UpdateObservedPCs() { |
| 161 | std::vector<uintptr_t> CoveredFuncs; |
| 162 | auto ObservePC = [&](const PCTableEntry *TE) { |
| 163 | if (ObservedPCs.insert(TE).second && DoPrintNewPCs) { |
| 164 | PrintPC("\tNEW_PC: %p %F %L", "\tNEW_PC: %p", |
| 165 | GetNextInstructionPc(TE->PC)); |
| 166 | Printf("\n"); |
| 167 | } |
| 168 | }; |
| 169 | |
| 170 | auto Observe = [&](const PCTableEntry *TE) { |
| 171 | if (PcIsFuncEntry(TE)) |
| 172 | if (++ObservedFuncs[TE->PC] == 1 && NumPrintNewFuncs) |
| 173 | CoveredFuncs.push_back(TE->PC); |
| 174 | ObservePC(TE); |
| 175 | }; |
| 176 | |
| 177 | if (NumPCsInPCTables) { |
| 178 | if (NumInline8bitCounters == NumPCsInPCTables) { |
| 179 | for (size_t i = 0; i < NumModules; i++) { |
| 180 | auto &M = Modules[i]; |
| 181 | assert(M.Size() == |
| 182 | (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start)); |
| 183 | for (size_t r = 0; r < M.NumRegions; r++) { |
| 184 | auto &R = M.Regions[r]; |
| 185 | if (!R.Enabled) continue; |
| 186 | for (uint8_t *P = R.Start; P < R.Stop; P++) |
| 187 | if (*P) |
| 188 | Observe(&ModulePCTable[i].Start[M.Idx(P)]); |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | for (size_t i = 0, N = Min(CoveredFuncs.size(), NumPrintNewFuncs); i < N; |
| 195 | i++) { |
| 196 | Printf("\tNEW_FUNC[%zd/%zd]: ", i + 1, CoveredFuncs.size()); |
| 197 | PrintPC("%p %F %L", "%p", GetNextInstructionPc(CoveredFuncs[i])); |
| 198 | Printf("\n"); |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | uintptr_t TracePC::PCTableEntryIdx(const PCTableEntry *TE) { |
| 203 | size_t TotalTEs = 0; |
no test coverage detected