summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriTNTPiston <zhaoyizhu2000@gmail.com>2021-02-06 22:35:23 -0500
committerLéo Lam <leo@leolam.fr>2021-02-07 16:08:54 +0100
commit6ef151ac1f17c0e33dcb4bf29d12e2500ca03db4 (patch)
tree07b495a6bf4df2aaa62ba5875ec7b8d0e7a097c5
parenta16f01aed7b6b40b1e48f0e33ab9d10319a26965 (diff)
ksys/evt: Fix OrderParam tryAlloc loop
-rw-r--r--src/KingSystem/Event/evtOrderParam.cpp124
-rw-r--r--src/KingSystem/Event/evtOrderParam.h20
2 files changed, 70 insertions, 74 deletions
diff --git a/src/KingSystem/Event/evtOrderParam.cpp b/src/KingSystem/Event/evtOrderParam.cpp
index 46d4f6a1..999598cd 100644
--- a/src/KingSystem/Event/evtOrderParam.cpp
+++ b/src/KingSystem/Event/evtOrderParam.cpp
@@ -21,18 +21,16 @@ bool OrderParam::initialize(s32 entry_count) {
error_message.format("[%s] initialize(%d) is failed.", "ksys::evt::OrderParam", entry_count);
uninitialize();
- if (entry_count == 0)
+ if (!entry_count)
return true;
if (!mHeap)
return false;
- if (entry_count < 1)
- return false;
if (!mEntries.tryAllocBuffer(entry_count, mHeap))
return false;
- // I think compiler is unrolling this loop
- for (s32 i = 0; i != mEntries.size(); ++i) {
- clearEntry(&mEntries[i]);
+ for (s32 i = 0; i < entry_count; i++) {
+ clearEntry(&mEntries[i]); // no matter what I do, the compiler unrolls the first 2
+ // iterations out of the loop
}
mEntryCount = 0;
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) {
return getPointerByName(name, out_ptr, OrderParamType::ARRAY, out_size);
}
-
-// This one also does not match
+OrderParamEntry* OrderParam::getFreeEntry() {
+ 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) {
sead::FixedSafeString<0x100> error_message;
error_message.format("[%s] tryAlloc_(%d, %d, %s) is failed.", "ksys::evt::OrderParam", type,
size, name.cstr());
- for (s32 i = 0; i < mEntries.size(); i++) {
- auto* e = &mEntries[i];
+ OrderParamEntry* entry = getFreeEntry(); // inlining here fixed the for loop
- if (!e->mPointer) {
- void** in_ptr = &(e->mPointer);
- std::nothrow_t nothrow_t;
- auto* heap = mHeap;
- if (!heap)
- return nullptr;
+ if (!entry)
+ return nullptr;
+ auto* heap = mHeap;
+ if (!heap)
+ return nullptr;
+ std::nothrow_t nothrow;
- e->mName = new (heap, nothrow_t) sead::FixedSafeString<0x20>(name);
- 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_2:
- *in_ptr = new (heap, nothrow_t) u32(0);
- size = sizeof(u32);
- break;
+ entry->mName =
+ new (heap, nothrow) sead::FixedSafeString<0x20>(name); // scheduling mismatches here
+ // entry->mName = new_name;
+ // inlining here doesn't fix the mismatch
- case OrderParamType::BYTE:
- *in_ptr = new (heap, nothrow_t) char(0);
- size = sizeof(char);
- break;
- case OrderParamType::ACTOR:
- *in_ptr = new (heap, nothrow_t) ksys::act::BaseProcLink;
- size = sizeof(ksys::act::BaseProcLink);
- break;
- case OrderParamType::ARRAY:
- *in_ptr = new (heap, nothrow_t) char[size];
- default:
- 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) {
+ switch (type) {
+ case OrderParamType::INT:
+ case OrderParamType::INT_2:
+ doAlloc(entry, new (heap, nothrow) s32(0));
+ break;
+ case OrderParamType::STRING:
+ doAlloc(entry,
+ new (heap, nothrow) sead::FixedSafeString<0x40>); // scheduling mismatches here
+ break;
+ case OrderParamType::BYTE:
+ doAlloc(entry, new (heap, nothrow) char(0));
+ break;
+ case OrderParamType::ACTOR:
+ doAlloc(entry, new (heap, nothrow) ksys::act::BaseProcLink);
+ break;
+ case OrderParamType::ARRAY:
+ doAlloc(entry, new (heap, nothrow) char[size], size);
+ break;
+ default:
+ break;
+ }
- //} 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 nullptr;
+ return entry;
}
-// 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,
u32* out_size) const {
const u32 hash = sead::HashCRC32::calcStringHash(name);
diff --git a/src/KingSystem/Event/evtOrderParam.h b/src/KingSystem/Event/evtOrderParam.h
index 5eff171c..52a7295c 100644
--- a/src/KingSystem/Event/evtOrderParam.h
+++ b/src/KingSystem/Event/evtOrderParam.h
@@ -20,12 +20,12 @@ enum class OrderParamType : u16 {
};
struct OrderParamEntry {
- u32 mHash = 0;
+ u32 mHash;
// u32 _4; alignment gap
- sead::SafeString* mName = nullptr;
- void* mPointer = nullptr; //_10
- u32 mSize = 0; //_18
- OrderParamType mType = OrderParamType::INVALID;
+ sead::SafeString* mName;
+ void* mPointer; //_10
+ u32 mSize; //_18
+ OrderParamType mType;
// u16 _1e; alignment gap
};
@@ -53,7 +53,7 @@ public:
private:
bool doAssign(OrderParam* other);
- // OrderParamEntry* getEntryByName(const sead::SafeString& name, OrderParamType type);
+ OrderParamEntry* getFreeEntry();
void* getPointerByName(const sead::SafeString& name, OrderParamType type,
u32* out_size = nullptr) const;
@@ -78,6 +78,13 @@ private:
return nullptr;
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) {
e->mHash = 0;
@@ -86,6 +93,7 @@ private:
e->mName = nullptr;
e->mPointer = nullptr;
}
+
sead::ExpHeap* mHeap;
sead::Buffer<OrderParamEntry> mEntries;
u32 mEntryCount = 0;