ksys/evt: Fix OrderParam tryAlloc loop

This commit is contained in:
iTNTPiston 2021-02-06 22:35:23 -05:00 committed by Léo Lam
parent a16f01aed7
commit 6ef151ac1f
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
2 changed files with 71 additions and 75 deletions

View File

@ -21,18 +21,16 @@ bool OrderParam::initialize(s32 entry_count) {
error_message.format("[%s] initialize(%d) is failed.", "ksys::evt::OrderParam", entry_count); error_message.format("[%s] initialize(%d) is failed.", "ksys::evt::OrderParam", entry_count);
uninitialize(); uninitialize();
if (entry_count == 0) if (!entry_count)
return true; return true;
if (!mHeap) if (!mHeap)
return false; return false;
if (entry_count < 1)
return false;
if (!mEntries.tryAllocBuffer(entry_count, mHeap)) if (!mEntries.tryAllocBuffer(entry_count, mHeap))
return false; return false;
// I think compiler is unrolling this loop for (s32 i = 0; i < entry_count; i++) {
for (s32 i = 0; i != mEntries.size(); ++i) { clearEntry(&mEntries[i]); // no matter what I do, the compiler unrolls the first 2
clearEntry(&mEntries[i]); // iterations out of the loop
} }
mEntryCount = 0; mEntryCount = 0;
mInitialized = true; mInitialized = true;
@ -208,82 +206,72 @@ bool OrderParam::getStringByName(const sead::SafeString& name, sead::SafeString*
bool OrderParam::getArrayByName(const sead::SafeString& name, void** out_ptr, u32* out_size) { bool OrderParam::getArrayByName(const sead::SafeString& name, void** out_ptr, u32* out_size) {
return getPointerByName(name, out_ptr, OrderParamType::ARRAY, out_size); return getPointerByName(name, out_ptr, OrderParamType::ARRAY, out_size);
} }
OrderParamEntry* OrderParam::getFreeEntry() {
// This one also does not match for (s32 i = 0; i < mEntries.size(); i++) {
auto* entry = &mEntries[i];
if (!entry->mPointer) {
return entry;
}
}
return nullptr;
}
// This one does not match
OrderParamEntry* OrderParam::tryAlloc(OrderParamType type, u32 size, const sead::SafeString& name) { OrderParamEntry* OrderParam::tryAlloc(OrderParamType type, u32 size, const sead::SafeString& name) {
sead::FixedSafeString<0x100> error_message; sead::FixedSafeString<0x100> error_message;
error_message.format("[%s] tryAlloc_(%d, %d, %s) is failed.", "ksys::evt::OrderParam", type, error_message.format("[%s] tryAlloc_(%d, %d, %s) is failed.", "ksys::evt::OrderParam", type,
size, name.cstr()); size, name.cstr());
for (s32 i = 0; i < mEntries.size(); i++) { OrderParamEntry* entry = getFreeEntry(); // inlining here fixed the for loop
auto* e = &mEntries[i];
if (!e->mPointer) { if (!entry)
void** in_ptr = &(e->mPointer); return nullptr;
std::nothrow_t nothrow_t;
auto* heap = mHeap; auto* heap = mHeap;
if (!heap) if (!heap)
return nullptr; return nullptr;
std::nothrow_t nothrow;
entry->mName =
new (heap, nothrow) sead::FixedSafeString<0x20>(name); // scheduling mismatches here
// entry->mName = new_name;
// inlining here doesn't fix the mismatch
e->mName = new (heap, nothrow_t) sead::FixedSafeString<0x20>(name);
switch (type) { switch (type) {
case OrderParamType::STRING:
*in_ptr = new (heap, nothrow_t) sead::FixedSafeString<0x40>;
size = sizeof(sead::FixedSafeString<0x40>);
break;
case OrderParamType::INT: case OrderParamType::INT:
case OrderParamType::INT_2: case OrderParamType::INT_2:
*in_ptr = new (heap, nothrow_t) u32(0); doAlloc(entry, new (heap, nothrow) s32(0));
size = sizeof(u32); break;
case OrderParamType::STRING:
doAlloc(entry,
new (heap, nothrow) sead::FixedSafeString<0x40>); // scheduling mismatches here
break; break;
case OrderParamType::BYTE: case OrderParamType::BYTE:
*in_ptr = new (heap, nothrow_t) char(0); doAlloc(entry, new (heap, nothrow) char(0));
size = sizeof(char);
break; break;
case OrderParamType::ACTOR: case OrderParamType::ACTOR:
*in_ptr = new (heap, nothrow_t) ksys::act::BaseProcLink; doAlloc(entry, new (heap, nothrow) ksys::act::BaseProcLink);
size = sizeof(ksys::act::BaseProcLink);
break; break;
case OrderParamType::ARRAY: case OrderParamType::ARRAY:
*in_ptr = new (heap, nothrow_t) char[size]; doAlloc(entry, new (heap, nothrow) char[size], size);
break;
default: default:
break; break;
} }
e->mSize = size;
if (e->mPointer) {
e->mHash = sead::HashCRC32::calcStringHash(e->mName->cstr());
e->mType = type;
return e;
}
if (e->mName)
delete e->mName;
// clearEntry(e);
*e = {};
return nullptr;
// auto* entry = mAllocArray+i;
// if (*in_ptr) {
//} else { auto* ptr = entry->mPointer;
//} if (ptr) {
entry->mHash = sead::HashCRC32::calcStringHash(*entry->mName);
entry->mType = type;
} else {
if (entry->mName)
delete entry->mName;
clearEntry(entry);
entry = nullptr;
} }
} return entry;
return nullptr;
} }
// OrderParamEntry* OrderParam::getEntryByName(const sead::SafeString& name, OrderParamType type) {
// const u32 hash = sead::HashCRC32::calcStringHash(name);
// for (s32 i = 0; i < mEntries.size(); i++) {
// if (mEntries[i].mHash == hash && mEntries[i].mType == type) {
// return &mEntries[i];
// }
// }
// return nullptr;
// }
void* OrderParam::getPointerByName(const sead::SafeString& name, OrderParamType type, void* OrderParam::getPointerByName(const sead::SafeString& name, OrderParamType type,
u32* out_size) const { u32* out_size) const {
const u32 hash = sead::HashCRC32::calcStringHash(name); const u32 hash = sead::HashCRC32::calcStringHash(name);

View File

@ -20,12 +20,12 @@ enum class OrderParamType : u16 {
}; };
struct OrderParamEntry { struct OrderParamEntry {
u32 mHash = 0; u32 mHash;
// u32 _4; alignment gap // u32 _4; alignment gap
sead::SafeString* mName = nullptr; sead::SafeString* mName;
void* mPointer = nullptr; //_10 void* mPointer; //_10
u32 mSize = 0; //_18 u32 mSize; //_18
OrderParamType mType = OrderParamType::INVALID; OrderParamType mType;
// u16 _1e; alignment gap // u16 _1e; alignment gap
}; };
@ -53,7 +53,7 @@ public:
private: private:
bool doAssign(OrderParam* other); bool doAssign(OrderParam* other);
// OrderParamEntry* getEntryByName(const sead::SafeString& name, OrderParamType type); OrderParamEntry* getFreeEntry();
void* getPointerByName(const sead::SafeString& name, OrderParamType type, void* getPointerByName(const sead::SafeString& name, OrderParamType type,
u32* out_size = nullptr) const; u32* out_size = nullptr) const;
@ -78,6 +78,13 @@ private:
return nullptr; return nullptr;
return static_cast<T*>(entry->mPointer); return static_cast<T*>(entry->mPointer);
} }
template <typename T>
void doAlloc(OrderParamEntry* e, T* ptr, u32 size = sizeof(T)) {
//*size_ptr = sizeof(T);
e->mPointer = ptr;
e->mSize = size;
// return sizeof(T);
}
inline void clearEntry(OrderParamEntry* e) { inline void clearEntry(OrderParamEntry* e) {
e->mHash = 0; e->mHash = 0;
@ -86,6 +93,7 @@ private:
e->mName = nullptr; e->mName = nullptr;
e->mPointer = nullptr; e->mPointer = nullptr;
} }
sead::ExpHeap* mHeap; sead::ExpHeap* mHeap;
sead::Buffer<OrderParamEntry> mEntries; sead::Buffer<OrderParamEntry> mEntries;
u32 mEntryCount = 0; u32 mEntryCount = 0;