Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ jobs:
- name: run
run: bin${{ inputs.sep }}TestMain

big_blocks:
runs-on: ${{ inputs.os }}
name: haxe (big blocks)
defaults:
run:
working-directory: test/haxe
steps:
- name: checkout
uses: actions/checkout@v4
- name: setup
uses: ./.github/workflows/setup
with:
haxe: ${{ inputs.haxe }}
- name: build
run: haxe compile.hxml --debug -D HXCPP_GC_BIG_BLOCKS -D ${{ env.HXCPP_ARCH_FLAG }}
- name: run
run: bin${{ inputs.sep }}TestMain-debug

cffi:
runs-on: ${{ inputs.os }}
name: cffi
Expand Down
36 changes: 29 additions & 7 deletions src/hx/gc/Immix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <thread>
#include <condition_variable>
#include <inttypes.h>
#include <limits>

#ifdef __EMSCRIPTEN__
#include <emscripten/stack.h>
Expand Down Expand Up @@ -494,13 +495,13 @@ extern void scriptMarkStack(hx::MarkContext *);
using BlockIdType = unsigned short;
#endif

constexpr uint16_t IMMIX_BLOCK_SIZE{ 1 << IMMIX_BLOCK_BITS };
constexpr uint32_t IMMIX_BLOCK_SIZE{ 1 << IMMIX_BLOCK_BITS };
constexpr uint16_t IMMIX_BLOCK_OFFSET_MASK{ IMMIX_BLOCK_SIZE - 1 };
constexpr uint8_t IMMIX_LINE_COUNT_BITS{ IMMIX_BLOCK_BITS - IMMIX_LINE_BITS };
constexpr uint16_t IMMIX_LINES{ 1 << IMMIX_LINE_COUNT_BITS };
constexpr uintptr_t IMMIX_BLOCK_BASE_MASK{ ~uintptr_t{ IMMIX_BLOCK_OFFSET_MASK } };
constexpr uint8_t IMMIX_HEADER_LINES{ IMMIX_LINES >> IMMIX_LINE_BITS };
constexpr uint8_t IMMIX_USEFUL_LINES{ IMMIX_LINES - IMMIX_HEADER_LINES };
constexpr uint16_t IMMIX_USEFUL_LINES{ IMMIX_LINES - IMMIX_HEADER_LINES };
constexpr uint8_t IMMIX_MAX_ALLOC_GROUPS_SIZE{ 1 << IMMIX_BLOCK_GROUP_BITS };

// Every second line used
Expand Down Expand Up @@ -750,11 +751,11 @@ struct BlockDataInfo
HoleRange mRanges[MAX_HOLES];
uint8_t mHoles;

uint8_t mUsedRows;
uint16_t mUsedRows;
uint16_t mMaxHoleSize;
int mMoveScore;
uint16_t mUsedBytes;
uint8_t mFraggedRows;
uint16_t mFraggedRows;
bool mPinned;
unsigned char mZeroed;
bool mReclaimed;
Expand Down Expand Up @@ -894,8 +895,22 @@ struct BlockDataInfo
bool isEmpty() const { return mUsedRows == 0; }
int getUsedRows() const { return mUsedRows; }

// A row count above the block's useful lines is corrupted GC state, about to be
// added into the heap stats that size working memory.
void checkRowCounts() const
{
#ifdef HXCPP_DEBUG
if (mUsedRows>IMMIX_USEFUL_LINES || mFraggedRows>IMMIX_USEFUL_LINES)
{
GCLOG("Bad block row counts: used %d, fragged %d, max %d\n", (int)mUsedRows, (int)mFraggedRows, (int)IMMIX_USEFUL_LINES);
DebuggerTrap();
}
#endif
}

void getStats(BlockDataStats &outStats)
{
checkRowCounts();
outStats.rowsInUse += mUsedRows;
outStats.bytesInUse += mUsedBytes;
outStats.fraggedRows += mFraggedRows;
Expand Down Expand Up @@ -976,6 +991,7 @@ struct BlockDataInfo

mZeroLock = 0;
mOwned = false;
checkRowCounts();
outStats.rowsInUse += mUsedRows;
outStats.bytesInUse += mUsedBytes;
outStats.fraggedRows += mFraggedRows;
Expand Down Expand Up @@ -1145,6 +1161,7 @@ struct BlockDataInfo
mMoveScore = calcFragScore();
mReclaimed = true;

checkRowCounts();
if (outStats)
{
outStats->rowsInUse += mUsedRows;
Expand Down Expand Up @@ -1414,6 +1431,11 @@ struct BlockDataInfo
#endif
};

static_assert(IMMIX_USEFUL_LINES <= std::numeric_limits<decltype(BlockDataInfo::mUsedRows)>::max(),
"BlockDataInfo::mUsedRows must hold IMMIX_USEFUL_LINES");
static_assert(IMMIX_USEFUL_LINES <= std::numeric_limits<decltype(BlockDataInfo::mFraggedRows)>::max(),
"BlockDataInfo::mFraggedRows must hold IMMIX_USEFUL_LINES");

static bool SmallestFreeFirst(BlockDataInfo *inA, BlockDataInfo *inB)
{
return inA->mMaxHoleSize < inB->mMaxHoleSize;
Expand Down Expand Up @@ -5764,7 +5786,7 @@ class LocalAllocator : public hx::StackContext
uint8_t mCurrentHole;
uint8_t mCurrentHoles;
HoleRange *mCurrentRange;
uint8_t *mFraggedRows;
uint16_t *mFraggedRows;

bool mMoreHoles;

Expand Down Expand Up @@ -6255,7 +6277,7 @@ class LocalAllocator : public hx::StackContext
// spaceOversize might have been set to zero for quick-termination of alloc.
unsigned char* s{ spaceOversize };
if (s>spaceFirst && mFraggedRows)
*mFraggedRows += static_cast<uint8_t>((s - spaceFirst) >> IMMIX_LINE_BITS);
*mFraggedRows += static_cast<uint16_t>((s - spaceFirst) >> IMMIX_LINE_BITS);
#else
#ifdef HXCPP_ALIGN_ALLOC
if (!(size_t{ spaceStart } & 0x4))
Expand Down Expand Up @@ -6292,7 +6314,7 @@ class LocalAllocator : public hx::StackContext
}
if (mFraggedRows && spaceEnd > spaceStart)
{
*mFraggedRows += static_cast<uint8_t>((spaceEnd - spaceStart) >> IMMIX_LINE_BITS);
*mFraggedRows += static_cast<uint16_t>((spaceEnd - spaceStart) >> IMMIX_LINE_BITS);
}
#endif

Expand Down
Loading