From 468edb97d2d73b6c1df0cccf499e9008ea161789 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 14 Feb 2011 11:47:59 -0700 Subject: [PATCH] work around GCC name mangling bug It seems that older versions of GCC (4.0 and older, at least) generate assembly files with duplicate symbols for function templates which differ only by the attributes of the templated types. Newer versions have no such problem, but we need to support both, hence the workaround in this commit of using a dedicated, non-template "alias" function where we previously used "cast". --- src/common.h | 21 +++++++++++++++++++-- src/machine.cpp | 8 ++++---- src/machine.h | 13 +++++++------ src/util.cpp | 12 ++++++------ 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/common.h b/src/common.h index d4af04aa32..13957bedfd 100644 --- a/src/common.h +++ b/src/common.h @@ -59,7 +59,15 @@ typedef uint64_t uintptr_t; # error "unsupported architecture" # endif -typedef intptr_t alias_t; +namespace vm { + +inline intptr_t& +alias(void* p, unsigned offset) +{ + return *reinterpret_cast(static_cast(p) + offset); +} + +} // namespace vm #else // not _MSC_VER @@ -88,7 +96,16 @@ typedef intptr_t alias_t; # error "unsupported architecture" # endif -typedef intptr_t __attribute__((__may_alias__)) alias_t; +namespace vm { + +typedef intptr_t __attribute__((__may_alias__)) intptr_alias_t; +inline intptr_alias_t& +alias(void* p, unsigned offset) +{ + return *reinterpret_cast(static_cast(p) + offset); +} + +} // namespace vm #endif // not _MSC_VER diff --git a/src/machine.cpp b/src/machine.cpp index 4933d30f7c..c174f4aafd 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -2145,8 +2145,8 @@ class HeapClient: public Heap::Client { memcpy(dst, src, n * BytesPerWord); if (hashTaken(t, src)) { - cast(dst, 0) &= PointerMask; - cast(dst, 0) |= ExtendedMark; + alias(dst, 0) &= PointerMask; + alias(dst, 0) |= ExtendedMark; extendedWord(t, dst, base) = takeHash(t, src); } } @@ -2781,7 +2781,7 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type, memset(o, 0, sizeInBytes); - cast(o, 0) = FixedMark; + alias(o, 0) = FixedMark; t->m->fixedFootprint += total; @@ -2796,7 +2796,7 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type, memset(o, 0, sizeInBytes); - cast(o, 0) = FixedMark; + alias(o, 0) = FixedMark; return o; } diff --git a/src/machine.h b/src/machine.h index 78ce6d5448..af79ca2372 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1878,8 +1878,9 @@ setObjectClass(Thread*, object o, object value) { cast(o, 0) = reinterpret_cast - (reinterpret_cast(value) - | (reinterpret_cast(cast(o, 0)) & (~PointerMask))); + (reinterpret_cast(value) + | (reinterpret_cast + (cast(o, 0)) & (~PointerMask))); } inline const char* @@ -2094,19 +2095,19 @@ setType(Thread* t, Machine::Type type, object value) inline bool objectFixed(Thread*, object o) { - return (cast(o, 0) & (~PointerMask)) == FixedMark; + return (alias(o, 0) & (~PointerMask)) == FixedMark; } inline bool objectExtended(Thread*, object o) { - return (cast(o, 0) & (~PointerMask)) == ExtendedMark; + return (alias(o, 0) & (~PointerMask)) == ExtendedMark; } inline bool hashTaken(Thread*, object o) { - return (cast(o, 0) & (~PointerMask)) == HashTakenMark; + return (alias(o, 0) & (~PointerMask)) == HashTakenMark; } inline unsigned @@ -2237,7 +2238,7 @@ markHashTaken(Thread* t, object o) ACQUIRE_RAW(t, t->m->heapLock); - cast(o, 0) |= HashTakenMark; + alias(o, 0) |= HashTakenMark; t->m->heap->pad(o); } diff --git a/src/util.cpp b/src/util.cpp index 7ae8de1217..1c7702d853 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -66,32 +66,32 @@ inline object getTreeNodeValue(Thread*, object n) { return reinterpret_cast - (cast(n, TreeNodeValue) & PointerMask); + (alias(n, TreeNodeValue) & PointerMask); } inline void setTreeNodeValue(Thread* t, object n, object value) { - alias_t red = cast(n, TreeNodeValue) & (~PointerMask); + intptr_t red = alias(n, TreeNodeValue) & (~PointerMask); set(t, n, TreeNodeValue, value); - cast(n, TreeNodeValue) |= red; + alias(n, TreeNodeValue) |= red; } inline bool treeNodeRed(Thread*, object n) { - return (cast(n, TreeNodeValue) & (~PointerMask)) == 1; + return (alias(n, TreeNodeValue) & (~PointerMask)) == 1; } inline void setTreeNodeRed(Thread*, object n, bool red) { if (red) { - cast(n, TreeNodeValue) |= 1; + alias(n, TreeNodeValue) |= 1; } else { - cast(n, TreeNodeValue) &= PointerMask; + alias(n, TreeNodeValue) &= PointerMask; } }