#ifndef MRT_BASE_OBJECT_H
#define MRT_BASE_OBJECT_H
#include "Common/StateWord.h"
#include "ObjectModel/Field.h"
#include "ObjectModel/MClass.inline.h"
#include "ObjectModel/RefField.h"
namespace MapleRuntime {
class BaseObject {
public:
TypeInfo* GetTypeInfo() const;
inline bool HasRefField() const { return GetTypeInfo()->HasRefField(); }
inline bool IsWeakRef() const { return GetTypeInfo()->IsWeakRefType(); }
inline bool IsValidObject() const { return stateWord.IsValidStateWord(); }
inline bool IsRawArray() const { return GetTypeInfo()->IsRawArray(); }
inline TypeInfo* GetComponentTypeInfo() const { return GetTypeInfo()->GetComponentTypeInfo(); }
inline GCTib GetGCTib() const { return GetTypeInfo()->GetGCTib(); }
void ForEachRefField(const RefFieldVisitor& visitor);
void ForEachRefInStruct(const RefFieldVisitor& visitor, MAddress aggStart, MAddress aggEnd);
size_t GetSize() const;
size_t GetSize(TypeInfo* kls) const;
bool CompareExchangeRefField(RefField<>& field, const RefField<> oldRef, const RefField<> newRef);
template<bool isVolatile = false>
RefField<isVolatile>& GetRefField(U32 offset) const
{
auto addr = reinterpret_cast<uintptr_t>(this) + offset;
return *reinterpret_cast<RefField<isVolatile>*>(addr);
}
template<typename T>
Field<T>& GetField(U32 offset) const
{
auto addr = reinterpret_cast<uintptr_t>(this) + offset;
return *reinterpret_cast<Field<T>*>(static_cast<Uptr>(addr));
}
#if defined(MRT_DEBUG) && (MRT_DEBUG == 1)
void DumpObject(int logtype, bool isSimple = false) const;
#endif
StateWord GetStateWord() const { return stateWord.GetStateWord(); }
ObjectState GetObjectState() const { return stateWord.GetObjectState(); }
bool IsForwarded() const { return GetObjectState().IsForwardedState(); }
void SetClassInfo(TypeInfo* klassRef) { stateWord.SetTypeInfo(klassRef); }
void SetStateCode(ObjectState::ObjectStateCode state) { stateWord.SetStateCode(state); }
bool IsInTraceRegion() const;
bool TryLockObject(const StateWord curWord) { return stateWord.TryLockStateWord(curWord.GetObjectState()); }
void UnlockObject(const ObjectState newState) { stateWord.UnlockStateWord(newState); }
void OnFinalizerCreated();
static intptr_t FieldOffset(const BaseObject* obj, const void* field)
{
return reinterpret_cast<intptr_t>(field) - reinterpret_cast<intptr_t>(obj);
}
protected:
static inline BaseObject* SetClassInfo(MAddress address, TypeInfo* klass)
{
auto ref = reinterpret_cast<BaseObject*>(address);
ref->stateWord.SetTypeInfo(klass);
return ref;
}
private:
BaseObject() = delete;
~BaseObject() = delete;
void ForEachAggRefFieldInArray(const RefFieldVisitor& visitor, MAddress aggStart, MAddress aggEnd);
void ForEachAggRefFieldInNonArray(const RefFieldVisitor& visitor, MAddress aggStart, MAddress aggEnd) const;
StateWord stateWord;
};
using ObjectPtr = BaseObject*;
using ObjectVisitor = std::function<void(ObjectPtr)>;
struct ObjectRef {
BaseObject* object;
};
using RawRefVisitor = std::function<void(ObjectRef&)>;
using RootVisitor = RawRefVisitor;
using StackPtrVisitor = RawRefVisitor;
}
#endif