Load and destroy methods revised for proper reference counting
The update enhances object management by involving scope-based reference counting. The change affects loading and destruction operations in the Object and several other classes, ensuring the release or retention of objects adhere to their usage context. A function for logging type data has also been introduced to provide better clarity during debugging. Also, tests in script & interpreter have been altered to run in separate module initializations to avoid cross-test interference. Overall, it provides better memory management and dependable tests.
This commit is contained in:
parent
b06e1da529
commit
55571ca3dd
12 changed files with 58 additions and 10 deletions
|
|
@ -527,6 +527,7 @@ void obj::BCgen::deinit() {
|
||||||
ASSERT(sParger);
|
ASSERT(sParger);
|
||||||
if (sParger) {
|
if (sParger) {
|
||||||
delete sParger;
|
delete sParger;
|
||||||
|
sParger = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,11 @@ static void deinit(const tp::ModuleManifest*) {
|
||||||
MethodObject::UnInitialize();
|
MethodObject::UnInitialize();
|
||||||
|
|
||||||
obj::BCgen::deinit();
|
obj::BCgen::deinit();
|
||||||
|
|
||||||
|
assertNoLeaks();
|
||||||
|
|
||||||
delete NDO;
|
delete NDO;
|
||||||
|
NDO = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tp::ModuleManifest* sModuleDependencies[] = {
|
static tp::ModuleManifest* sModuleDependencies[] = {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
#include "NewPlacement.hpp"
|
#include "NewPlacement.hpp"
|
||||||
#include "core/object.h"
|
#include "core/object.h"
|
||||||
|
|
||||||
|
#include "primitives/nullobject.h"
|
||||||
|
|
||||||
#include "HeapAllocatorGlobal.hpp"
|
#include "HeapAllocatorGlobal.hpp"
|
||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
@ -63,6 +65,27 @@ namespace obj {
|
||||||
tp::HeapAllocGlobal::deallocate(memh);
|
tp::HeapAllocGlobal::deallocate(memh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logTypeData(const ObjectType* type) {
|
||||||
|
printf("type - %s\n", type->name);
|
||||||
|
if (type->base) {
|
||||||
|
printf("Based on ");
|
||||||
|
logTypeData(type->base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertNoLeaks() {
|
||||||
|
if (bottom) {
|
||||||
|
printf("ERROR : not all objects are destroyed\n");
|
||||||
|
tp::ualni idx = 0;
|
||||||
|
for (ObjectMemHead* memh = bottom; memh; memh = memh->up) {
|
||||||
|
printf(" ===== Object - %i. Ref count - %i ===== \n", idx, memh->refc);
|
||||||
|
logTypeData(NDO_FROM_MEMH(memh)->type);
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ObjectFileHead {
|
struct ObjectFileHead {
|
||||||
Object* load_head_adress = 0;
|
Object* load_head_adress = 0;
|
||||||
tp::halni refc = 0;
|
tp::halni refc = 0;
|
||||||
|
|
@ -274,7 +297,13 @@ namespace obj {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
setrefc(out, ofh.refc);
|
setrefc(out, 0);
|
||||||
|
|
||||||
|
// check for null object
|
||||||
|
if (out->type == &NullObject::TypeData) {
|
||||||
|
ObjectMemDeallocate(out);
|
||||||
|
out = NdoNull_globalInstance;
|
||||||
|
}
|
||||||
|
|
||||||
// save heap adress in "loaded_file"
|
// save heap adress in "loaded_file"
|
||||||
((ObjectFileHead*) (loaded_file + file_adress))->load_head_adress = out;
|
((ObjectFileHead*) (loaded_file + file_adress))->load_head_adress = out;
|
||||||
|
|
@ -405,8 +434,6 @@ namespace obj {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setrefc(out, 0);
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,8 @@ void load_constants(ScriptSection* self, ArchiverIn& file, tp::alni start_addr)
|
||||||
// script text
|
// script text
|
||||||
tp::alni str_addr;
|
tp::alni str_addr;
|
||||||
file >> str_addr;
|
file >> str_addr;
|
||||||
|
|
||||||
|
NDO->destroy(script->mReadable); // we already have string object in the script when creating script
|
||||||
script->mReadable = NDO_CAST(obj::StringObject, obj::NDO->load(file, str_addr));
|
script->mReadable = NDO_CAST(obj::StringObject, obj::NDO->load(file, str_addr));
|
||||||
|
|
||||||
file.setAddress(file.getAddress() + sizeof(tp::alni)); // constants length
|
file.setAddress(file.getAddress() + sizeof(tp::alni)); // constants length
|
||||||
|
|
@ -257,6 +259,7 @@ void ScriptSection::initialize() {
|
||||||
void ScriptSection::uninitialize() {
|
void ScriptSection::uninitialize() {
|
||||||
ASSERT(gScriptSection);
|
ASSERT(gScriptSection);
|
||||||
delete gScriptSection;
|
delete gScriptSection;
|
||||||
|
gScriptSection = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptSection* ScriptSection::globalHandle() {
|
ScriptSection* ScriptSection::globalHandle() {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ void ClassObject::load(ArchiverIn& file_self, ClassObject* self) {
|
||||||
alni ndo_object_adress;
|
alni ndo_object_adress;
|
||||||
file_self >> ndo_object_adress;
|
file_self >> ndo_object_adress;
|
||||||
self->members = NDO_CAST(DictObject, NDO->load(file_self, ndo_object_adress));
|
self->members = NDO_CAST(DictObject, NDO->load(file_self, ndo_object_adress));
|
||||||
|
NDO->refinc(self->members);
|
||||||
}
|
}
|
||||||
|
|
||||||
tp::Buffer<Object*> childs_retrival(ClassObject* self) {
|
tp::Buffer<Object*> childs_retrival(ClassObject* self) {
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ void DictObject::load(ArchiverIn& file_self, DictObject* self) {
|
||||||
file_self >> key;
|
file_self >> key;
|
||||||
|
|
||||||
// add to dictinary
|
// add to dictinary
|
||||||
self->items.put(key, val);
|
self->put(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ void LinkObject::load(ArchiverIn& file_self, LinkObject* self) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self->link = NDO->load(file_self, saved_object_adress);
|
self->link = NDO->load(file_self, saved_object_adress);
|
||||||
|
NDO->refinc(self->link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ void ListObject::load(ArchiverIn& file_self, ListObject* self) {
|
||||||
for (alni i = 0; i < len; i++) {
|
for (alni i = 0; i < len; i++) {
|
||||||
alni ndo_object_adress;
|
alni ndo_object_adress;
|
||||||
file_self >> ndo_object_adress;
|
file_self >> ndo_object_adress;
|
||||||
self->items.pushBack(NDO->load(file_self, ndo_object_adress));
|
self->pushBack(NDO->load(file_self, ndo_object_adress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,9 @@ namespace obj {
|
||||||
Object* load(ArchiverIn&, tp::alni file_adress);
|
Object* load(ArchiverIn&, tp::alni file_adress);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void logTypeData(const ObjectType* type);
|
||||||
|
void assertNoLeaks();
|
||||||
|
|
||||||
Object* ndo_cast(const Object* in, const ObjectType* to_type);
|
Object* ndo_cast(const Object* in, const ObjectType* to_type);
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,19 @@ int main() {
|
||||||
tp::ModuleManifest module("ObjectsTests", nullptr, nullptr, deps);
|
tp::ModuleManifest module("ObjectsTests", nullptr, nullptr, deps);
|
||||||
|
|
||||||
if (module.initialize()) {
|
if (module.initialize()) {
|
||||||
|
|
||||||
testCore();
|
testCore();
|
||||||
testPrimitives();
|
|
||||||
testInterpreter();
|
|
||||||
|
|
||||||
module.deinitialize();
|
module.deinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (module.initialize()) {
|
||||||
|
testPrimitives();
|
||||||
|
module.deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module.initialize()) {
|
||||||
|
testInterpreter();
|
||||||
|
module.deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -31,8 +31,8 @@ TEST_DEF_STATIC(Simple) {
|
||||||
|
|
||||||
interpreterLoaded->exec();
|
interpreterLoaded->exec();
|
||||||
|
|
||||||
NDO->destroy(interpreter);
|
|
||||||
NDO->destroy(interpreterLoaded);
|
NDO->destroy(interpreterLoaded);
|
||||||
|
NDO->destroy(interpreter);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_DEF(Interpreter) {
|
TEST_DEF(Interpreter) {
|
||||||
|
|
|
||||||
|
|
@ -54,5 +54,6 @@ namespace tp {
|
||||||
void Logger::deinitializeGlobal() {
|
void Logger::deinitializeGlobal() {
|
||||||
DEBUG_ASSERT(gLogger)
|
DEBUG_ASSERT(gLogger)
|
||||||
delete gLogger;
|
delete gLogger;
|
||||||
|
gLogger = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue