hschumann2/TempleOS-Source-Code
0847
1 2#help_index "Debugging/Heap;Memory/Debugging"3#help_file "::/Doc/HeapDbg"4 5#define HL_CALLER_DEPTH 5 //Feel free to change this.6#define HL_HASH_SIZE 0x10007 8class CHeapLog9{10 CHeapLog *next,*last;11 union {12 U8 *addr;13 I64 size;14 }15 I64 cnt;16 U8 *caller[HL_CALLER_DEPTH];17};18 19class CHeapLogHash20{21 CHeapLog *next,*last;22};23 24CHeapCtrl *heaplog_hc_watched,*heaplog_hc=NULL;25CHeapLogHash *heaplog_head=NULL;26 27U0 HeapLogMAlloc(U8 *addr)28{29 CHeapLog *tmphl;30 I64 i;31 if (MHeapCtrl(addr)==heaplog_hc_watched) {32 tmphl=MAlloc(sizeof(CHeapLog),heaplog_hc);33 tmphl->addr=addr;34 for (i=0;i<HL_CALLER_DEPTH;i++)35 tmphl->caller[i]=Caller(i+2);36 i=addr>>3 &(HL_HASH_SIZE-1);37 PUSHFD38 CLI39 while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))40 PAUSE41 QueIns(tmphl,heaplog_head[i].last);42 LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);43 POPFD44 }45}46 47U0 HeapLogFree(U8 *addr)48{49 I64 i;50 CHeapLog *tmphl;51 if (!addr) return;52 if (MHeapCtrl(addr)==heaplog_hc_watched) {53 i=addr>>3 &(HL_HASH_SIZE-1);54 PUSHFD55 CLI56 while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))57 PAUSE58 tmphl=heaplog_head[i].next;59 while (tmphl!=&heaplog_head[i]) {60 if (addr==tmphl->addr) {61 QueRem(tmphl);62 LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);63 POPFD64 Free(tmphl);65 return;66 }67 tmphl=tmphl->next;68 }69 LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);70 POPFD71 }72}73 74public Bool HeapLog(Bool val=ON,CTask *task=NULL)75{//Turn on. Collect data. Call HeapLogAddrRep() or HeapLogSizeRep().76 I64 i;77 if (val) {78 if (Bt(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {79 "HeapLog Already Active\n";80 return TRUE;81 } else {82 if (!task) task=Fs;83 if (TaskValidate(task))84 heaplog_hc_watched=task->data_heap;85 else86 heaplog_hc_watched=task;//Actually, not a task, must be a HeapCtrl.87 PUSHFD88 CLI89 while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))90 PAUSE91 heaplog_hc=HeapCtrlInit(,,sys_data_bp);92 ext[EXT_HEAPLOG_MALLOC]=&HeapLogMAlloc;93 ext[EXT_HEAPLOG_FREE]=&HeapLogFree;94 heaplog_head=MAlloc(sizeof(CHeapLogHash)*HL_HASH_SIZE,heaplog_hc);95 for (i=0;i<HL_HASH_SIZE;i++)96 QueInit(&heaplog_head[i]);97 LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);98 POPFD99 LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);100 return FALSE;101 }102 } else {103 if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {104 "HeapLog Not Active\n";105 return FALSE;106 } else {107 HeapCtrlDel(heaplog_hc);108 heaplog_head=heaplog_hc=NULL;109 ext[EXT_HEAPLOG_MALLOC]=NULL;110 ext[EXT_HEAPLOG_FREE]=NULL;111 return TRUE;112 }113 }114}115 116public U0 HeapLogAddrRep(Bool leave_it=OFF)117{//Call HeapLog() first and collect data.118 I64 i,j,total=0;119 CHeapLog *tmphl,hl;120 if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {121 "HeapLog Not Active\n";122 return;123 }124 "$WW,0$";125 while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))126 PAUSE127 for (i=0;i<HL_HASH_SIZE;i++) {128 tmphl=heaplog_head[i].next;129 while (tmphl!=&heaplog_head[i]) {130//Take snapshot in case modified. (while we work)131 MemCpy(&hl,tmphl,sizeof(CHeapLog));132 "$PURPLE$%08X$FG$ %08X",MSize(hl.addr),hl.addr;133 for (j=0;j<HL_CALLER_DEPTH;j++)134 " %P",hl.caller[j];135 '\n';136 total+=MSize(hl.addr);137 tmphl=hl.next;138 }139 }140 LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);141 "\n$LTRED$Total:%08X$FG$\n",total;142 LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);143 if (!leave_it)144 HeapLog(OFF);145}146 147public U0 HeapLogSizeRep(Bool leave_it=OFF)148{//Call HeapLog() first and collect data.149 I64 i,j,k,total=0;150 CHeapLog *tmphla,hla,*tmphls,*tmphls1;151 CHeapLogHash *size_head;152 if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {153 "HeapLog Not Active\n";154 return;155 }156 157 size_head=MAlloc(sizeof(CHeapLogHash)*HL_HASH_SIZE,heaplog_hc);158 for (i=0;i<HL_HASH_SIZE;i++)159 QueInit(&size_head[i]);160 161 "$WW,0$";162 while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))163 PAUSE164 for (i=0;i<HL_HASH_SIZE;i++) {165 tmphla=heaplog_head[i].next;166 while (tmphla!=&heaplog_head[i]) {167//Take snapshot in case modified. (while we work)168 MemCpy(&hla,tmphla,sizeof(CHeapLog));169 k=(MSize(hla.addr)>>3+hla.caller[0])&(HL_HASH_SIZE-1);170 tmphls=size_head[k].next;171 while (tmphls!=&size_head[k]) {172 if (MSize(hla.addr)==tmphls->size) {173 for (j=0;j<HL_CALLER_DEPTH;j++)174 if (hla.caller[j]!=tmphls->caller[j])175 goto hl_next;176 tmphls->cnt++;177 goto hl_found;178 }179hl_next:180 tmphls=tmphls->next;181 }182 tmphls=MAlloc(sizeof(CHeapLog),heaplog_hc);183 MemCpy(tmphls,&hla,sizeof(CHeapLog));184 tmphls->cnt=1;185 tmphls->size=MSize(hla.addr);186 QueIns(tmphls,size_head[k].last);187hl_found:188 tmphla=hla.next;189 }190 }191 LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);192 193 for (i=0;i<HL_HASH_SIZE;i++) {194 tmphls=size_head[i].next;195 while (tmphls!=&size_head[i]) {196 tmphls1=tmphls->next;197 "%08X*%08X=%08X",tmphls->size,tmphls->cnt,tmphls->size*tmphls->cnt;198 for (j=0;j<HL_CALLER_DEPTH;j++)199 " %P",tmphls->caller[j];200 '\n';201 total+=tmphls->size*tmphls->cnt;202 Free(tmphls);203 tmphls=tmphls1;204 }205 }206 Free(size_head);207 208 "\n$LTRED$Total:%08X$FG$\n",total;209 LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);210 if (!leave_it)211 HeapLog(OFF);212}213 