Initial commit.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
#include "GarbageCollector.h"
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace gc
|
||||
{
|
||||
template<typename T>
|
||||
class Allocator
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
typedef Allocator<T> allocator_type;
|
||||
Allocator() {}
|
||||
Allocator(const Allocator&) {}
|
||||
|
||||
pointer allocate(size_type n, const void * = 0)
|
||||
{
|
||||
T* t = (T*)GarbageCollector::AllocateFixed(n * sizeof(T), 0);
|
||||
return t;
|
||||
}
|
||||
|
||||
void deallocate(void* p, size_type)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
GarbageCollector::FreeFixed(p);
|
||||
}
|
||||
}
|
||||
|
||||
pointer address(reference x) const { return &x; }
|
||||
const_pointer address(const_reference x) const { return &x; }
|
||||
Allocator<T>& operator=(const Allocator&) { return *this; }
|
||||
void construct(pointer p, const T& val) { new((T*)p)T(val); }
|
||||
void destroy(pointer p) { p->~T(); }
|
||||
|
||||
size_type max_size() const { return size_t(-1); }
|
||||
|
||||
template<class U>
|
||||
struct rebind { typedef Allocator<U> other; };
|
||||
|
||||
template<class U>
|
||||
Allocator(const Allocator<U>&) {}
|
||||
|
||||
template<class U>
|
||||
Allocator& operator=(const Allocator<U>&) { return *this; }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/Il2CppHashMap.h"
|
||||
#include "utils/NonCopyable.h"
|
||||
#include "GarbageCollector.h"
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace gc
|
||||
{
|
||||
template<class Key, class T,
|
||||
class HashFcn,
|
||||
class EqualKey = std::equal_to<Key> >
|
||||
class AppendOnlyGCHashMap : public il2cpp::utils::NonCopyable
|
||||
{
|
||||
typedef Il2CppHashMap<Key, size_t, HashFcn, EqualKey> hash_map_type;
|
||||
typedef typename Il2CppHashMap<Key, size_t, HashFcn, EqualKey>::const_iterator ConstIterator;
|
||||
public:
|
||||
|
||||
typedef typename hash_map_type::key_type key_type;
|
||||
typedef T data_type;
|
||||
typedef typename hash_map_type::size_type size_type;
|
||||
typedef typename hash_map_type::hasher hasher;
|
||||
typedef typename hash_map_type::key_equal key_equal;
|
||||
|
||||
AppendOnlyGCHashMap() :
|
||||
m_Data(NULL),
|
||||
m_Size(0)
|
||||
{
|
||||
}
|
||||
|
||||
~AppendOnlyGCHashMap()
|
||||
{
|
||||
if (m_Data)
|
||||
il2cpp::gc::GarbageCollector::FreeFixed(m_Data);
|
||||
}
|
||||
|
||||
bool Contains(const Key& k)
|
||||
{
|
||||
return m_Map.find(k) != m_Map.end();
|
||||
}
|
||||
|
||||
// Returns true if value was added. False if it already existed
|
||||
bool Add(const Key& k, T value)
|
||||
{
|
||||
if (m_Map.find(k) != m_Map.end())
|
||||
return false;
|
||||
|
||||
if (m_Size == 0)
|
||||
{
|
||||
m_Size = 8;
|
||||
m_Data = (T*)il2cpp::gc::GarbageCollector::AllocateFixed(m_Size * sizeof(T), NULL);
|
||||
assert(m_Data);
|
||||
}
|
||||
else if (m_Map.size() == m_Size)
|
||||
{
|
||||
size_t newSize = 2 * m_Size;
|
||||
T* newData = (T*)il2cpp::gc::GarbageCollector::AllocateFixed(newSize * sizeof(T), NULL);
|
||||
|
||||
MemCpyData memCpyData = { newData, m_Data, m_Size * sizeof(T) };
|
||||
// perform memcpy with GC lock held so GC doesn't see torn pointer values.I think this is less of an issue with Boehm than other GCs, but being safe.
|
||||
il2cpp::gc::GarbageCollector::CallWithAllocLockHeld(&CopyValues, &memCpyData);
|
||||
|
||||
il2cpp::gc::GarbageCollector::FreeFixed(m_Data);
|
||||
|
||||
GarbageCollector::SetWriteBarrier((void**)newData, m_Size * sizeof(T));
|
||||
|
||||
m_Size = newSize;
|
||||
m_Data = newData;
|
||||
assert(m_Data);
|
||||
}
|
||||
|
||||
size_t index = m_Map.size();
|
||||
m_Map.insert(std::make_pair(k, index));
|
||||
m_Data[index] = value;
|
||||
|
||||
GarbageCollector::SetWriteBarrier((void**)(m_Data + index));
|
||||
|
||||
assert(m_Map.size() <= m_Size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryGetValue(const Key& k, T* value)
|
||||
{
|
||||
ConstIterator iter = m_Map.find(k);
|
||||
if (iter == m_Map.end())
|
||||
return false;
|
||||
|
||||
size_t index = iter->second;
|
||||
assert(index <= m_Map.size());
|
||||
*value = m_Data[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
struct MemCpyData
|
||||
{
|
||||
void* dst;
|
||||
const void* src;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static void* CopyValues(void* arg)
|
||||
{
|
||||
MemCpyData* thisPtr = (MemCpyData*)arg;
|
||||
memcpy(thisPtr->dst, thisPtr->src, thisPtr->size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Il2CppHashMap<Key, size_t, HashFcn, EqualKey> m_Map;
|
||||
T* m_Data;
|
||||
size_t m_Size;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct Il2CppObject;
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace gc
|
||||
{
|
||||
enum GCHandleType
|
||||
{
|
||||
HANDLE_WEAK,
|
||||
HANDLE_WEAK_TRACK,
|
||||
HANDLE_NORMAL,
|
||||
HANDLE_PINNED
|
||||
};
|
||||
|
||||
class LIBIL2CPP_CODEGEN_API GCHandle
|
||||
{
|
||||
public:
|
||||
// external
|
||||
static uint32_t New(Il2CppObject *obj, bool pinned);
|
||||
static uint32_t NewWeakref(Il2CppObject *obj, bool track_resurrection);
|
||||
static Il2CppObject* GetTarget(uint32_t gchandle);
|
||||
static GCHandleType GetHandleType(uint32_t gcHandle);
|
||||
static void Free(uint32_t gchandle);
|
||||
public:
|
||||
//internal
|
||||
static int32_t GetTargetHandle(Il2CppObject * obj, int32_t handle, int32_t type);
|
||||
|
||||
typedef void(*WalkGCHandleTargetsCallback)(Il2CppObject* obj, void* context);
|
||||
static void WalkStrongGCHandleTargets(WalkGCHandleTargetsCallback callback, void* context);
|
||||
};
|
||||
} /* gc */
|
||||
} /* il2cpp */
|
||||
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
struct Il2CppGuid;
|
||||
struct Il2CppIUnknown;
|
||||
struct Il2CppObject;
|
||||
struct Il2CppThread;
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace gc
|
||||
{
|
||||
class LIBIL2CPP_CODEGEN_API GarbageCollector
|
||||
{
|
||||
public:
|
||||
static void Collect(int maxGeneration);
|
||||
static int32_t CollectALittle();
|
||||
static int32_t GetCollectionCount(int32_t generation);
|
||||
static int64_t GetUsedHeapSize();
|
||||
#if IL2CPP_ENABLE_WRITE_BARRIERS
|
||||
static void SetWriteBarrier(void **ptr);
|
||||
static void SetWriteBarrier(void **ptr, size_t numBytes);
|
||||
#else
|
||||
static inline void SetWriteBarrier(void **ptr) {}
|
||||
static inline void SetWriteBarrier(void **ptr, size_t numBytes) {}
|
||||
#endif
|
||||
|
||||
public:
|
||||
// internal
|
||||
typedef void (*FinalizerCallback)(void* object, void* client_data);
|
||||
|
||||
// functions implemented in a GC agnostic manner
|
||||
static void InitializeFinalizer();
|
||||
static bool IsFinalizerThread(Il2CppThread* thread);
|
||||
static int32_t GetGeneration(void* addr);
|
||||
static void UninitializeFinalizers();
|
||||
static void UninitializeGC();
|
||||
static void NotifyFinalizers();
|
||||
static void RunFinalizer(void *obj, void *data);
|
||||
static void RegisterFinalizerForNewObject(Il2CppObject* obj);
|
||||
static void RegisterFinalizer(Il2CppObject* obj);
|
||||
static void SuppressFinalizer(Il2CppObject* obj);
|
||||
static void WaitForPendingFinalizers();
|
||||
static int32_t GetMaxGeneration();
|
||||
static void AddMemoryPressure(int64_t value);
|
||||
static Il2CppIUnknown* GetOrCreateCCW(Il2CppObject* obj, const Il2CppGuid& iid);
|
||||
|
||||
// functions implemented in a GC specific manner
|
||||
static void Initialize();
|
||||
static void Enable();
|
||||
static void Disable();
|
||||
static bool IsDisabled();
|
||||
|
||||
static FinalizerCallback RegisterFinalizerWithCallback(Il2CppObject* obj, FinalizerCallback callback);
|
||||
|
||||
static int64_t GetAllocatedHeapSize();
|
||||
|
||||
static void* MakeDescriptorForObject(size_t *bitmap, int numbits);
|
||||
static void* MakeDescriptorForString();
|
||||
static void* MakeDescriptorForArray();
|
||||
|
||||
static void* AllocateFixed(size_t size, void *descr);
|
||||
static void FreeFixed(void* addr);
|
||||
|
||||
static bool RegisterThread(void *baseptr);
|
||||
static bool UnregisterThread();
|
||||
|
||||
static bool HasPendingFinalizers();
|
||||
static int32_t InvokeFinalizers();
|
||||
|
||||
static void AddWeakLink(void **link_addr, Il2CppObject *obj, bool track);
|
||||
static void RemoveWeakLink(void **link_addr);
|
||||
static Il2CppObject *GetWeakLink(void **link_addr);
|
||||
|
||||
/* Used by liveness code */
|
||||
static void StopWorld();
|
||||
static void StartWorld();
|
||||
|
||||
typedef void (*HeapSectionCallback) (void* user_data, void* start, void* end);
|
||||
static void ForEachHeapSection(void* user_data, HeapSectionCallback callback);
|
||||
static size_t GetSectionCount();
|
||||
|
||||
typedef void* (*GCCallWithAllocLockCallback)(void* user_data);
|
||||
static void* CallWithAllocLockHeld(GCCallWithAllocLockCallback callback, void* user_data);
|
||||
|
||||
static void RegisterRoot(char *start, size_t size);
|
||||
static void UnregisterRoot(char* start);
|
||||
|
||||
#if NET_4_0
|
||||
static void SetSkipThread(bool skip);
|
||||
#endif
|
||||
};
|
||||
} /* namespace vm */
|
||||
} /* namespace il2cpp */
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
struct Il2CppObject;
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace gc
|
||||
{
|
||||
class WriteBarrier
|
||||
{
|
||||
public:
|
||||
static void GenericStore(void* ptr, Il2CppObject* value);
|
||||
};
|
||||
} /* gc */
|
||||
} /* il2cpp */
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "il2cpp-config.h"
|
||||
|
||||
#if IL2CPP_GC_BOEHM
|
||||
|
||||
/* here is the defines we build Boehm with */
|
||||
#define IGNORE_DYNAMIC_LOADING 1
|
||||
#define GC_DONT_REGISTER_MAIN_STATIC_DATA 1
|
||||
#if IL2CPP_HAS_GC_DESCRIPTORS
|
||||
#define GC_GCJ_SUPPORT 1
|
||||
#endif
|
||||
#if IL2CPP_SUPPORT_THREADS
|
||||
#define GC_THREADS 1
|
||||
#endif
|
||||
|
||||
#include "gc.h"
|
||||
#include "gc_typed.h"
|
||||
#include "gc_mark.h"
|
||||
#include "gc_gcj.h"
|
||||
|
||||
#define GC_NO_DESCRIPTOR ((void*)(0 | GC_DS_LENGTH))
|
||||
|
||||
#else
|
||||
#define GC_NO_DESCRIPTOR ((void*)0)
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user