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