Skip to content

Commit 1b7bd47

Browse files
committed
Machine: Fix memory leak
1 parent ca20e91 commit 1b7bd47

File tree

3 files changed

+105
-104
lines changed

3 files changed

+105
-104
lines changed

src/machine/machine.cpp

Lines changed: 65 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,32 @@ using namespace machine;
1111
Machine::Machine(MachineConfig config, bool load_symtab, bool load_executable)
1212
: machine_config(std::move(config))
1313
, stat(ST_READY) {
14-
regs = new Registers();
14+
regs.reset(new Registers());
1515

1616
if (load_executable) {
1717
ProgramLoader program(machine_config.elf());
1818
this->machine_config.set_simulated_endian(program.get_endian());
19-
mem_program_only = new Memory(machine_config.get_simulated_endian());
20-
program.to_memory(mem_program_only);
19+
mem_program_only.reset(new Memory(machine_config.get_simulated_endian()));
20+
program.to_memory(mem_program_only.data());
2121

2222
if (program.get_architecture_type() == ARCH64)
2323
this->machine_config.set_simulated_xlen(Xlen::_64);
2424
else
2525
this->machine_config.set_simulated_xlen(Xlen::_32);
2626

27-
if (load_symtab) { symtab = program.get_symbol_table(); }
27+
if (load_symtab) { symtab.reset(program.get_symbol_table()); }
2828

2929
program_end = program.end();
3030
if (program.get_executable_entry() != 0x0_addr) {
3131
regs->write_pc(program.get_executable_entry());
3232
}
33-
mem = new Memory(*mem_program_only);
33+
mem.reset(new Memory(*mem_program_only));
3434
} else {
35-
mem = new Memory(machine_config.get_simulated_endian());
35+
mem.reset(new Memory(machine_config.get_simulated_endian()));
3636
}
3737

38-
data_bus = new MemoryDataBus(machine_config.get_simulated_endian());
39-
data_bus->insert_device_to_range(mem, 0x00000000_addr, 0xefffffff_addr, false);
38+
data_bus.reset(new MemoryDataBus(machine_config.get_simulated_endian()));
39+
data_bus->insert_device_to_range(mem.data(), 0x00000000_addr, 0xefffffff_addr, false);
4040

4141
setup_serial_port();
4242
setup_perip_spi_led();
@@ -50,44 +50,46 @@ Machine::Machine(MachineConfig config, bool load_symtab, bool load_executable)
5050
unsigned access_time_burst = machine_config.memory_access_time_burst();
5151
bool access_enable_burst = machine_config.memory_access_enable_burst();
5252

53-
cch_level2 = new Cache(
54-
data_bus, &machine_config.cache_level2(), access_time_read, access_time_write,
55-
access_time_burst, access_enable_burst);
53+
cch_level2.reset(new Cache(
54+
data_bus.data(), &machine_config.cache_level2(), access_time_read, access_time_write,
55+
access_time_burst, access_enable_burst));
5656
if (machine_config.cache_level2().enabled()) {
5757
access_time_read = machine_config.memory_access_time_level2();
5858
access_time_write = machine_config.memory_access_time_level2();
5959
access_time_burst = 0;
6060
access_enable_burst = true;
6161
}
62-
cch_program = new Cache(
63-
cch_level2, &machine_config.cache_program(), access_time_read, access_time_write,
64-
access_time_burst, access_enable_burst);
65-
cch_data = new Cache(
66-
cch_level2, &machine_config.cache_data(), access_time_read, access_time_write,
67-
access_time_burst, access_enable_burst);
68-
69-
controlst
70-
= new CSR::ControlState(machine_config.get_simulated_xlen(), machine_config.get_isa_word());
71-
predictor = new BranchPredictor(
62+
cch_program.reset(new Cache(
63+
cch_level2.data(), &machine_config.cache_program(), access_time_read, access_time_write,
64+
access_time_burst, access_enable_burst));
65+
cch_data.reset(new Cache(
66+
cch_level2.data(), &machine_config.cache_data(), access_time_read, access_time_write,
67+
access_time_burst, access_enable_burst));
68+
69+
controlst.reset(
70+
new CSR::ControlState(machine_config.get_simulated_xlen(), machine_config.get_isa_word()));
71+
predictor.reset(new BranchPredictor(
7272
machine_config.get_bp_enabled(), machine_config.get_bp_type(),
7373
machine_config.get_bp_init_state(), machine_config.get_bp_btb_bits(),
74-
machine_config.get_bp_bhr_bits(), machine_config.get_bp_bht_addr_bits());
74+
machine_config.get_bp_bhr_bits(), machine_config.get_bp_bht_addr_bits()));
7575

7676
if (machine_config.pipelined()) {
77-
cr = new CorePipelined(
78-
regs, predictor, cch_program, cch_data, controlst, machine_config.get_simulated_xlen(),
79-
machine_config.get_isa_word(), machine_config.hazard_unit());
77+
cr.reset(new CorePipelined(
78+
regs.data(), predictor.data(), cch_program.data(), cch_data.data(), controlst.data(),
79+
machine_config.get_simulated_xlen(), machine_config.get_isa_word(),
80+
machine_config.hazard_unit()));
8081
} else {
81-
cr = new CoreSingle(
82-
regs, predictor, cch_program, cch_data, controlst, machine_config.get_simulated_xlen(),
83-
machine_config.get_isa_word());
82+
cr.reset(new CoreSingle(
83+
regs.data(), predictor.data(), cch_program.data(), cch_data.data(), controlst.data(),
84+
machine_config.get_simulated_xlen(), machine_config.get_isa_word()));
8485
}
8586
connect(
86-
this, &Machine::set_interrupt_signal, controlst, &CSR::ControlState::set_interrupt_signal);
87+
this, &Machine::set_interrupt_signal, controlst.data(),
88+
&CSR::ControlState::set_interrupt_signal);
8789

88-
run_t = new QTimer(this);
90+
run_t.reset(new QTimer(this));
8991
set_speed(0); // In default run as fast as possible
90-
connect(run_t, &QTimer::timeout, this, &Machine::step_timer);
92+
connect(run_t.data(), &QTimer::timeout, this, &Machine::step_timer);
9193

9294
for (int i = 0; i < EXCAUSE_COUNT; i++) {
9395
if (i != EXCAUSE_INT && i != EXCAUSE_BREAK && i != EXCAUSE_HWBREAK) {
@@ -166,30 +168,7 @@ void Machine::setup_aclint_sswi() {
166168
}
167169

168170
Machine::~Machine() {
169-
delete run_t;
170-
run_t = nullptr;
171-
delete cr;
172-
cr = nullptr;
173-
delete controlst;
174-
controlst = nullptr;
175-
delete regs;
176-
regs = nullptr;
177-
delete mem;
178-
mem = nullptr;
179-
delete cch_program;
180-
cch_program = nullptr;
181-
delete cch_data;
182-
cch_data = nullptr;
183-
delete cch_level2;
184-
cch_level2 = nullptr;
185-
delete data_bus;
186-
data_bus = nullptr;
187-
delete mem_program_only;
188-
mem_program_only = nullptr;
189-
delete symtab;
190-
symtab = nullptr;
191-
delete predictor;
192-
predictor = nullptr;
171+
stop_core_clock();
193172
}
194173

195174
const MachineConfig &Machine::config() {
@@ -206,49 +185,49 @@ void Machine::set_speed(unsigned int ips, unsigned int time_chunk) {
206185
}
207186

208187
const Registers *Machine::registers() {
209-
return regs;
188+
return regs.data();
210189
}
211190

212191
const CSR::ControlState *Machine::control_state() {
213-
return controlst;
192+
return controlst.data();
214193
}
215194

216195
const Memory *Machine::memory() {
217-
return mem;
196+
return mem.data();
218197
}
219198

220199
Memory *Machine::memory_rw() {
221-
return mem;
200+
return mem.data();
222201
}
223202

224203
const Cache *Machine::cache_program() {
225-
return cch_program;
204+
return cch_program.data();
226205
}
227206

228207
const Cache *Machine::cache_data() {
229-
return cch_data;
208+
return cch_data.data();
230209
}
231210

232211
const Cache *Machine::cache_level2() {
233-
return cch_level2;
212+
return cch_level2.data();
234213
}
235214

236215
Cache *Machine::cache_data_rw() {
237-
return cch_data;
216+
return cch_data.data();
238217
}
239218

240219
void Machine::cache_sync() {
241-
if (cch_program != nullptr) { cch_program->sync(); }
242-
if (cch_data != nullptr) { cch_data->sync(); }
243-
if (cch_level2 != nullptr) { cch_level2->sync(); }
220+
if (!cch_program.isNull()) { cch_program->sync(); }
221+
if (!cch_data.isNull()) { cch_data->sync(); }
222+
if (!cch_level2.isNull()) { cch_level2->sync(); }
244223
}
245224

246225
const MemoryDataBus *Machine::memory_data_bus() {
247-
return data_bus;
226+
return data_bus.data();
248227
}
249228

250229
MemoryDataBus *Machine::memory_data_bus_rw() {
251-
return data_bus;
230+
return data_bus.data();
252231
}
253232

254233
SerialPort *Machine::serial_port() {
@@ -264,8 +243,8 @@ LcdDisplay *Machine::peripheral_lcd_display() {
264243
}
265244

266245
SymbolTable *Machine::symbol_table_rw(bool create) {
267-
if (create && (symtab == nullptr)) { symtab = new SymbolTable; }
268-
return symtab;
246+
if (create && (symtab.isNull())) { symtab.reset(new SymbolTable); }
247+
return symtab.data();
269248
}
270249

271250
const SymbolTable *Machine::symbol_table(bool create) {
@@ -278,24 +257,24 @@ void Machine::set_symbol(
278257
uint32_t size,
279258
unsigned char info,
280259
unsigned char other) {
281-
if (symtab == nullptr) { symtab = new SymbolTable; }
260+
if (symtab.isNull()) { symtab.reset(new SymbolTable); }
282261
symtab->set_symbol(name, value, size, info, other);
283262
}
284263

285264
const Core *Machine::core() {
286-
return cr;
265+
return cr.data();
287266
}
288267

289268
const CoreSingle *Machine::core_singe() {
290-
return machine_config.pipelined() ? nullptr : (const CoreSingle *)cr;
269+
return machine_config.pipelined() ? nullptr : (const CoreSingle *)cr.data();
291270
}
292271

293272
const CorePipelined *Machine::core_pipelined() {
294-
return machine_config.pipelined() ? (const CorePipelined *)cr : nullptr;
273+
return machine_config.pipelined() ? (const CorePipelined *)cr.data() : nullptr;
295274
}
296275

297276
bool Machine::executable_loaded() const {
298-
return (mem_program_only != nullptr);
277+
return (!mem_program_only.isNull());
299278
}
300279

301280
enum Machine::Status Machine::status() {
@@ -404,7 +383,7 @@ void Machine::step_timer() {
404383
void Machine::restart() {
405384
pause();
406385
regs->reset();
407-
if (mem_program_only != nullptr) { mem->reset(*mem_program_only); }
386+
if (!mem_program_only.isNull()) { mem->reset(*mem_program_only); }
408387
cch_program->reset();
409388
cch_data->reset();
410389
cch_level2->reset();
@@ -419,52 +398,52 @@ void Machine::set_status(enum Status st) {
419398
}
420399

421400
void Machine::register_exception_handler(ExceptionCause excause, ExceptionHandler *exhandler) {
422-
if (cr != nullptr) { cr->register_exception_handler(excause, exhandler); }
401+
if (!cr.isNull()) { cr->register_exception_handler(excause, exhandler); }
423402
}
424403

425404
bool Machine::memory_bus_insert_range(
426405
BackendMemory *mem_acces,
427406
Address start_addr,
428407
Address last_addr,
429408
bool move_ownership) {
430-
if (data_bus == nullptr) { return false; }
409+
if (data_bus.isNull()) { return false; }
431410
return data_bus->insert_device_to_range(mem_acces, start_addr, last_addr, move_ownership);
432411
}
433412

434413
void Machine::insert_hwbreak(Address address) {
435-
if (cr != nullptr) { cr->insert_hwbreak(address); }
414+
if (!cr.isNull()) { cr->insert_hwbreak(address); }
436415
}
437416

438417
void Machine::remove_hwbreak(Address address) {
439-
if (cr != nullptr) { cr->remove_hwbreak(address); }
418+
if (!cr.isNull()) { cr->remove_hwbreak(address); }
440419
}
441420

442421
bool Machine::is_hwbreak(Address address) {
443-
if (cr != nullptr) { return cr->is_hwbreak(address); }
422+
if (!cr.isNull()) { return cr->is_hwbreak(address); }
444423
return false;
445424
}
446425

447426
void Machine::set_stop_on_exception(enum ExceptionCause excause, bool value) {
448-
if (cr != nullptr) { cr->set_stop_on_exception(excause, value); }
427+
if (!cr.isNull()) { cr->set_stop_on_exception(excause, value); }
449428
}
450429

451430
bool Machine::get_stop_on_exception(enum ExceptionCause excause) const {
452-
if (cr != nullptr) { return cr->get_stop_on_exception(excause); }
431+
if (!cr.isNull()) { return cr->get_stop_on_exception(excause); }
453432
return false;
454433
}
455434

456435
void Machine::set_step_over_exception(enum ExceptionCause excause, bool value) {
457-
if (cr != nullptr) { cr->set_step_over_exception(excause, value); }
436+
if (!cr.isNull()) { cr->set_step_over_exception(excause, value); }
458437
}
459438

460439
bool Machine::get_step_over_exception(enum ExceptionCause excause) const {
461-
if (cr != nullptr) { return cr->get_step_over_exception(excause); }
440+
if (!cr.isNull()) { return cr->get_step_over_exception(excause); }
462441
return false;
463442
}
464443

465444
enum ExceptionCause Machine::get_exception_cause() const {
466445
uint32_t val;
467-
if (controlst == nullptr) { return EXCAUSE_NONE; }
446+
if (controlst.isNull()) { return EXCAUSE_NONE; }
468447
val = (controlst->read_internal(CSR::Id::MCAUSE).as_u64());
469448
if (val & 0xffffffff80000000) {
470449
return EXCAUSE_INT;

src/machine/machine.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,36 +113,37 @@ private slots:
113113

114114
MachineConfig machine_config;
115115

116-
Registers *regs = nullptr;
117-
Memory *mem = nullptr;
116+
Box<Registers> regs;
117+
Box<Memory> mem;
118118
/**
119119
* Memory with loaded program only.
120120
* It is not used for execution, only for quick
121121
* simulation reset without repeated ELF file loading.
122122
*/
123-
Memory *mem_program_only = nullptr;
124-
MemoryDataBus *data_bus = nullptr;
123+
Box<Memory> mem_program_only;
124+
Box<MemoryDataBus> data_bus;
125+
// Peripherals are owned by data_bus
125126
SerialPort *ser_port = nullptr;
126127
PeripSpiLed *perip_spi_led = nullptr;
127128
LcdDisplay *perip_lcd_display = nullptr;
128129
aclint::AclintMtimer *aclint_mtimer = nullptr;
129130
aclint::AclintMswi *aclint_mswi = nullptr;
130131
aclint::AclintSswi *aclint_sswi = nullptr;
131-
Cache *cch_program = nullptr;
132-
Cache *cch_data = nullptr;
133-
Cache *cch_level2 = nullptr;
134-
CSR::ControlState *controlst = nullptr;
135-
BranchPredictor *predictor = nullptr;
136-
Core *cr = nullptr;
137-
138-
QTimer *run_t = nullptr;
132+
Box<Cache> cch_level2;
133+
Box<Cache> cch_program;
134+
Box<Cache> cch_data;
135+
Box<CSR::ControlState> controlst;
136+
Box<BranchPredictor> predictor;
137+
Box<Core> cr;
138+
139+
Box<QTimer> run_t;
139140
unsigned int time_chunk = { 0 };
140141

141142
// Used to monitor the real CPU frequency
142143
QElapsedTimer frequency_timer;
143144
uint64_t last_cycle_count = 0;
144145

145-
SymbolTable *symtab = nullptr;
146+
Box<SymbolTable> symtab;
146147
Address program_end = 0xffff0000_addr;
147148
enum Status stat = ST_READY;
148149
void set_status(enum Status st);

0 commit comments

Comments
 (0)