2 // heapallocatorbrowser.cpp: Memory heap allocation
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9 // --- ---------- -----------------------------------------------------------
10 // JPM 01/08/2017 Created this file
11 // JPM 09/05/2018 Support of the DRAM size limit option
12 // JPM 09/05/2018 Use definitions for error instead of hard values
13 // JPM 09/05/2018 Detect if heap allocation shares space with SP (Stack)
14 // JPM 09/06/2018 Added a status bar and better status report
15 // JPM 09/07/2018 Set information values in a tab
20 // To set the information display at the right
21 // Feature to list the pointer(s) in the code using the allocation
26 #include "debugger/heapallocatorbrowser.h"
28 #include "debugger/DBGManager.h"
29 #include "m68000/m68kinterface.h"
33 HeapAllocatorBrowserWindow::HeapAllocatorBrowserWindow(QWidget
* parent
/*= 0*/) : QWidget(parent
, Qt::Dialog
),
34 layout(new QVBoxLayout
),
36 text(new QTextBrowser
),
38 TableView(new QTableView
),
39 model(new QStandardItemModel
),
40 proxyModel(new QSortFilterProxyModel
),
42 statusbar(new QStatusBar
),
45 setWindowTitle(tr("Heap Allocation"));
48 QFont
fixedFont("Lucida Console", 8, QFont::Normal
);
49 fixedFont
.setStyleHint(QFont::TypeWriter
);
52 // Set original layout
53 text
->setFont(fixedFont
);
54 layout
->addWidget(text
);
56 // Set the new layout with proper identation and readibility
57 model
->setColumnCount(3);
58 model
->setHeaderData(0, Qt::Horizontal
, QObject::tr("Pointer"));
59 model
->setHeaderData(1, Qt::Horizontal
, QObject::tr("Size"));
60 model
->setHeaderData(2, Qt::Horizontal
, QObject::tr("Use"));
62 TableView
->setModel(model
);
63 TableView
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
64 TableView
->setShowGrid(0);
65 TableView
->setFont(fixedFont
);
66 TableView
->verticalHeader()->setDefaultSectionSize(TableView
->verticalHeader()->minimumSectionSize());
67 TableView
->verticalHeader()->setDefaultAlignment(Qt::AlignRight
);
68 layout
->addWidget(TableView
);
70 proxyModel
->setSourceModel(model
);
71 QRegExp
regExp("*", Qt::CaseInsensitive
, QRegExp::Wildcard
);
72 proxyModel
->setFilterRegExp(regExp
);
76 layout
->addWidget(statusbar
);
82 HeapAllocatorBrowserWindow::~HeapAllocatorBrowserWindow(void)
88 void HeapAllocatorBrowserWindow::RefreshContents(void)
91 char string
[1024] = { 0 };
96 size_t Adr68K
, Adr68KHigh
;
97 size_t Error
= HA_NOERROR
;
98 size_t NbBlocks
, TotalBytesUsed
;
99 HeapAllocation HeapAllocation
;
105 Adr68KHigh
= TotalBytesUsed
= NbBlocks
= 0;
106 #ifndef HA_LAYOUTTEXTS
107 model
->setRowCount(0);
111 if ((Adr68K
>= 0x4000) && (Adr68K
< vjs
.DRAM_size
))
113 if (Adr68K
< m68k_get_reg(NULL
, M68K_REG_SP
))
115 memcpy(&HeapAllocation
, &jaguarMainRAM
[Adr68K
], sizeof(HeapAllocation
));
117 if (HeapAllocation
.size
= ((HeapAllocation
.size
& 0xff) << 24) + ((HeapAllocation
.size
& 0xff00) << 8) + ((HeapAllocation
.size
& 0xff0000) >> 8) + ((HeapAllocation
.size
& 0xff000000) >> 24))
119 if (HeapAllocation
.size
<= (vjs
.DRAM_size
- 0x4000))
121 if ((HeapAllocation
.used
= ((HeapAllocation
.used
& 0xff) << 8) + ((HeapAllocation
.used
& 0xff00) >> 8)) <= 1)
123 HeapAllocation
.nextalloc
= ((HeapAllocation
.nextalloc
& 0xff) << 24) + ((HeapAllocation
.nextalloc
& 0xff00) << 8) + ((HeapAllocation
.nextalloc
& 0xff0000) >> 8) + ((HeapAllocation
.nextalloc
& 0xff000000) >> 24);
125 if ((HeapAllocation
.nextalloc
>= 0x4000) && (HeapAllocation
.nextalloc
< vjs
.DRAM_size
))
127 #ifdef HA_LAYOUTTEXTS
130 HA
+= QString("<br>");
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
);
133 HA
+= QString(string
);
135 model
->insertRow(NbBlocks
);
136 model
->setItem(NbBlocks
, 0, new QStandardItem(QString("0x%1").arg(Adr68K
, 6, 16, QChar('0'))));
137 model
->setItem(NbBlocks
, 1, new QStandardItem(QString("%1").arg((HeapAllocation
.size
- sizeof(HeapAllocation
)))));
138 model
->setItem(NbBlocks
++, 2, new QStandardItem(QString("%1").arg(HeapAllocation
.used
? "Allocated" : "Free")));
140 TotalBytesUsed
+= HeapAllocation
.size
;
142 if ((Adr68K
= HeapAllocation
.nextalloc
) > Adr68KHigh
)
149 sprintf(msg
, "Unable to determine the next memory allocation");
150 Error
= HA_UNABLENEXTMEMORYALLOC
;
155 sprintf(msg
, "Unable to determine if the allocated memory is used or not");
156 Error
= HA_UNABLEALLOCATEMEMORYUSAGE
;
161 sprintf(msg
, "Memory bloc size has a problem");
162 Error
= HA_MEMORYBLOCKSIZEPROBLEM
;
167 sprintf(msg
, "%i blocks | %i bytes in blocks | %i contiguous bytes free", NbBlocks
, TotalBytesUsed
, (m68k_get_reg(NULL
, M68K_REG_SP
) - Adr68KHigh
));
172 sprintf(msg
, "Memory allocations and Stack have reached the same space");
173 Error
= HA_HAANDSPSHARESPACE
;
178 sprintf(msg
, "Memory allocations may have a problem");
179 Error
= HA_MEMORYALLOCATIONPROBLEM
;
182 while (HeapAllocation
.size
&& !Error
);
188 if (Adr
= DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))
190 if (Adr68K
= DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))
192 if (!(Adr68K
= (jaguarMainRAM
[Adr68K
] << 24) + (jaguarMainRAM
[Adr68K
+ 1] << 16) + (jaguarMainRAM
[Adr68K
+ 2] << 8) + (jaguarMainRAM
[Adr68K
+ 3])) || ((Adr68K
< 0x4000) || (Adr68K
>= 0x200000)))
194 sprintf(msg
, "Memory allocator not yet initialised");
195 Error
= HA_MEMORYALLOCATORNOTINITIALIZED
;
200 return RefreshContents();
205 sprintf(msg
, "Memory allocator is not compatible");
206 Error
= HA_MEMORYALLOCATORNOTCOMPATIBLE
;
212 sprintf(msg
, "Memory allocator doesn't exist");
213 Error
= HA_MEMORYALLOCATORNOTEXIST
;
215 #ifdef HA_LAYOUTTEXTS
218 model
->setRowCount(0);
223 // Display status bar
226 if ((Error
& HA_WARNING
))
228 statusbar
->setStyleSheet("background-color: lightyellow; font: bold");
232 statusbar
->setStyleSheet("background-color: tomato; font: bold");
237 statusbar
->setStyleSheet("background-color: lightgreen; font: bold");
239 statusbar
->showMessage(MSG
);
241 #ifdef HA_LAYOUTTEXTS
251 void HeapAllocatorBrowserWindow::Reset(void)
255 if (DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))
257 if (Adr68K
= DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))
259 jaguarMainRAM
[Adr68K
] = jaguarMainRAM
[Adr68K
+ 1] = jaguarMainRAM
[Adr68K
+ 2] = jaguarMainRAM
[Adr68K
+ 3] = 0;
267 void HeapAllocatorBrowserWindow::keyPressEvent(QKeyEvent
* e
)
269 if (e
->key() == Qt::Key_Escape
)