Skip to content

Commit

Permalink
Merge remote-tracking branch 'schveiguy/arrayrewrite' into arrayrewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
kinke committed Nov 14, 2024
2 parents 2a63416 + 6244451 commit 04a4618
Show file tree
Hide file tree
Showing 18 changed files with 1,813 additions and 1,362 deletions.
8 changes: 5 additions & 3 deletions druntime/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ endif
DMD=../generated/$(OS)/$(BUILD)/$(MODEL)/dmd$(DOTEXE)
INSTALL_DIR=../../install

SDCALLOC?=../../sdc/lib/libdmdalloc.a

# directory where the html files for the documentation are placed
DOC_OUTPUT_DIR=doc
IMPDIR=import
Expand Down Expand Up @@ -410,8 +412,8 @@ $(DRUNTIMESOLIB): $(OBJS) $(SRCS) $(DMD)

################### Library generation #########################

$(DRUNTIME): $(OBJS) $(SRCS) $(DMD)
$(DMD) -lib -of$(DRUNTIME) -Xfdruntime.json $(DFLAGS) $(SRCS) $(OBJS)
$(DRUNTIME): $(OBJS) $(SRCS) $(DMD) $(SDCALLOC)
$(DMD) -lib -of$(DRUNTIME) $(SDCALLOC) -Xfdruntime.json $(DFLAGS) $(SRCS) $(OBJS)

lib: $(DRUNTIME)

Expand Down Expand Up @@ -462,7 +464,7 @@ UT_DRUNTIMELIB:=$(ROOT)/unittest/libdruntime-ut$(if $(findstring $(OS),windows),

$(UT_DRUNTIME): UDFLAGS+=-version=Shared $(SHAREDFLAGS)
$(UT_DRUNTIME): $(OBJS) $(SRCS) $(DMD)
$(DMD) $(UDFLAGS) -shared $(UTFLAGS) -of$@ $(SRCS) $(OBJS) $(LINKDL) -defaultlib= $(if $(findstring $(OS),windows),user32.lib -L/IMPLIB:$(UT_DRUNTIMELIB),) $(SOLIBS)
$(DMD) $(UDFLAGS) -shared $(UTFLAGS) -of$@ $(SRCS) $(OBJS) $(LINKDL) $(SDCALLOC) -defaultlib= $(if $(findstring $(OS),windows),user32.lib -L/IMPLIB:$(UT_DRUNTIMELIB),) $(SOLIBS)

$(ROOT)/unittest/test_runner$(DOTEXE): $(UT_DRUNTIME) src/test_runner.d $(DMD)
$(DMD) $(UDFLAGS) -of$@ src/test_runner.d -L$(UT_DRUNTIMELIB) -defaultlib= $(if $(findstring $(OS),windows),-dllimport=defaultLibsOnly user32.lib,-L-lpthread -L-lm)
Expand Down
2 changes: 2 additions & 0 deletions druntime/mak/SRCS
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ SRCS=\
src\core\internal\gc\pooltable.d \
src\core\internal\gc\proxy.d \
src\core\internal\gc\impl\conservative\gc.d \
src\core\internal\gc\impl\conservative\blkcache.d \
src\core\internal\gc\impl\manual\gc.d \
src\core\internal\gc\impl\proto\gc.d \
src\core\internal\gc\impl\sdc\gc.d \
\
src\core\internal\util\array.d \
src\core\internal\util\math.d \
Expand Down
140 changes: 132 additions & 8 deletions druntime/src/core/gc/gcinterface.d
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ struct Range
bool opEquals(const scope Range rhs) nothrow const { return pbot == rhs.pbot; }
}

private void setupContextAndBitmap(uint bits, const TypeInfo ti, ref const(void) *context, ref immutable(size_t) *ptrBitmap) nothrow
{
if (ti !is null)
{
context = (bits & BlkAttr.STRUCTFINAL) ? cast(void *)ti : null;
ptrBitmap = cast(immutable size_t *)ti.rtInfo();
}
else
{
context = null;
ptrBitmap = cast(immutable size_t *)rtinfoHasPointers; // note the bits
}
}

interface GC
{
/**
Expand Down Expand Up @@ -74,24 +88,65 @@ interface GC
uint clrAttr(void* p, uint mask) nothrow;

/**
* malloc based on using a TypeInfo. This forwards to malloc with the
* appropriate runtime pointer for the context, and the pointer
* bitmap based on TypeInfo.RTInfo.
*
* The bits determine how TypeInfo is passed according to the
* original rules of the GC.
*/
void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow;
final void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow
{
const(void) *context;
immutable(size_t) *ptrBitmap;
setupContextAndBitmap(bits, ti, context, ptrBitmap);
return malloc(size, bits, context, ptrBitmap);
}

/**
* Newer version of malloc that decouples from TypeInfo. Note that
* STRUCTFINAL is ignored in the bits.
*/
void *malloc(size_t size, uint bits, const void *context, immutable size_t *pointerbitmap) nothrow;

/*
*
*/
BlkInfo qalloc(size_t size, uint bits, const scope TypeInfo ti) nothrow;

/*
*
/**
* Same as malloc, but zero-initializes the data
*/
void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow;
final void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow
{
const(void) *context;
immutable(size_t) *ptrBitmap;
setupContextAndBitmap(bits, ti, context, ptrBitmap);
return calloc(size, bits, context, ptrBitmap);
}

/// ditto
void* calloc(size_t size, uint bits, const void* context, immutable size_t* pointerBitmap) nothrow;

/*
*
* realloc a block. The original block is freed.
*/
void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow;
final void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow
{
immutable(size_t) *ptrBitmap;
// no context pointer for realloc (it's not allowed)
if (ti !is null)
{
ptrBitmap = cast(immutable size_t*)ti.rtInfo();
}
else
{
ptrBitmap = cast(immutable size_t*)rtinfoHasPointers;
}
return realloc(p, size, bits, ptrBitmap);
}

void* realloc(void* p, size_t size, uint bits, immutable size_t *ptrBitmap) nothrow;

/**
* Attempt to in-place enlarge the memory block pointed to by p by at least
Expand All @@ -102,7 +157,7 @@ interface GC
* 0 if could not extend p,
* total size of entire memory block if successful.
*/
size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow;
size_t extend(void* p, size_t minsize, size_t maxsize) nothrow;

/**
*
Expand Down Expand Up @@ -130,7 +185,7 @@ interface GC
* Determine the base address of the block containing p. If p is not a gc
* allocated pointer, return null.
*/
BlkInfo query(void* p) nothrow;
BlkInfo query(void* p) nothrow @nogc;

/**
* Retrieve statistics about garbage collection.
Expand Down Expand Up @@ -190,4 +245,73 @@ interface GC
* GC.stats().allocatedInCurrentThread, but faster.
*/
ulong allocatedInCurrentThread() nothrow;

// ARRAY FUNCTIONS
/**
* Get the current used capacity of an array block. Note that this is only
* needed if you are about to change the array used size and need to deal
* with the memory that is about to go away. For appending or shrinking
* arrays that have no destructors, you probably don't need this function.
* Params:
* ptr - The pointer to check. This can be an interior pointer, but if it
* is beyond the end of the used space, the return value may not be
* valid.
* atomic - If true, the value is fetched atomically (for shared arrays)
* Returns: Current array slice, or null if the pointer does not point to a
* valid appendable GC block.
*/
void[] getArrayUsed(void *ptr, bool atomic = false) nothrow @nogc;

/**
* Expand the array used size. Used for appending and expanding the length
* of the array slice. If the operation can be performed without
* reallocating, the function succeeds. Newly expanded data is not
* initialized.
*
* slices that do not point at expandable GC blocks cannot be affected, and
* this function will always return false.
* Params:
* slice - the slice to attempt expanding in place.
* newUsed - the size that should be stored as used.
* atomic - if true, the array may be shared between threads, and this
* operation should be done atomically.
* Returns: true if successful.
*/
bool expandArrayUsed(void[] slice, size_t newUsed, bool atomic = false) nothrow;

/**
* Expand the array capacity. Used for reserving space that can be used for
* appending. If the operation can be performed without reallocating, the
* function succeeds. The used size is not changed.
*
* slices that do not point at expandable GC blocks cannot be affected, and
* this function will always return false.
* Params:
* slice - the slice to attempt reserving capacity for.
* request - the requested size to expand to. Includes the existing data.
* Passing a value less than the current array size will result in no
* changes, but will return the current capacity.
* atomic - if true, the array may be shared between threads, and this
* operation should be done atomically.
* Returns: resulting capacity size, 0 if the operation could not be performed.
*/
size_t reserveArrayCapacity(void[] slice, size_t request, bool atomic = false) nothrow @safe;

/**
* Shrink used space of a slice. Unlike the other array functions, the
* array slice passed in is the target slice, and the existing used space
* is passed separately. This is to discourage code that ends up with a
* slice to dangling valid data.
* If slice.ptr[0 .. existingUsed] does not point to the end of a valid GC
* appendable slice, then the operation fails.
* Params:
* slice - The proposed valid slice data.
* existingUsed - The amount of data in the block (starting at slice.ptr)
* that is currently valid in the array. If this amount does not match
* the current used size, the operation fails.
* atomic - If true, the slice may be shared between threads, and the
* operation should be atomic.
* Returns: true if successful.
*/
bool shrinkArrayUsed(void[] slice, size_t existingUsed, bool atomic = false) nothrow;
}
17 changes: 6 additions & 11 deletions druntime/src/core/internal/array/construction.d
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ T[] _d_newarrayU(T)(size_t length, bool isShared=false) @trusted
{
import core.exception : onOutOfMemoryError;
import core.internal.traits : Unqual;
import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
import core.internal.array.utils : __arrayAlloc;

alias UnqT = Unqual!T;

Expand Down Expand Up @@ -396,15 +396,11 @@ Loverflow:

Lcontinue:
auto info = __arrayAlloc!UnqT(arraySize);
if (!info.base)
if (!info.ptr)
goto Loverflow;
debug(PRINTF) printf("p = %p\n", info.base);
debug(PRINTF) printf("p = %p\n", info.ptr);

auto arrstart = __arrayStart(info);

__setArrayAllocLength!UnqT(info, arraySize, isShared);

return (cast(T*) arrstart)[0 .. length];
return (cast(T*) info.ptr)[0 .. length];
}

/// ditto
Expand Down Expand Up @@ -522,7 +518,7 @@ Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trust

void[] __allocateInnerArray(size_t[] dims)
{
import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
import core.internal.array.utils : __arrayAlloc;

auto dim = dims[0];

Expand All @@ -536,8 +532,7 @@ Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trust
auto allocSize = (void[]).sizeof * dim;
// the array-of-arrays holds pointers! Don't use UnqT here!
auto info = __arrayAlloc!(void[])(allocSize);
__setArrayAllocLength!(void[])(info, allocSize, isShared);
auto p = __arrayStart(info)[0 .. dim];
auto p = info.ptr[0 .. dim];

foreach (i; 0..dim)
{
Expand Down
Loading

0 comments on commit 04a4618

Please sign in to comment.