SaveSizeCounter is introduced and used for calculating the save size of objects. The previous method of calculating save size directly in each class was replaced with a call to the SaveSizeCounter's calc method. This results in a cleaner, more maintainable code as the size calculation logic is now centralized in one class. It is more efficient and scalable as any changes to the calculation can be made in one place and will be reflected everywhere.
265 lines
6.6 KiB
C++
265 lines
6.6 KiB
C++
|
|
#include "NewPlacement.hpp"
|
|
#include "HeapAllocatorGlobal.hpp"
|
|
|
|
#include "core/scriptsection.h"
|
|
|
|
using namespace obj;
|
|
|
|
ScriptSection* gScriptSection = NULL;
|
|
|
|
struct script_data_head {
|
|
tp::alni refc = 0;
|
|
tp::alni store_adress = 0;
|
|
};
|
|
|
|
void set_script_head_store_adress(Script* in, tp::alni address) {
|
|
((script_data_head*)in - 1)->store_adress = address;
|
|
}
|
|
|
|
tp::alni get_script_head_store_adress(Script* in) {
|
|
return ((script_data_head*)in - 1)->store_adress;
|
|
}
|
|
|
|
Script* ScriptSection::createScript() {
|
|
auto sdhead = (script_data_head*)tp::HeapAllocGlobal::allocate(sizeof(script_data_head) + sizeof(Script));
|
|
auto out = (Script*)(sdhead + 1);
|
|
|
|
if (!sdhead) {
|
|
return NULL;
|
|
}
|
|
|
|
sdhead->refc = 1;
|
|
sdhead->store_adress = -1;
|
|
|
|
mScripts.pushBack(out);
|
|
|
|
new (out) Script();
|
|
out->mReadable = obj::StringObject::create("");
|
|
obj::NDO->refinc(out->mReadable);
|
|
return out;
|
|
}
|
|
|
|
void ScriptSection::delete_script(Script* script) {
|
|
script->~Script();
|
|
obj::NDO->destroy(script->mReadable);
|
|
|
|
tp::HeapAllocGlobal::deallocate((((script_data_head*)script) - 1));
|
|
}
|
|
|
|
void ScriptSection::reference_script(Script* script) {
|
|
(((script_data_head*)script) - 1)->refc++;
|
|
}
|
|
|
|
void ScriptSection::abandonScript(Script* script) {
|
|
if ((((script_data_head*)script) - 1)->refc > 1) {
|
|
(((script_data_head*)script) - 1)->refc--;
|
|
}
|
|
else {
|
|
// ISSUE : on delete list structure is outdated
|
|
// FIXME : use pool alloc with ref count
|
|
// forwarding to global destruction
|
|
//delete_script(script);
|
|
}
|
|
}
|
|
|
|
void ScriptSection::changeScript(Script** current_script, Script** new_script) {
|
|
abandonScript(*current_script);
|
|
reference_script(*new_script);
|
|
|
|
*current_script = *new_script;
|
|
}
|
|
|
|
tp::alni ScriptSection::get_script_file_adress(Script* in) {
|
|
return get_script_head_store_adress(in);
|
|
}
|
|
|
|
tp::alni ScriptSection::save_script_table_to_file_size(ScriptSection* self, ArchiverOut& file) {
|
|
tp::alni size = 0;
|
|
size += 5; // header
|
|
size += sizeof(tp::alni); // scripts length
|
|
|
|
for (auto iter : self->mScripts) {
|
|
|
|
set_script_head_store_adress(iter.data(), file.getAddress() + size);
|
|
|
|
size += sizeof(tp::alni); // scripts string obj ref
|
|
size += sizeof(tp::alni); // constants length
|
|
|
|
for (auto const_obj : iter->mBytecode.mConstants) {
|
|
size += sizeof(tp::alni); // constant object addres
|
|
}
|
|
|
|
// instructions
|
|
size += tp::SaveSizeCounter::calc(iter->mBytecode.mInstructions);
|
|
}
|
|
|
|
size += sizeof(tp::alni); // objects mem offset
|
|
size += 5; // header
|
|
return size;
|
|
}
|
|
|
|
void ScriptSection::save_script_table_to_file(ScriptSection* self, ArchiverOut& file) {
|
|
// header
|
|
file.writeBytes("/scr/", 5);
|
|
|
|
// scripts length
|
|
tp::alni scripts_count = self->mScripts.length();
|
|
file << scripts_count;
|
|
|
|
for (auto iter : self->mScripts) {
|
|
|
|
// scripts string obj ref
|
|
auto obj_addres = obj::NDO->save(file, iter->mReadable);
|
|
file << obj_addres;
|
|
|
|
// constants length
|
|
tp::alni consts_count = iter->mBytecode.mConstants.size();
|
|
file << consts_count;
|
|
|
|
for (auto const_obj : iter->mBytecode.mConstants) {
|
|
// constant object addres
|
|
auto obj_addres = obj::NDO->save(file, const_obj.data());
|
|
file << obj_addres;
|
|
}
|
|
|
|
// mInstructions
|
|
file << iter->mBytecode.mInstructions;
|
|
}
|
|
|
|
// header
|
|
file.writeBytes("/scr/", 5);
|
|
|
|
tp::alni objects_mem_offset = file.getFreeAddress();
|
|
file << objects_mem_offset;
|
|
}
|
|
|
|
void load_constants(ScriptSection* self, ArchiverIn& file, tp::alni start_addr) {
|
|
auto addres = file.getAddress();
|
|
|
|
file.setAddress(start_addr);
|
|
file.setAddress( start_addr + 5); // header
|
|
|
|
tp::alni scripts_count;
|
|
file >> scripts_count;
|
|
|
|
for (tp::alni i = 0; i < scripts_count; i++) {
|
|
|
|
auto script = self->get_scritp_from_file_adress(file.getAddress());
|
|
|
|
// script text
|
|
tp::alni str_addr;
|
|
file >> str_addr;
|
|
script->mReadable = NDO_CAST(obj::StringObject, obj::NDO->load(file, str_addr));
|
|
|
|
file.setAddress(file.getAddress() + sizeof(tp::alni)); // constants length
|
|
|
|
for (auto const_obj : script->mBytecode.mConstants) {
|
|
tp::alni consts_addr;
|
|
file >> consts_addr;
|
|
const_obj.data() = obj::NDO->load(file, consts_addr);
|
|
}
|
|
|
|
// instructions
|
|
file.setAddress(file.getAddress() + tp::SaveSizeCounter::calc(script->mBytecode.mInstructions));
|
|
}
|
|
|
|
file.setAddress(addres);
|
|
}
|
|
|
|
void ScriptSection::load_script_table_from_file(ScriptSection* self, ArchiverIn& file) {
|
|
for (auto iter : self->mScripts) {
|
|
set_script_head_store_adress(iter.data(), -1);
|
|
}
|
|
|
|
auto section_start_addr = file.getAddress();
|
|
|
|
// header
|
|
file.setAddress(file.getAddress() + 5);
|
|
|
|
// scripts length
|
|
tp::alni scripts_count;
|
|
file >> scripts_count;
|
|
|
|
for (tp::alni i = 0; i < scripts_count; i++) {
|
|
|
|
auto new_script = self->createScript();
|
|
set_script_head_store_adress(new_script, file.getAddress());
|
|
|
|
// scripts text
|
|
file.setAddress(file.getAddress() + sizeof(tp::alni));
|
|
|
|
// constants length
|
|
tp::alni consts_count;
|
|
file >> consts_count;
|
|
|
|
new_script->mBytecode.mConstants.reserve(consts_count);
|
|
|
|
for (tp::alni j = 0; j < consts_count; j++) {
|
|
// constant object addres
|
|
tp::alni consts_addr;
|
|
file >> consts_addr;
|
|
|
|
// skiping
|
|
//new_script->mBytecode.mConstants[j] = obj::NDO->load(file, consts_addr);
|
|
}
|
|
|
|
// mInstructions
|
|
file >> new_script->mBytecode.mInstructions;
|
|
}
|
|
|
|
load_constants(self, file, section_start_addr);
|
|
|
|
// header
|
|
file.setAddress(file.getAddress() + 5);
|
|
|
|
tp::alni objects_mem_offset;
|
|
file >> objects_mem_offset;
|
|
|
|
file.setAddress(objects_mem_offset);
|
|
}
|
|
|
|
Script* ScriptSection::get_scritp_from_file_adress(tp::alni file_adress) {
|
|
for (auto iter : mScripts) {
|
|
if (get_script_head_store_adress(iter.data()) == file_adress) {
|
|
return iter.data();
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
ScriptSection::~ScriptSection() {
|
|
for (auto iter : mScripts) {
|
|
delete_script(iter.data());
|
|
}
|
|
}
|
|
|
|
obj::save_load_callbacks ScriptSection::slcb_script_section = {
|
|
.self = gScriptSection,
|
|
.pre_save = (obj::pre_save_callback*)ScriptSection::save_script_table_to_file,
|
|
.size = (obj::slcb_size_callback*)ScriptSection::save_script_table_to_file_size,
|
|
.pre_load = (obj::pre_load_callback*)ScriptSection::load_script_table_from_file,
|
|
.post_save = NULL,
|
|
.post_load = NULL,
|
|
};
|
|
|
|
|
|
void ScriptSection::initialize() {
|
|
ASSERT(!gScriptSection);
|
|
gScriptSection = new ScriptSection();
|
|
|
|
ASSERT(obj::NDO && "Forgot to initialize objects?");
|
|
|
|
slcb_script_section.self = gScriptSection;
|
|
obj::NDO->add_sl_callbacks(&slcb_script_section);
|
|
}
|
|
|
|
void ScriptSection::uninitialize() {
|
|
ASSERT(gScriptSection);
|
|
delete gScriptSection;
|
|
}
|
|
|
|
ScriptSection* ScriptSection::globalHandle() {
|
|
return gScriptSection;
|
|
}
|
|
|