Merge pull request #18 from djipi/release/R4
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / heapallocatorbrowser.cpp
... / ...
CommitLineData
1//\r
2// heapallocatorbrowser.cpp: Memory heap allocation\r
3//\r
4// by Jean-Paul Mari\r
5//\r
6// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
7//\r
8// Who When (MM/DD/YY) What\r
9// --- --------------- -----------------------------------------------------------\r
10// JPM 01/08/2017 Created this file\r
11// JPM Sept./2018 Support of the DRAM size limit option, use definitions for error instead of hard values, detect if heap allocation shares space with SP (Stack), added a status bar and better status report, and set information values in a tab\r
12// JPM 07/04/2019 Fix the support of the DRAM size limit option\r
13//\r
14\r
15// STILL TO DO:\r
16// To have filters\r
17// To set the information display at the right\r
18// Feature to list the pointer(s) in the code using the allocation\r
19//\r
20\r
21\r
22#include "settings.h"\r
23#include "debugger/heapallocatorbrowser.h"\r
24#include "memory.h"\r
25#include "debugger/DBGManager.h"\r
26#include "m68000/m68kinterface.h"\r
27\r
28\r
29// \r
30HeapAllocatorBrowserWindow::HeapAllocatorBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r
31layout(new QVBoxLayout),\r
32#ifdef HA_LAYOUTTEXTS\r
33text(new QTextBrowser),\r
34#else\r
35TableView(new QTableView),\r
36model(new QStandardItemModel),\r
37proxyModel(new QSortFilterProxyModel),\r
38#endif\r
39statusbar(new QStatusBar),\r
40Adr(0)\r
41{\r
42 setWindowTitle(tr("Heap Allocation"));\r
43\r
44 // Set the font\r
45 QFont fixedFont("Lucida Console", 8, QFont::Normal);\r
46 fixedFont.setStyleHint(QFont::TypeWriter);\r
47\r
48#ifdef HA_LAYOUTTEXTS\r
49 // Set original layout\r
50 text->setFont(fixedFont);\r
51 layout->addWidget(text);\r
52#else\r
53 // Set the new layout with proper identation and readibility\r
54 model->setColumnCount(3);\r
55 model->setHeaderData(0, Qt::Horizontal, QObject::tr("Pointer"));\r
56 model->setHeaderData(1, Qt::Horizontal, QObject::tr("Size"));\r
57 model->setHeaderData(2, Qt::Horizontal, QObject::tr("Use"));\r
58 // Information table\r
59 TableView->setModel(model);\r
60 TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);\r
61 TableView->setShowGrid(0);\r
62 TableView->setFont(fixedFont);\r
63 TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());\r
64 TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);\r
65 layout->addWidget(TableView);\r
66 // Set filter\r
67 proxyModel->setSourceModel(model);\r
68 QRegExp regExp("*", Qt::CaseInsensitive, QRegExp::Wildcard);\r
69 proxyModel->setFilterRegExp(regExp);\r
70#endif\r
71\r
72 // Status bar\r
73 layout->addWidget(statusbar);\r
74 setLayout(layout);\r
75}\r
76\r
77\r
78//\r
79HeapAllocatorBrowserWindow::~HeapAllocatorBrowserWindow(void)\r
80{\r
81}\r
82\r
83\r
84//\r
85void HeapAllocatorBrowserWindow::RefreshContents(void)\r
86{\r
87#ifdef HA_LAYOUTTEXTS\r
88 char string[1024] = { 0 };\r
89 QString HA;\r
90#endif\r
91 char msg[1024];\r
92 QString MSG;\r
93 size_t Adr68K, Adr68KHigh;\r
94 size_t Error = HA_NOERROR;\r
95 size_t NbBlocks, TotalBytesUsed;\r
96 HeapAllocation HeapAllocation;\r
97\r
98 if (isVisible())\r
99 {\r
100 if (Adr68K = Adr)\r
101 {\r
102 Adr68KHigh = TotalBytesUsed = NbBlocks = 0;\r
103#ifndef HA_LAYOUTTEXTS\r
104 model->setRowCount(0);\r
105#endif\r
106 do\r
107 {\r
108 if ((Adr68K >= 0x4000) && (Adr68K < vjs.DRAM_size))\r
109 {\r
110 if (Adr68K < m68k_get_reg(NULL, M68K_REG_SP))\r
111 {\r
112 memcpy(&HeapAllocation, &jaguarMainRAM[Adr68K], sizeof(HeapAllocation));\r
113\r
114 if (HeapAllocation.size = ((HeapAllocation.size & 0xff) << 24) + ((HeapAllocation.size & 0xff00) << 8) + ((HeapAllocation.size & 0xff0000) >> 8) + ((HeapAllocation.size & 0xff000000) >> 24))\r
115 {\r
116 if (HeapAllocation.size <= (vjs.DRAM_size - 0x4000))\r
117 {\r
118 if ((HeapAllocation.used = ((HeapAllocation.used & 0xff) << 8) + ((HeapAllocation.used & 0xff00) >> 8)) <= 1)\r
119 {\r
120 HeapAllocation.nextalloc = ((HeapAllocation.nextalloc & 0xff) << 24) + ((HeapAllocation.nextalloc & 0xff00) << 8) + ((HeapAllocation.nextalloc & 0xff0000) >> 8) + ((HeapAllocation.nextalloc & 0xff000000) >> 24);\r
121\r
122 if ((HeapAllocation.nextalloc >= 0x4000) && (HeapAllocation.nextalloc < vjs.DRAM_size))\r
123 {\r
124#ifdef HA_LAYOUTTEXTS\r
125 if (NbBlocks++)\r
126 {\r
127 HA += QString("<br>");\r
128 }\r
129 sprintf(string, "0x%06x | 0x%0x (%zi) | %s | 0x%06x", Adr68K, HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.used ? "Allocated" : "Free", HeapAllocation.nextalloc);\r
130 HA += QString(string);\r
131#else\r
132 model->insertRow(NbBlocks);\r
133 model->setItem(NbBlocks, 0, new QStandardItem(QString("0x%1").arg(Adr68K, 6, 16, QChar('0'))));\r
134 model->setItem(NbBlocks, 1, new QStandardItem(QString("%1").arg((HeapAllocation.size - sizeof(HeapAllocation)))));\r
135 model->setItem(NbBlocks++, 2, new QStandardItem(QString("%1").arg(HeapAllocation.used ? "Allocated" : "Free")));\r
136#endif\r
137 TotalBytesUsed += HeapAllocation.size;\r
138\r
139 if ((Adr68K = HeapAllocation.nextalloc) > Adr68KHigh)\r
140 {\r
141 Adr68KHigh = Adr68K;\r
142 }\r
143 }\r
144 else\r
145 {\r
146 sprintf(msg, "Unable to determine the next memory allocation");\r
147 Error = HA_UNABLENEXTMEMORYALLOC;\r
148 }\r
149 }\r
150 else\r
151 {\r
152 sprintf(msg, "Unable to determine if the allocated memory is used or not");\r
153 Error = HA_UNABLEALLOCATEMEMORYUSAGE;\r
154 }\r
155 }\r
156 else\r
157 {\r
158 sprintf(msg, "Memory bloc size has a problem");\r
159 Error = HA_MEMORYBLOCKSIZEPROBLEM;\r
160 }\r
161 }\r
162 else\r
163 {\r
164 sprintf(msg, "%i blocks | %i bytes in blocks | %i contiguous bytes free", NbBlocks, TotalBytesUsed, (m68k_get_reg(NULL, M68K_REG_SP) - Adr68KHigh));\r
165 }\r
166 }\r
167 else\r
168 {\r
169 sprintf(msg, "Memory allocations and Stack have reached the same space");\r
170 Error = HA_HAANDSPSHARESPACE;\r
171 }\r
172 }\r
173 else\r
174 {\r
175 sprintf(msg, "Memory allocations may have a problem");\r
176 Error = HA_MEMORYALLOCATIONPROBLEM;\r
177 }\r
178 }\r
179 while (HeapAllocation.size && !Error);\r
180\r
181 MSG += QString(msg);\r
182 }\r
183 else\r
184 {\r
185 if (Adr = DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))\r
186 {\r
187 if (Adr68K = DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))\r
188 {\r
189 if (!(Adr68K = (jaguarMainRAM[Adr68K] << 24) + (jaguarMainRAM[Adr68K + 1] << 16) + (jaguarMainRAM[Adr68K + 2] << 8) + (jaguarMainRAM[Adr68K + 3])) || ((Adr68K < 0x4000) || (Adr68K >= vjs.DRAM_size)))\r
190 {\r
191 sprintf(msg, "Memory allocator not yet initialised");\r
192 Error = HA_MEMORYALLOCATORNOTINITIALIZED;\r
193 Adr = 0;\r
194 }\r
195 else\r
196 {\r
197 return RefreshContents();\r
198 }\r
199 }\r
200 else\r
201 {\r
202 sprintf(msg, "Memory allocator is not compatible");\r
203 Error = HA_MEMORYALLOCATORNOTCOMPATIBLE;\r
204 Adr = 0;\r
205 }\r
206 }\r
207 else\r
208 {\r
209 sprintf(msg, "Memory allocator doesn't exist");\r
210 Error = HA_MEMORYALLOCATORNOTEXIST;\r
211 }\r
212#ifdef HA_LAYOUTTEXTS\r
213 HA += QString("");\r
214#else\r
215 model->setRowCount(0);\r
216#endif\r
217 MSG += QString(msg);\r
218 }\r
219\r
220 // Display status bar\r
221 if (Error)\r
222 {\r
223 if ((Error & HA_WARNING))\r
224 {\r
225 statusbar->setStyleSheet("background-color: lightyellow; font: bold");\r
226 }\r
227 else\r
228 {\r
229 statusbar->setStyleSheet("background-color: tomato; font: bold");\r
230 }\r
231 }\r
232 else\r
233 {\r
234 statusbar->setStyleSheet("background-color: lightgreen; font: bold");\r
235 }\r
236 statusbar->showMessage(MSG);\r
237\r
238#ifdef HA_LAYOUTTEXTS\r
239 // Display values\r
240 text->clear();\r
241 text->setText(HA);\r
242#endif\r
243 }\r
244}\r
245\r
246\r
247// \r
248void HeapAllocatorBrowserWindow::Reset(void)\r
249{\r
250 size_t Adr68K;\r
251\r
252 if (DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))\r
253 {\r
254 if (Adr68K = DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))\r
255 {\r
256 jaguarMainRAM[Adr68K] = jaguarMainRAM[Adr68K + 1] = jaguarMainRAM[Adr68K + 2] = jaguarMainRAM[Adr68K + 3] = 0;\r
257 Adr = 0;\r
258 }\r
259 }\r
260}\r
261\r
262\r
263// \r
264void HeapAllocatorBrowserWindow::keyPressEvent(QKeyEvent * e)\r
265{\r
266 if (e->key() == Qt::Key_Escape)\r
267 {\r
268 hide();\r
269 }\r
270}\r
271\r