Skip to content

Commit

Permalink
Eliminated GC step1.
Browse files Browse the repository at this point in the history
  • Loading branch information
kekyo committed Apr 5, 2019
1 parent 26428d5 commit 3655cbf
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 29 deletions.
1 change: 1 addition & 0 deletions IL2C.Runtime/src/Private/arduino_all.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern void il2c_free(void* p);

#define il2c_iand(pDest, newValue) __sync_fetch_and_and((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ior(pDest, newValue) __sync_fetch_and_or((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ixor(pDest, newValue) __sync_fetch_and_xor((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_iinc(pDest) __sync_add_and_fetch((interlock_t*)(pDest), 1)
#define il2c_idec(pDest) __sync_sub_and_fetch((interlock_t*)(pDest), 1)
#define il2c_ixchg(pDest, newValue) __sync_lock_test_and_set((interlock_t*)(pDest), (interlock_t)(newValue))
Expand Down
1 change: 1 addition & 0 deletions IL2C.Runtime/src/Private/gcc_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ extern void il2c_free(void* p);

#define il2c_iand(pDest, newValue) __sync_fetch_and_and((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ior(pDest, newValue) __sync_fetch_and_or((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ixor(pDest, newValue) __sync_fetch_and_xor((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_iinc(pDest) __sync_add_and_fetch((interlock_t*)(pDest), 1)
#define il2c_idec(pDest) __sync_sub_and_fetch((interlock_t*)(pDest), 1)
#define il2c_ixchg(pDest, newValue) __sync_lock_test_and_set((interlock_t*)(pDest), (interlock_t)(newValue))
Expand Down
1 change: 1 addition & 0 deletions IL2C.Runtime/src/Private/gcc_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ extern wchar_t* il2c_u64tow(uint64_t value, wchar_t* buffer, int radix);

#define il2c_iand(pDest, newValue) __sync_fetch_and_and((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ior(pDest, newValue) __sync_fetch_and_or((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ixor(pDest, newValue) __sync_fetch_and_xor((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_iinc(pDest) __sync_add_and_fetch((interlock_t*)(pDest), 1)
#define il2c_idec(pDest) __sync_sub_and_fetch((interlock_t*)(pDest), 1)
#define il2c_ixchg(pDest, newValue) __sync_lock_test_and_set((interlock_t*)(pDest), (interlock_t)(newValue))
Expand Down
1 change: 1 addition & 0 deletions IL2C.Runtime/src/Private/msvc_uefi.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ extern void il2c_free(void* p);

#define il2c_iand(pDest, newValue) _InterlockedAnd((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ior(pDest, newValue) _InterlockedOr((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ixor(pDest, newValue) _InterlockedXor((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_iinc(pDest) _InterlockedIncrement((interlock_t*)(pDest))
#define il2c_idec(pDest) _InterlockedDecrement((interlock_t*)(pDest))
#define il2c_ixchg(pDest, newValue) _InterlockedExchange((interlock_t*)(pDest), (interlock_t)(newValue))
Expand Down
1 change: 1 addition & 0 deletions IL2C.Runtime/src/Private/msvc_wdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ extern "C" {

#define il2c_iand(pDest, newValue) _InterlockedAnd((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ior(pDest, newValue) _InterlockedOr((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ixor(pDest, newValue) _InterlockedXor((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_iinc(pDest) _InterlockedIncrement((interlock_t*)(pDest))
#define il2c_idec(pDest) _InterlockedDecrement((interlock_t*)(pDest))
#define il2c_ixchg(pDest, newValue) _InterlockedExchange((interlock_t*)(pDest), (interlock_t)(newValue))
Expand Down
1 change: 1 addition & 0 deletions IL2C.Runtime/src/Private/msvc_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ extern wchar_t* il2c_u64tow(uint64_t value, wchar_t* buffer, int radix);

#define il2c_iand(pDest, newValue) _InterlockedAnd((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ior(pDest, newValue) _InterlockedOr((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_ixor(pDest, newValue) _InterlockedXor((interlock_t*)(pDest), (interlock_t)(newValue))
#define il2c_iinc(pDest) _InterlockedIncrement((interlock_t*)(pDest))
#define il2c_idec(pDest) _InterlockedDecrement((interlock_t*)(pDest))
#define il2c_ixchg(pDest, newValue) _InterlockedExchange((interlock_t*)(pDest), (interlock_t)(newValue))
Expand Down
49 changes: 21 additions & 28 deletions IL2C.Runtime/src/il2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static IL2C_STATIC_FIELDS* g_pBeginStaticFields__ = NULL;

static IL2C_MONITOR_LOCK_BLOCK_INFORMATION* g_MonitorLockBlockInformations[7] = { NULL };

static interlock_t g_CollectionMarkIndex__ = 0; // IL2C_CHARACTERISTIC_MARK_INDEX;
static interlock_t g_ExecutingCollection__ = 0;

// The initializer count produces when works the type initializer.
Expand Down Expand Up @@ -106,9 +107,10 @@ void* il2c_get_uninitialized_object_internal__(
// Guarantee cleared body
memset(pReference, 0, bodySize);

pHeader->pNext = NULL;
pHeader->type = type;
pHeader->characteristic = 0;

// HACK: Current GC mark status is same as g_CollectionMarkIndex__, it means "Marked."
pHeader->characteristic = g_CollectionMarkIndex__;

// Safe link both headers.
while (1)
Expand Down Expand Up @@ -679,12 +681,12 @@ static void il2c_release_all_monitor_lock_for_final_shutdown__(void)
/////////////////////////////////////////////////////////////
// Internal GC mark handlers

// Has to ignore if objref is const.
// Has to ignore if objref is const. (NOT const and NOT marked)
// HACK: It's shame the icmpxchg may cause system fault if header is placed at read-only memory (CONST).
// (at x86/x64 cause, another platform may cause)
#define TRY_GET_HEADER(pHeader, pAdjustedReference) \
IL2C_REF_HEADER* pHeader = il2c_get_header__(pAdjustedReference); \
if (il2c_unlikely__((pHeader->characteristic & (IL2C_CHARACTERISTIC_CONST | IL2C_CHARACTERISTIC_LIVE)) == 0))
if (il2c_unlikely__(((pHeader->characteristic & (IL2C_CHARACTERISTIC_CONST | IL2C_CHARACTERISTIC_MARK_INDEX)) ^ IL2C_CHARACTERISTIC_MARK_INDEX) == g_CollectionMarkIndex__))

static void il2c_mark_handler_recursive__(void* pTarget, IL2C_RUNTIME_TYPE type, const uint8_t offset);

Expand All @@ -698,14 +700,14 @@ static void il2c_mark_handler_for_objref__(System_Object* pAdjustedReference)
il2c_assert(pHeader->type != NULL);

// Marking with atomicity.
interlock_t characteristic = il2c_ior(&pHeader->characteristic, IL2C_CHARACTERISTIC_LIVE);
if (il2c_likely__((characteristic & IL2C_CHARACTERISTIC_LIVE) == IL2C_CHARACTERISTIC_LIVE))
const interlock_t lastCharacteristic = il2c_ixor(&pHeader->characteristic, IL2C_CHARACTERISTIC_MARK_INDEX);
if (il2c_likely__((lastCharacteristic & IL2C_CHARACTERISTIC_MARK_INDEX) == g_CollectionMarkIndex__))
{
il2c_runtime_debug_log_format(
L"il2c_mark_handler_for_objref__ [1]: pAdjustedReference=0x{0:p}, type={1:s}, characteristic=0x{2:x}",
L"il2c_mark_handler_for_objref__ [1]: pAdjustedReference=0x{0:p}, type={1:s}, lastCharacteristic=0x{2:x}",
pAdjustedReference,
pHeader->type->pTypeName,
characteristic);
lastCharacteristic);
// Already marked/fixed/constant
return;
}
Expand Down Expand Up @@ -842,21 +844,6 @@ static void il2c_mark_handler_recursive__(void* pTarget, IL2C_RUNTIME_TYPE type,
/////////////////////////////////////////////////////////////
// GC processes

static void il2c_step1_clear_gcmark__(void)
{
// It has to invoke from inside for GC process.
il2c_assert(g_ExecutingCollection__ >= 1);

// Clear header marks.
IL2C_REF_HEADER* pCurrentHeader = g_pBeginHeader__;
while (il2c_likely__(pCurrentHeader != NULL))
{
// Drop live marking.
il2c_iand(&pCurrentHeader->characteristic, ~IL2C_CHARACTERISTIC_LIVE);
pCurrentHeader = pCurrentHeader->pNext;
}
}

static void il2c_step2_mark_gcmark__(IL2C_GC_TRACKING_INFORMATION* pBeginFrame)
{
// It has to invoke from inside for GC process.
Expand Down Expand Up @@ -981,7 +968,7 @@ static void il2c_step3_sweep_garbage__(void)
while (il2c_likely__(pCurrentHeader != NULL))
{
IL2C_REF_HEADER* pNext = pCurrentHeader->pNext;
if (il2c_unlikely__((pCurrentHeader->characteristic & IL2C_CHARACTERISTIC_LIVE) == 0))
if (il2c_unlikely__((pCurrentHeader->characteristic & IL2C_CHARACTERISTIC_MARK_INDEX) != g_CollectionMarkIndex__))
{
// Very important unlink step: because cause misread on purpose this__ instance is living.
*ppUnlinkTarget = pNext;
Expand Down Expand Up @@ -1091,8 +1078,11 @@ void il2c_collect__(void)
//////////////////////////////////////////////////
// GC Step 1:

il2c_step1_clear_gcmark__();
il2c_check_heap();
// Note: Traditional mark-sweep GC's first step is clearing markings.
// The IL2C GC skips this step and mark/clear flag indicates with inverse arithmetic
// between g_CollectionMarkIndex__ and characteristic's MARK_INDEX.
// The instances characteristic MARK_INDEX will indicate last stats, so makes NOT MARKED if inversed this flag.
il2c_ixor(&g_CollectionMarkIndex__, IL2C_CHARACTERISTIC_MARK_INDEX);

//////////////////////////////////////
// GC Step 2:
Expand Down Expand Up @@ -1157,8 +1147,11 @@ static void il2c_collect_for_final_shutdown__(void)
//////////////////////////////////////////////////
// GC Step 1:

il2c_step1_clear_gcmark__();
il2c_check_heap();
// Note: Traditional mark-sweep GC's first step is clearing markings.
// The IL2C GC skips this step and mark/clear flag indicates with inverse arithmetic
// between g_CollectionMarkIndex__ and characteristic's MARK_INDEX.
// The instances characteristic MARK_INDEX will indicate last stats, so makes NOT MARKED if inversed this flag.
il2c_ixor(&g_CollectionMarkIndex__, IL2C_CHARACTERISTIC_MARK_INDEX);

//////////////////////////////////////
// GC Step 2:
Expand Down
2 changes: 1 addition & 1 deletion IL2C.Runtime/src/il2c_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ struct IL2C_RUNTIME_TYPE_DECL
// IL2C_REF_HEADER_DECL.characteristic
#define IL2C_CHARACTERISTIC_ACQUIRED_MONITOR_LOCK ((interlock_t)0x10000000UL)
#define IL2C_CHARACTERISTIC_SUPPRESS_FINALIZE ((interlock_t)0x20000000UL)
#define IL2C_CHARACTERISTIC_LIVE ((interlock_t)0x40000000UL)
#define IL2C_CHARACTERISTIC_MARK_INDEX ((interlock_t)0x40000000UL) // Mark index is only 0 or 1.
#define IL2C_CHARACTERISTIC_CONST ((interlock_t)0x80000000UL)

#define il2c_get_header__(pReference) \
Expand Down

0 comments on commit 3655cbf

Please sign in to comment.