This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: empty-string refcount contention
- From: Martin Sebor <sebor at roguewave dot com>
- To: libstdc++ at gcc dot gnu dot org
- Date: Wed, 02 Apr 2003 16:49:59 -0700
- Subject: Re: empty-string refcount contention
- Organization: Rogue Wave Software, Inc.
- References: <20030328223847.GD16816@tofu.dreamhost.com> <200303290021.h2T0Ld05089665@latour.rsch.comm.mot.com> <20030331110628.71962cbf.bkoz@redhat.com> <20030331195256.GF16816@tofu.dreamhost.com> <20030331163135.411029b0.bkoz@redhat.com> <20030402182808.GM16816@tofu.dreamhost.com> <3E8B2FE6.8050609@roguewave.com> <20030402230210.GA10137@tofu.dreamhost.com>
- Reply-to: libstdc++ at gcc dot gnu dot org
Nathan Myers wrote:
On Wed, Apr 02, 2003 at 11:45:58AM -0700, Martin Sebor wrote:
...
I thought about that alternative, and I don't think it helps. You
would have to make sure it appears in the main program and not any
user library, and even then code instantiated in libstdc++.so or in
user libraries would have to use a relocation to get to it. (Anyway
I don't know how to force data to be instantiated only in the main
program.)
It's probably not hard to get basic_string<T>::_S_empty_rep_storage
for T in {char, wchar_t} instantiated in (and not exported from)
libstdc++.so, but where should instantiations for other T go, and how
can we get them there?
Making sure the _Rep object isn't defined in the libstdc++ binary
is not difficult -- simply do not provide a definition for it when
compiling the library :)
Making sure it is defined when using the library (including its
headers) is also not difficult -- define the object in a library
header (say <string>), but only do so conditionally (see above).
I don't think there's anything one can do to guarantee that it
doesn't get emitted in a 3rd party library, but it should be
easy to make sure that if it is also emitted in the executable
program that that copy is the one that gets used -- linkers
resolve references left to right, so if the symbol is defined
in both a.o and libfoo.so, the order a.o -lfoo on the link
line will make the linker pick up the definition from a.o over
the one in libfoo.so.
Whether this hackery buys you anything in terms of performance
or not I don't know, but it does seem to solve the relocation
problem from the point of the executable program since a.o does
not (typically) contain relocatable code. Looking at the
disassembly should tell you if I'm smoking something or not ;-)
Martin
PS Here's an example better illustrating what I'm trying to
describe above:
$ (cat t.cpp; gcc -c -fpic -g -s t.cpp && gcc -shared -o libbar.so t.o
&& gcc -DMAIN t.cpp -L. -lbar && export LD_LIBRARY_PATH=. && ./a.out)
template <class T>
struct S {
static const T t_;
int foo (const T*) const;
};
template <class T>
int S<T>::foo (const T *t) const { return t == &t_; }
int bar (const int*);
#ifndef MAIN
template class S<int>;
int bar (const int *i) { return &S<int>::t_ == i; }
#else
template <class T>
const T S<T>::t_ = T ();
extern "C" int printf (const char*, ...);
int main ()
{
S<int> s;
printf ("%d %d\n", s.foo (&S<int>::t_), bar (&S<int>::t_));
}
#endif
1 1