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