Issue C-2 comments: initialization priority
Jim Dehnert
dehnert at baalbek.engr.sgi.com
Thu Nov 11 03:01:56 UTC 1999
I said I would revisit my proposal, looking at two questions:
A) Can we sort based on section name instead of data?
B) Can we get less linker impact?
I'll address them separately.
----------------
B) Linker impact
----------------
I believe the proposal made need have almost no linker impact.
Consider the second suggested implementation scheme, based on IBM's
description of their approach.
A minimalist implementation (from the linker point of view)
includes:
1) The link components are bracketed (either by a driver constructing
the command line, or by implicit arguments generated within the
linker) by two INIT_ARRAY entries. The first calls
__cxx_priority_init_begin()
The one at the end calls
__cxx_priority_init_end()
These are both in the implementation runtime. The begin routine
determines the address and size of the SHT_CXX_PRIORITY_INIT section
(below). It sorts the section by priority, and calls
__cxx_priority_init(addr,cnt) as described in the proposal with the
count of <=0 entries.
__cxx_priority_init_end calls __cxx_priority_init(addr,cnt) with the
address and count of >0 entries.
2) The linker simply concatenates the SHT_CXX_PRIORITY_INIT sections,
and emits markers (DT entries) that allow __cxx_priority_init_begin
to find the section and its size. At the same time, it creates a
init_array section from other (i.e. non-constructor) entries as it
normally would, which of course gets bracketed by the entries
described above.
3) At runtime, when loading the executable object, the init_array
entries are executed, thereby sorting the constructor entries,
executing the <=0-priority entries, executing the non-constructor
entries, and finally executing the >0-priority entries.
My original proposal did not describe the dynamic tags to delimit the
section, nor the __cxx_priority_init_<begin,end> routines. Given such
an approach, it's hard for me to imagine much less linker impact.
Now suppose you want to minimize runtime instead of linker impact --
the first suggested implementation scheme. There are at least two
approaches:
- The linker sorts the SHT_CXX_PRIORITY_INIT section after generating
it, and emits bracketing __cxx_priority_init_<begin,end> calls in
init_array entries itself.
- To make things even simpler for the runtime, the linker could also
convert init_array entries in the .o files to CXX_PRIORITY_INIT
section entries with priority zero, reducing everything to a single
init_array entry that calls __cxx_priority_init.
One of my original objectives, and I think a key attribute of this
proposal, is that this full range of possible implementations, from
minimal linker impact to minimal runtime impact, makes absolutely no
difference to the generated .o files -- compatibility between compilers
does not depend on the chosen link-time implementation.
-------------------
A) Sorting approach
-------------------
Sorting is a more interesting issue. I see four possibilities:
1) No sorting -- the low-linker-impact approach above.
2) Implicit sorting -- the low-runtime approach above, with knowledge
explicit in the linker about how to sort SHT_CXX_PRIORITY_INIT.
3) Explicit sorting within a section, e.g. what my proposal described,
based on an explicit sorting specification that describes the size
of objects to be sorted and the key location.
4) Explicit sorting of sections, based on a sort key encoded in the
section name (for example).
I'll say up front that I think implicit sorting is adequate for the
purpose at hand, and I'd like to understand other applications before
I'd choose (3) or (4).
There are two differences between (3) and (4):
- the unit of sorting (an object within a section, or a whole section)
- the sort key (part of the data, or separate from the data).
Either would work for the application at hand. Approach (3) would
require only one SHT_CXX_PRIORITY_INIT section per .o file, while
approach (4) would require up to one such section per constructor call
(though only if the user used lots of different priorities). I
personally think sorting based on a data vector that's already been
concatenated should be much more efficient, but it probably doesn't
matter much.
On the other hand, sorting an arbitrarily-sized section, based on an
external key, is more flexible except that the keys may be more
constrained. So, again, I think the choice comes down to other
applications of the feature. Absent significant other demands, I'd
just stick to implicit sorting (and optional at that) for now.
Jim
- Jim Dehnert x3-4272
More information about the cxx-abi-dev
mailing list