mirror of
https://github.com/openRuyi-Project/gcc.git
synced 2026-09-06 14:01:37 +00:00
D front-end changes: - Import latest fixes from v2.112.0-beta.1. - Associative array operations are now lowered to templates defined in `core.internal.newaa'. D runtime changes: - Import latest fixes from v2.112.0-beta.1. Phobos changes: - Import latest fixes from v2.112.0-beta.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd e1f6680f50. * Make-lang.in (D_FRONTEND_OBJS): Remove d/gluelayer.o, d/iasm.o, d/iasmgcc.o. Add d/iasm-package.o, d/iasm-gcc.o. (d/iasm-%.o): New recipe. * d-convert.cc (convert_expr): Remove library call to dynamic_cast. * d-lang.cc (d_init_options): Set errorSupplementLimit parameter. * decl.cc (DeclVisitor::visit): Update for new front-end interface. * expr.cc (ExprVisitor::visit (EqualExp *)): Update for front-end lowering expression using templates. (ExprVisitor::visit (InExp *)): Likewise. (ExprVisitor::visit (IndexExp *)): Likewise. (ExprVisitor::visit (CastExp *)): Likewise. (ExprVisitor::visit (RemoveExp *)): Likewise. (ExprVisitor::visit (AddrExp *)): Likewise. (ExprVisitor::visit (NewExp *)): Likewise. (ExprVisitor::visit (ArrayLiteralExp *)): Likewise. (ExprVisitor::visit (AssocArrayLiteralExp *)): Likewise. * imports.cc (ImportVisitor::visit (AliasDeclaration *)): Update for new front-end interface. * runtime.def (DYNAMIC_CAST): Remove. (INTERFACE_CAST): Remove. (ARRAYLITERALTX): Remove. (ADEQ2): Remove. (ASSOCARRAYLITERALTX): Remove. (AANEW): Remove. (AAEQUAL): Remove. (AAINX): Remove. (AAGETY): Remove. (AAGETRVALUEX): Remove. (AADELX): Remove. * typeinfo.cc (TypeInfoVisitor::visit): Layout xopEquals and xtoHash in TypeInfo_AssociativeArray. (create_typeinfo): Add new fields to internal typeinfo. (check_typeinfo_type): Print instantiation trace of error. * types.cc (TypeVisitor::visit (TypeStruct *)): Update for new front-end interface. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime e1f6680f50. * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add core/internal/cast_.d. Remove rt/aaA.d, rt/adi.d, rt/cast_.d. (DRUNTIME_DSOURCES_POSIX): Add core/sys/posix/endian.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos f87979028. * src/Makefile.am (PHOBOS_DSOURCES): Add std/internal/entropy.d. * src/Makefile.in: Regenerate. * testsuite/libphobos.aa/test_aa.d: Adjust test. * testsuite/libphobos.init_fini/custom_gc.d: Likewise. gcc/testsuite/ChangeLog: * gdc.dg/asm1.d: Adjust test. * gdc.dg/asm5.d: Likewise. * gdc.dg/pr100967.d: Likewise. * gdc.dg/rtti1.d: Likewise. * gdc.dg/rtti2.d: New test.
309 lines
7.6 KiB
D
309 lines
7.6 KiB
D
/**
|
|
* Contains the external GC interface.
|
|
*
|
|
* Copyright: D Language Foundation 2005 - 2021.
|
|
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
|
* Authors: Walter Bright, Sean Kelly
|
|
*/
|
|
module core.internal.gc.proxy;
|
|
|
|
import core.internal.gc.impl.proto.gc;
|
|
import core.gc.config;
|
|
import core.gc.gcinterface;
|
|
import core.gc.registry : createGCInstance;
|
|
|
|
static import core.memory;
|
|
|
|
private
|
|
{
|
|
static import core.memory;
|
|
alias BlkInfo = core.memory.GC.BlkInfo;
|
|
|
|
import core.internal.spinlock;
|
|
static SpinLock instanceLock;
|
|
|
|
__gshared bool isInstanceInit = false;
|
|
__gshared GC _instance = new ProtoGC();
|
|
__gshared GC proxiedGC; // used to iterate roots of Windows DLLs
|
|
|
|
pragma (inline, true) @trusted @nogc nothrow
|
|
GC instance() { return _instance; }
|
|
}
|
|
|
|
extern (C)
|
|
{
|
|
import core.attribute : weak;
|
|
|
|
// do not import GC modules, they might add a dependency to this whole module
|
|
void _d_register_conservative_gc();
|
|
void _d_register_manual_gc();
|
|
|
|
// if you don't want to include the default GCs, replace during link by another implementation
|
|
void* register_default_gcs() @weak
|
|
{
|
|
pragma(inline, false);
|
|
// do not call, they register implicitly through pragma(crt_constructor)
|
|
// avoid being optimized away
|
|
auto reg1 = &_d_register_conservative_gc;
|
|
auto reg2 = &_d_register_manual_gc;
|
|
return reg1 < reg2 ? reg1 : reg2;
|
|
}
|
|
|
|
void gc_init()
|
|
{
|
|
instanceLock.lock();
|
|
if (!isInstanceInit)
|
|
{
|
|
register_default_gcs();
|
|
config.initialize();
|
|
auto protoInstance = instance;
|
|
auto newInstance = createGCInstance(config.gc);
|
|
if (newInstance is null)
|
|
{
|
|
import core.stdc.stdio : fprintf, stderr;
|
|
import core.stdc.stdlib : exit;
|
|
import core.atomic : atomicLoad;
|
|
|
|
fprintf(atomicLoad(stderr), "No GC was initialized, please recheck the name of the selected GC ('%.*s').\n", cast(int)config.gc.length, config.gc.ptr);
|
|
instanceLock.unlock();
|
|
exit(1);
|
|
|
|
// Shouldn't get here.
|
|
assert(0);
|
|
}
|
|
_instance = newInstance;
|
|
// Transfer all ranges and roots to the real GC.
|
|
(cast(ProtoGC) protoInstance).transferRangesAndRoots();
|
|
isInstanceInit = true;
|
|
}
|
|
instanceLock.unlock();
|
|
}
|
|
|
|
void gc_init_nothrow() nothrow
|
|
{
|
|
scope(failure)
|
|
{
|
|
import core.internal.abort;
|
|
abort("Cannot initialize the garbage collector.\n");
|
|
assert(0);
|
|
}
|
|
gc_init();
|
|
}
|
|
|
|
void gc_term()
|
|
{
|
|
if (isInstanceInit)
|
|
{
|
|
switch (config.cleanup)
|
|
{
|
|
default:
|
|
import core.stdc.stdio : fprintf, stderr;
|
|
import core.atomic : atomicLoad;
|
|
|
|
fprintf(atomicLoad(stderr), "Unknown GC cleanup method, please recheck ('%.*s').\n",
|
|
cast(int)config.cleanup.length, config.cleanup.ptr);
|
|
break;
|
|
case "none":
|
|
break;
|
|
case "collect":
|
|
instance.collect();
|
|
break;
|
|
case "finalize":
|
|
instance.runFinalizers((cast(ubyte*)null)[0 .. size_t.max]);
|
|
break;
|
|
}
|
|
destroy(instance);
|
|
}
|
|
}
|
|
|
|
void gc_enable()
|
|
{
|
|
instance.enable();
|
|
}
|
|
|
|
void gc_disable()
|
|
{
|
|
instance.disable();
|
|
}
|
|
|
|
void gc_collect() nothrow
|
|
{
|
|
instance.collect();
|
|
}
|
|
|
|
void gc_minimize() nothrow
|
|
{
|
|
instance.minimize();
|
|
}
|
|
|
|
uint gc_getAttr( void* p ) nothrow
|
|
{
|
|
return instance.getAttr(p);
|
|
}
|
|
|
|
uint gc_setAttr( void* p, uint a ) nothrow
|
|
{
|
|
return instance.setAttr(p, a);
|
|
}
|
|
|
|
uint gc_clrAttr( void* p, uint a ) nothrow
|
|
{
|
|
return instance.clrAttr(p, a);
|
|
}
|
|
|
|
void* gc_malloc( size_t sz, uint ba = 0, const scope TypeInfo ti = null ) nothrow
|
|
{
|
|
return instance.malloc(sz, ba, ti);
|
|
}
|
|
|
|
BlkInfo gc_qalloc( size_t sz, uint ba = 0, const scope TypeInfo ti = null ) nothrow
|
|
{
|
|
return instance.qalloc( sz, ba, ti );
|
|
}
|
|
|
|
void* gc_calloc( size_t sz, uint ba = 0, const scope TypeInfo ti = null ) nothrow
|
|
{
|
|
return instance.calloc( sz, ba, ti );
|
|
}
|
|
|
|
void* gc_realloc( void* p, size_t sz, uint ba = 0, const scope TypeInfo ti = null ) nothrow
|
|
{
|
|
return instance.realloc( p, sz, ba, ti );
|
|
}
|
|
|
|
size_t gc_extend( void* p, size_t mx, size_t sz, const scope TypeInfo ti = null ) nothrow
|
|
{
|
|
return instance.extend( p, mx, sz,ti );
|
|
}
|
|
|
|
size_t gc_reserve( size_t sz ) nothrow
|
|
{
|
|
return instance.reserve( sz );
|
|
}
|
|
|
|
void gc_free( void* p ) nothrow @nogc
|
|
{
|
|
return instance.free( p );
|
|
}
|
|
|
|
void* gc_addrOf( void* p ) nothrow @nogc
|
|
{
|
|
return instance.addrOf( p );
|
|
}
|
|
|
|
size_t gc_sizeOf( void* p ) nothrow @nogc
|
|
{
|
|
return instance.sizeOf( p );
|
|
}
|
|
|
|
BlkInfo gc_query( void* p ) nothrow
|
|
{
|
|
return instance.query( p );
|
|
}
|
|
|
|
core.memory.GC.Stats gc_stats() @safe nothrow @nogc
|
|
{
|
|
return instance.stats();
|
|
}
|
|
|
|
core.memory.GC.ProfileStats gc_profileStats() @safe nothrow @nogc
|
|
{
|
|
return instance.profileStats();
|
|
}
|
|
|
|
void gc_addRoot( void* p ) nothrow @nogc
|
|
{
|
|
return instance.addRoot( p );
|
|
}
|
|
|
|
void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow @nogc
|
|
{
|
|
return instance.addRange( p, sz, ti );
|
|
}
|
|
|
|
void gc_removeRoot( void* p ) nothrow
|
|
{
|
|
return instance.removeRoot( p );
|
|
}
|
|
|
|
void gc_removeRange( void* p ) nothrow
|
|
{
|
|
return instance.removeRange( p );
|
|
}
|
|
|
|
void gc_runFinalizers(const scope void[] segment ) nothrow
|
|
{
|
|
return instance.runFinalizers( segment );
|
|
}
|
|
|
|
bool gc_inFinalizer() nothrow @nogc @safe
|
|
{
|
|
return instance.inFinalizer();
|
|
}
|
|
|
|
ulong gc_allocatedInCurrentThread() nothrow
|
|
{
|
|
return instance.allocatedInCurrentThread();
|
|
}
|
|
|
|
void[] gc_getArrayUsed(void *ptr, bool atomic) nothrow
|
|
{
|
|
return instance.getArrayUsed( ptr, atomic );
|
|
}
|
|
|
|
bool gc_expandArrayUsed(void[] slice, size_t newUsed, bool atomic) nothrow
|
|
{
|
|
return instance.expandArrayUsed( slice, newUsed, atomic );
|
|
}
|
|
|
|
size_t gc_reserveArrayCapacity(void[] slice, size_t request, bool atomic) nothrow
|
|
{
|
|
return instance.reserveArrayCapacity( slice, request, atomic );
|
|
}
|
|
|
|
bool gc_shrinkArrayUsed(void[] slice, size_t existingUsed, bool atomic) nothrow
|
|
{
|
|
return instance.shrinkArrayUsed( slice, existingUsed, atomic );
|
|
}
|
|
|
|
GC gc_getProxy() nothrow @nogc
|
|
{
|
|
return instance;
|
|
}
|
|
|
|
export
|
|
{
|
|
void gc_setProxy( GC proxy )
|
|
{
|
|
foreach (root; instance.rootIter)
|
|
{
|
|
proxy.addRoot(root);
|
|
}
|
|
|
|
foreach (range; instance.rangeIter)
|
|
{
|
|
proxy.addRange(range.pbot, range.ptop - range.pbot, range.ti);
|
|
}
|
|
|
|
proxiedGC = instance; // remember initial GC to later remove roots
|
|
_instance = proxy;
|
|
}
|
|
|
|
void gc_clrProxy()
|
|
{
|
|
foreach (root; proxiedGC.rootIter)
|
|
{
|
|
instance.removeRoot(root);
|
|
}
|
|
|
|
foreach (range; proxiedGC.rangeIter)
|
|
{
|
|
instance.removeRange(range);
|
|
}
|
|
|
|
_instance = proxiedGC;
|
|
proxiedGC = null;
|
|
}
|
|
}
|
|
}
|