diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f18328a..df5510e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,8 +260,6 @@ if(MSVC) ) endif() endif() -# disable dmd gc -list(REMOVE_ITEM FE_SRC ${PROJECT_SOURCE_DIR}/${DMDFE_PATH}/root/dmgcmem.c) set(LDC_SOURCE_FILES ${LDC_GENERATED} ${FE_SRC} diff --git a/dmd2/mars.c b/dmd2/mars.c index 2d0841ac..e521eccf 100644 --- a/dmd2/mars.c +++ b/dmd2/mars.c @@ -16,7 +16,7 @@ #include #include -#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun +#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun #include #endif @@ -604,7 +604,7 @@ int tryMain(size_t argc, char *argv[]) #if _WIN32 inifilename = inifile(argv[0], "sc.ini", "Environment"); -#elif linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun +#elif __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun inifilename = inifile(argv[0], "dmd.conf", "Environment"); #else #error "fix this" @@ -1023,7 +1023,7 @@ Language changes listed by -transition=id:\n\ browse("http://dlang.org/dmd-windows.html"); #endif #endif -#if linux +#if __linux__ #if DMDV1 browse("http://www.digitalmars.com/d/1.0/dmd-linux.html"); #else diff --git a/dmd2/root/async.c b/dmd2/root/async.c index 92767c8e..d68237d1 100644 --- a/dmd2/root/async.c +++ b/dmd2/root/async.c @@ -119,7 +119,7 @@ unsigned __stdcall startthread(void *p) return EXIT_SUCCESS; // if skidding } -#elif linux // Posix +#elif __linux__ // Posix #include #include diff --git a/dmd2/root/dmgcmem.c b/dmd2/root/dmgcmem.c deleted file mode 100644 index 02d1c0d1..00000000 --- a/dmd2/root/dmgcmem.c +++ /dev/null @@ -1,499 +0,0 @@ - - -// Copyright (c) 2000-2011 by Digital Mars -// All Rights Reserved -// written by Walter Bright -// http://www.digitalmars.com -// License for redistribution is by either the Artistic License -// in artistic.txt, or the GNU General Public License in gnu.txt. -// See the included readme.txt for details. - -#include -#include -#include -#include - -#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun -#include -#include -#endif - -#include "rmem.h" -#include "gc/gc.h" -//#include "printf.h" - -/* This implementation of the storage allocator uses the Digital Mars gc. - */ - -Mem mem; - -//static int nuncollectable; - -extern "C" -{ - void gc_init(); - GC *gc_get(); -} - -void Mem::init() -{ - gc_init(); -} - -char *Mem::strdup(const char *s) -{ - return gc_get()->strdup(s); -} - -void *Mem::malloc(size_t size) -{ - if (gc) // if cached allocator - { -// PRINTF("Using cached gc for size %d, file = '%s', line = %d\n", size, GC::file, GC::line); -// GC::file = NULL; -// GC::line = 0; - return ((GC *)gc)->malloc(size); - } - if (this == &mem) // don't cache global mem - { -// PRINTF("Using global gc for size %d, file = '%s', line = %d\n", size, GC::file, GC::line); -// GC::file = NULL; -// GC::line = 0; - return gc_get()->malloc(size); - } -// PRINTF("Generating cached gc for size %d, file = '%s', line = %d\n", size, GC::file, GC::line); - gc = gc_get(); - return gc->malloc(size); -} - -void *Mem::malloc_uncollectable(size_t size) -{ void *p; - - p = ::malloc(size); - if (!p) - error(); - addroots((char *)p, (char *)p + size); - -#if 0 - ++nuncollectable; - WPRINTF(L"malloc_uncollectable(%u) = %x, n=%d\n", size, p, nuncollectable); -#endif - - return p; -} - -void *Mem::calloc(size_t size, size_t n) -{ - return gc_get()->calloc(size, n); -} - -void *Mem::realloc(void *p, size_t size) -{ - return gc_get()->realloc(p, size); -} - -void Mem::free(void *p) -{ - gc_get()->free(p); -} - -void Mem::free_uncollectable(void *p) -{ - if (p) - { removeroots((char *)p); - ::free(p); - -#if 0 - --nuncollectable; - WPRINTF(L"free_uncollectable(%x) n=%d\n", p, nuncollectable); -#endif - -#if 0 - gc_get()->fullcollect(); - - GCStats stats; - - getStats(&stats); - WPRINTF(L"poolsize = %x, usedsize = %x, freelistsize = %x\n", - stats.poolsize, stats.usedsize, stats.freelistsize); -#endif - } -} - -void *Mem::mallocdup(void *o, size_t size) -{ - return gc_get()->mallocdup(o, size); -} - -void Mem::check(void *p) -{ - if (gc) - gc->check(p); - else - gc_get()->check(p); -} - -void Mem::error() -{ -#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun - assert(0); -#endif - printf("Error: out of memory\n"); - exit(EXIT_FAILURE); -} - -void Mem::fullcollect() -{ - gc_get()->fullcollect(); - -#if 0 - { - GCStats stats; - - gc_get()->getStats(&stats); - WPRINTF(L"Thread %x ", Thread::getId()); - WPRINTF(L"poolsize=x%x, usedsize=x%x, freelistsize=x%x, freeblocks=%d, pageblocks=%d\n", - stats.poolsize, stats.usedsize, stats.freelistsize, stats.freeblocks, stats.pageblocks); - } -#endif -} - - -void Mem::fullcollectNoStack() -{ - gc_get()->fullcollectNoStack(); - -#if 0 - { - GCStats stats; - - gc_get()->getStats(&stats); - WPRINTF(L"Thread %x ", Thread::getId()); - WPRINTF(L"poolsize=x%x, usedsize=x%x, freelistsize=x%x, freeblocks=%d, pageblocks=%d\n", - stats.poolsize, stats.usedsize, stats.freelistsize, stats.freeblocks, stats.pageblocks); - } -#endif -} - - -void Mem::mark(void *pointer) -{ - (void) pointer; // for VC /W4 compatibility -} - - -void Mem::addroots(char* pStart, char* pEnd) -{ - gc_get()->addRange(pStart, pEnd); -} - - -void Mem::removeroots(char* pStart) -{ - gc_get()->removeRange(pStart); -} - - -void Mem::setFinalizer(void* pObj, FINALIZERPROC pFn, void* pClientData) -{ - (void)pClientData; - gc_get()->setFinalizer(pObj, pFn); -} - - -void Mem::setStackBottom(void *stackbottom) -{ - gc_get()->setStackBottom(stackbottom); -} - - -GC *Mem::getThreadGC() -{ - return gc_get(); -} - - -/* =================================================== */ - -#if 1 -void * operator new(size_t m_size) -{ - //PRINTF("Call to global operator new(%d), file = '%s', line = %d\n", m_size, GC::file ? GC::file : "(null)", GC::line); - GC::file = NULL; - GC::line = 0; - return mem.malloc(m_size); -} - -void operator delete(void *p) -{ - //WPRINTF(L"Call to global operator delete\n"); - mem.free(p); -} - -void* operator new[](size_t size) -{ - return operator new(size); -} - -void operator delete[](void *pv) -{ - operator delete(pv); -} -#endif - -void * Mem::operator new(size_t m_size) -{ void *p; - - p = gc_get()->malloc(m_size); - //printf("Mem::operator new(%d) = %p\n", m_size, p); - if (!p) - mem.error(); - return p; -} - -void * Mem::operator new(size_t m_size, Mem *mem) -{ void *p; - - p = mem->malloc(m_size); - //printf("Mem::operator new(%d) = %p\n", m_size, p); - if (!p) - ::mem.error(); - return p; -} - -void * Mem::operator new(size_t m_size, GC *gc) -{ void *p; - -// if (!gc) -// WPRINTF(L"gc is NULL\n"); - p = gc->malloc(m_size); - //printf("Mem::operator new(%d) = %p\n", m_size, p); - if (!p) - ::mem.error(); - return p; -} - -void Mem::operator delete(void *p) -{ -// printf("Mem::operator delete(%p)\n", p); - gc_get()->free(p); -} - -/* ============================================================ */ - -/* The following section of code exists to find the right - * garbage collector for this thread. There is one independent instance - * of the collector per thread. - */ - -/* ===================== linux ================================ */ - -#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun - -#include - -#define LOG 0 // log thread creation / destruction - -extern "C" -{ - -// Key identifying the thread-specific data -static pthread_key_t gc_key; - -/* "Once" variable ensuring that the key for gc_alloc will be allocated - * exactly once. - */ -static pthread_once_t gc_alloc_key_once = PTHREAD_ONCE_INIT; - -/* Forward functions */ -static void gc_alloc_key(); -static void gc_alloc_destroy_gc(void * accu); - - -void gc_init() -{ -#if LOG - WPRINTF(L"Thread %lx: gc_init()\n", pthread_self()); -#endif - pthread_once(&gc_alloc_key_once, gc_alloc_key); -#if LOG - WPRINTF(L"Thread %lx: gc_init() return\n", pthread_self()); -#endif -} - -GC *gc_get() -{ - GC *gc; - - // Get the thread-specific data associated with the key - gc = (GC *) pthread_getspecific(gc_key); - - // It's initially NULL, meaning that we must allocate the buffer first. - if (gc == NULL) - { - GC_LOG(); - gc = new GC(); - gc->init(); - - // Store the buffer pointer in the thread-specific data. - pthread_setspecific(gc_key, (void *) gc); -#if LOG - WPRINTF(L"Thread %lx: allocating gc at %x\n", pthread_self(), gc); -#endif - } - return gc; -} - -// Function to allocate the key for gc_alloc thread-specific data. - -static void gc_alloc_key() -{ - pthread_key_create(&gc_key, gc_alloc_destroy_gc); -#if LOG - WPRINTF(L"Thread %lx: allocated gc key %d\n", pthread_self(), gc_key); -#endif -} - -// Function to free the buffer when the thread exits. -// Called only when the thread-specific data is not NULL. - -static void gc_alloc_destroy_gc(void *gc) -{ -#if LOG - WPRINTF(L"Thread %x: freeing gc at %x\n", pthread_self(), gc); -#endif - delete (GC *)gc; -} - -} - -#endif - -/* ===================== win32 ================================ */ - -#if !defined(linux) && defined(_WIN32) - -#if 1 // single threaded version - -extern "C" -{ - -static GC *gc; - -void gc_init() -{ - if (!gc) - { gc = (GC *)::malloc(sizeof(GC)); - gc->init(); - } -} - -GC *gc_get() -{ - return gc; -} - -} - -#else // multi threaded version - -#include "mutex.h" -#include "thread.h" - -/* This is the win32 version. It suffers from the bug that - * when the thread exits the data structure is not cleared, - * but the memory pool it points to is free'd. - * Thus, if a new thread comes along with the same thread id, - * the data will look initialized, but will point to garbage. - * - * What needs to happen is when a thread exits, the associated - * GC_context data struct is cleared. - */ - -struct GC_context -{ - ThreadId threadid; // identifier of current thread - GC *gc; -}; - -Mutex gc_mutex; - -static GC_context array[64]; - -// Array of pointers to GC_context objects, one per threadid -GC_context *gccontext = array; -unsigned gccontext_allocdim = 64; -unsigned gccontext_dim; - -ThreadId gc_cache_ti; -GC_context *gc_cache_cc; - -extern "C" void gc_init() -{ -} - - -extern "C" GC *gc_get() -{ - /* This works by creating an array of GC_context's, one - * for each thread. We match up by thread id. - */ - - ThreadId ti; - GC_context *cc; - - //PRINTF("gc_get()\n"); - - ti = Thread::getId(); - gc_mutex.acquire(); - - // Used cached version if we can - if (ti == gc_cache_ti) - { - cc = gc_cache_cc; - //exception(L"getGC_context(): cache x%x", ti); - } - else - { - // This does a linear search through gccontext[]. - // A hash table might be faster if there are more - // than a dozen threads. - GC_context *ccp; - GC_context *ccptop = &gccontext[gccontext_dim]; - for (ccp = gccontext; ccp < ccptop; ccp++) - { - cc = ccp; - if (cc->threadid == ti) - { - WPRINTF(L"getGC_context(): existing x%x", ti); - goto Lret; - } - } - - // Do not allocate with garbage collector, as this must reside - // global to all threads. - - assert(gccontext_dim < gccontext_allocdim); - cc = ccp; - memset(cc, 0, sizeof(*cc)); - cc->threadid = ti; - cc->gc = new GC(); - cc->gc->init(); - - gccontext_dim++; - WPRINTF(L"getGC_context(): new x%x\n", ti); - - Lret: - // Cache for next time - gc_cache_ti = ti; - gc_cache_cc = cc; - } - - gc_mutex.release(); - return cc->gc; -} - -#endif - - -#endif diff --git a/dmd2/root/man.c b/dmd2/root/man.c index f49d60b4..462ef92a 100644 --- a/dmd2/root/man.c +++ b/dmd2/root/man.c @@ -26,7 +26,7 @@ void browse(const char *url) #endif -#if linux || __FreeBSD__ || __OpenBSD__ || __sun +#if __linux__ || __FreeBSD__ || __OpenBSD__ || __sun #include #include diff --git a/dmd2/root/port.c b/dmd2/root/port.c index bf8ae7c5..028ec462 100644 --- a/dmd2/root/port.c +++ b/dmd2/root/port.c @@ -624,10 +624,10 @@ longdouble Port::strtold(const char *p, char **endp) #endif -#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __HAIKU__ +#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __HAIKU__ #include -#if linux +#if __linux__ #include #include #endif diff --git a/dmd2/root/root.c b/dmd2/root/root.c index 35f64e66..608dd785 100644 --- a/dmd2/root/root.c +++ b/dmd2/root/root.c @@ -8,7 +8,7 @@ // See the included readme.txt for details. #ifndef POSIX -#define POSIX (linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun) +#define POSIX (__linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun) #endif #include @@ -880,11 +880,11 @@ void FileName::ensurePathToNameExists(const char *name) */ const char *FileName::canonicalName(const char *name) { -#if linux +#if __linux__ // Lovely glibc extension to do it for us return canonicalize_file_name(name); #elif POSIX - #if _POSIX_VERSION >= 200809L || defined (linux) + #if _POSIX_VERSION >= 200809L || defined (__linux__) // NULL destination buffer is allowed and preferred return realpath(name, NULL); #else diff --git a/driver/ldmd.cpp b/driver/ldmd.cpp index ffb72302..bf701bae 100644 --- a/driver/ldmd.cpp +++ b/driver/ldmd.cpp @@ -1003,7 +1003,7 @@ int main(int argc, char *argv[]) std::string ldcPath = locateBinary(LDC_EXE_NAME, argv[0]); if (ldcPath.empty()) { - error("Could not locate "LDC_EXE_NAME" executable."); + error("Could not locate " LDC_EXE_NAME " executable."); } // We need to manually set up argv[0] and the terminating NULL. diff --git a/gen/functions.cpp b/gen/functions.cpp index be966a82..218c49a5 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -379,25 +379,23 @@ LLFunction* DtoInlineIRFunction(FuncDeclaration* fdecl) static llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) { IrFuncTy &irFty = fdecl->irFty; - LLFunctionType* type = 0; + if (irFty.funcType) return irFty.funcType; - // create new ir funcTy - irFty.reset(); irFty.ret = new IrFuncTyArg(Type::tvoid, false); irFty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false)); if (fdecl->llvmInternal == LLVMva_start) - type = GET_INTRINSIC_DECL(vastart)->getFunctionType(); + irFty.funcType = GET_INTRINSIC_DECL(vastart)->getFunctionType(); else if (fdecl->llvmInternal == LLVMva_copy) { - type = GET_INTRINSIC_DECL(vacopy)->getFunctionType(); + irFty.funcType = GET_INTRINSIC_DECL(vacopy)->getFunctionType(); irFty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false)); } else if (fdecl->llvmInternal == LLVMva_end) - type = GET_INTRINSIC_DECL(vaend)->getFunctionType(); - assert(type); + irFty.funcType = GET_INTRINSIC_DECL(vaend)->getFunctionType(); + assert(irFty.funcType); - return type; + return irFty.funcType; } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/ir/irfuncty.h b/ir/irfuncty.h index 9a416ea0..cb1be16c 100644 --- a/ir/irfuncty.h +++ b/ir/irfuncty.h @@ -127,51 +127,6 @@ struct IrFuncTy reverseParams(false) {} -#if defined(_MSC_VER) - // Copy constructor and operator= seems to be required for MSC - - IrFuncTy(const IrFuncTy& rhs) - : funcType(rhs.funcType), - ret(rhs.ret), - args(IrFuncTy::ArgList(rhs.args)), - arg_sret(rhs.arg_sret), - arg_this(rhs.arg_this), - arg_nest(rhs.arg_nest), - arg_arguments(rhs.arg_arguments), - arg_argptr(rhs.arg_argptr), - c_vararg(rhs.c_vararg), - reverseParams(rhs.reverseParams) - {} - - IrFuncTy& operator=(const IrFuncTy& rhs) - { - funcType = rhs.funcType; - ret = rhs.ret; - args = IrFuncTy::ArgList(rhs.args); - arg_sret = rhs.arg_sret; - arg_this = rhs.arg_this; - arg_nest = rhs.arg_nest; - arg_arguments = rhs.arg_arguments; - arg_argptr = rhs.arg_argptr; - c_vararg = rhs.c_vararg; - reverseParams = rhs.reverseParams; - return *this; - } -#endif - - void reset() { - funcType = 0; - ret = NULL; - arg_sret = arg_this = arg_nest = arg_arguments = arg_argptr = NULL; -#if defined(_MSC_VER) - args = IrFuncTy::ArgList(); -#else - args.clear(); -#endif - c_vararg = false; - reverseParams = false; - } - llvm::Value* putRet(Type* dty, DValue* dval); llvm::Value* getRet(Type* dty, DValue* dval);