[add] first
This commit is contained in:
55
Libraries/libil2cpp/include/gc/Allocator.h
Normal file
55
Libraries/libil2cpp/include/gc/Allocator.h
Normal file
@@ -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; }
|
||||
};
|
||||
}
|
||||
}
|
||||
127
Libraries/libil2cpp/include/gc/AppendOnlyGCHashMap.h
Normal file
127
Libraries/libil2cpp/include/gc/AppendOnlyGCHashMap.h
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/Il2CppHashMap.h"
|
||||
#include "utils/NonCopyable.h"
|
||||
#include "GarbageCollector.h"
|
||||
#include "os/FastReaderReaderWriterLock.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)
|
||||
{
|
||||
os::FastReaderReaderWriterAutoSharedLock readLock(&lock);
|
||||
return m_Map.find(k) != m_Map.end();
|
||||
}
|
||||
|
||||
// Returns the existing value if the it was already added or inserts and returns value
|
||||
T GetOrAdd(const Key& k, T value)
|
||||
{
|
||||
os::FastReaderReaderWriterAutoExclusiveLock writeLock(&lock);
|
||||
|
||||
ConstIterator iter = m_Map.find(k);
|
||||
if (iter != m_Map.end())
|
||||
{
|
||||
size_t index = iter->second;
|
||||
IL2CPP_ASSERT(index <= m_Map.size());
|
||||
return m_Data[index];
|
||||
}
|
||||
|
||||
if (m_Size == 0)
|
||||
{
|
||||
m_Size = 8;
|
||||
m_Data = (T*)il2cpp::gc::GarbageCollector::AllocateFixed(m_Size * sizeof(T), NULL);
|
||||
IL2CPP_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;
|
||||
IL2CPP_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));
|
||||
|
||||
IL2CPP_ASSERT(m_Map.size() <= m_Size);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool TryGetValue(const Key& k, T* value)
|
||||
{
|
||||
os::FastReaderReaderWriterAutoSharedLock readLock(&lock);
|
||||
|
||||
ConstIterator iter = m_Map.find(k);
|
||||
if (iter == m_Map.end())
|
||||
return false;
|
||||
|
||||
size_t index = iter->second;
|
||||
IL2CPP_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;
|
||||
os::FastReaderReaderWriterLock lock;
|
||||
};
|
||||
}
|
||||
}
|
||||
38
Libraries/libil2cpp/include/gc/GCHandle.h
Normal file
38
Libraries/libil2cpp/include/gc/GCHandle.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/Expected.h"
|
||||
#include "utils/Il2CppError.h"
|
||||
|
||||
#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 utils::Expected<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 utils::Expected<uint32_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 */
|
||||
114
Libraries/libil2cpp/include/gc/GarbageCollector.h
Normal file
114
Libraries/libil2cpp/include/gc/GarbageCollector.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#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 UninitializeGC();
|
||||
static void AddMemoryPressure(int64_t value);
|
||||
static int32_t GetMaxGeneration();
|
||||
static int32_t GetGeneration(void* addr);
|
||||
#if !RUNTIME_TINY
|
||||
static void InitializeFinalizer();
|
||||
static bool IsFinalizerThread(Il2CppThread* thread);
|
||||
static void UninitializeFinalizers();
|
||||
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 Il2CppIUnknown* GetOrCreateCCW(Il2CppObject* obj, const Il2CppGuid& iid);
|
||||
#endif
|
||||
|
||||
// functions implemented in a GC specific manner
|
||||
static void Initialize();
|
||||
|
||||
// Deprecated. Remove when Unity has switched to mono_unity_gc_set_mode
|
||||
static void Enable();
|
||||
// Deprecated. Remove when Unity has switched to mono_unity_gc_set_mode
|
||||
static void Disable();
|
||||
// Deprecated. Remove when Unity has switched to mono_unity_gc_set_mode
|
||||
static bool IsDisabled();
|
||||
|
||||
static void SetMode(Il2CppGCMode mode);
|
||||
|
||||
static bool IsIncremental();
|
||||
static void StartIncrementalCollection();
|
||||
|
||||
static int64_t GetMaxTimeSliceNs();
|
||||
static void SetMaxTimeSliceNs(int64_t maxTimeSlice);
|
||||
|
||||
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();
|
||||
|
||||
#if RUNTIME_TINY
|
||||
static void* Allocate(size_t size);
|
||||
static void* AllocateObject(size_t size, void* type);
|
||||
#endif
|
||||
|
||||
static void* AllocateFixed(size_t size, void *descr);
|
||||
static void FreeFixed(void* addr);
|
||||
|
||||
static bool RegisterThread(void *baseptr);
|
||||
static bool UnregisterThread();
|
||||
|
||||
#if !RUNTIME_TINY
|
||||
static bool HasPendingFinalizers();
|
||||
static int32_t InvokeFinalizers();
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
static void SetSkipThread(bool skip);
|
||||
|
||||
static bool EphemeronArrayAdd(Il2CppObject* obj);
|
||||
};
|
||||
} /* namespace vm */
|
||||
} /* namespace il2cpp */
|
||||
43
Libraries/libil2cpp/include/gc/WriteBarrier.h
Normal file
43
Libraries/libil2cpp/include/gc/WriteBarrier.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
struct Il2CppObject;
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace gc
|
||||
{
|
||||
class WriteBarrier
|
||||
{
|
||||
public:
|
||||
static void GenericStore(void** ptr, void* value);
|
||||
|
||||
template<typename TPtr, typename TValue>
|
||||
static void GenericStore(TPtr** ptr, TValue* value)
|
||||
{
|
||||
static_assert((std::is_assignable<TPtr*&, TValue*>::value), "Pointers types are not assignment compatible");
|
||||
GenericStore((void**)ptr, (void*)value);
|
||||
}
|
||||
|
||||
template<typename TPtr>
|
||||
static void GenericStoreNull(TPtr** ptr)
|
||||
{
|
||||
*ptr = NULL;
|
||||
}
|
||||
};
|
||||
} /* gc */
|
||||
} /* il2cpp */
|
||||
|
||||
#define IL2CPP_OBJECT_SETREF(obj, fieldname, value) do {\
|
||||
il2cpp::gc::WriteBarrier::GenericStore(&(obj)->fieldname, (value));\
|
||||
} while (0)
|
||||
|
||||
/* This should be used if 's' can reside on the heap */
|
||||
#define IL2CPP_STRUCT_SETREF(s, fieldname, value) do {\
|
||||
il2cpp::gc::WriteBarrier::GenericStore(&(s)->fieldname, (value));\
|
||||
} while (0)
|
||||
|
||||
#define IL2CPP_OBJECT_SETREF_NULL(obj, fieldname) do {\
|
||||
il2cpp::gc::WriteBarrier::GenericStoreNull(&(obj)->fieldname);\
|
||||
} while (0)
|
||||
22
Libraries/libil2cpp/include/gc/WriteBarrierValidation.h
Normal file
22
Libraries/libil2cpp/include/gc/WriteBarrierValidation.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#if IL2CPP_ENABLE_WRITE_BARRIER_VALIDATION
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace gc
|
||||
{
|
||||
class WriteBarrierValidation
|
||||
{
|
||||
public:
|
||||
typedef void(*ExternalAllocationTrackerFunction)(void*, size_t, int);
|
||||
static void SetExternalAllocationTracker(ExternalAllocationTrackerFunction func);
|
||||
typedef void(*ExternalWriteBarrierTrackerFunction)(void**);
|
||||
static void SetExternalWriteBarrierTracker(ExternalWriteBarrierTrackerFunction func);
|
||||
|
||||
static void Setup();
|
||||
static void Run();
|
||||
};
|
||||
} /* gc */
|
||||
} /* il2cpp */
|
||||
#endif
|
||||
28
Libraries/libil2cpp/include/gc/gc_wrapper.h
Normal file
28
Libraries/libil2cpp/include/gc/gc_wrapper.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#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"
|
||||
#include "gc_vector.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