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<alias_t>".
This commit is contained in:
Joel Dice 2011-02-14 11:47:59 -07:00
parent 2e0770b0f3
commit 468edb97d2
4 changed files with 36 additions and 18 deletions

View File

@ -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<intptr_t*>(static_cast<uint8_t*>(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<intptr_alias_t*>(static_cast<uint8_t*>(p) + offset);
}
} // namespace vm
#endif // not _MSC_VER

View File

@ -2145,8 +2145,8 @@ class HeapClient: public Heap::Client {
memcpy(dst, src, n * BytesPerWord);
if (hashTaken(t, src)) {
cast<alias_t>(dst, 0) &= PointerMask;
cast<alias_t>(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<alias_t>(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<alias_t>(o, 0) = FixedMark;
alias(o, 0) = FixedMark;
return o;
}

View File

@ -1878,8 +1878,9 @@ setObjectClass(Thread*, object o, object value)
{
cast<object>(o, 0)
= reinterpret_cast<object>
(reinterpret_cast<alias_t>(value)
| (reinterpret_cast<alias_t>(cast<object>(o, 0)) & (~PointerMask)));
(reinterpret_cast<intptr_alias_t>(value)
| (reinterpret_cast<intptr_alias_t>
(cast<object>(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<alias_t>(o, 0) & (~PointerMask)) == FixedMark;
return (alias(o, 0) & (~PointerMask)) == FixedMark;
}
inline bool
objectExtended(Thread*, object o)
{
return (cast<alias_t>(o, 0) & (~PointerMask)) == ExtendedMark;
return (alias(o, 0) & (~PointerMask)) == ExtendedMark;
}
inline bool
hashTaken(Thread*, object o)
{
return (cast<alias_t>(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<alias_t>(o, 0) |= HashTakenMark;
alias(o, 0) |= HashTakenMark;
t->m->heap->pad(o);
}

View File

@ -66,32 +66,32 @@ inline object
getTreeNodeValue(Thread*, object n)
{
return reinterpret_cast<object>
(cast<alias_t>(n, TreeNodeValue) & PointerMask);
(alias(n, TreeNodeValue) & PointerMask);
}
inline void
setTreeNodeValue(Thread* t, object n, object value)
{
alias_t red = cast<alias_t>(n, TreeNodeValue) & (~PointerMask);
intptr_t red = alias(n, TreeNodeValue) & (~PointerMask);
set(t, n, TreeNodeValue, value);
cast<alias_t>(n, TreeNodeValue) |= red;
alias(n, TreeNodeValue) |= red;
}
inline bool
treeNodeRed(Thread*, object n)
{
return (cast<alias_t>(n, TreeNodeValue) & (~PointerMask)) == 1;
return (alias(n, TreeNodeValue) & (~PointerMask)) == 1;
}
inline void
setTreeNodeRed(Thread*, object n, bool red)
{
if (red) {
cast<alias_t>(n, TreeNodeValue) |= 1;
alias(n, TreeNodeValue) |= 1;
} else {
cast<alias_t>(n, TreeNodeValue) &= PointerMask;
alias(n, TreeNodeValue) &= PointerMask;
}
}