Skip to content

Commit 8855262

Browse files
committed
Bug 1269171 - Change how mozalloc.h is hooked in STL wrappers. r=froydnj
Since the introduction of the STL wrappers, they have included mozalloc.h, and multiple times, we've hit header reentrancy problems, and worked around them as best as we could. Taking a step back, all mozalloc.h does is: - declare moz_* allocator functions. - define inline implementations of various operator new/delete variants. The first only requires the functions to be declared before they are used, so mozalloc.h only needs to be included before anything that would use those functions. The second doesn't actually require a specific order, as long as the declaration for those functions comes before their use, and they are either declared in <new> or implicitly by the C++ compiler. So all in all, it doesn't matter that mozalloc.h is included before the wrapped STL headers. What matters is that it's included when STL headers are included. So arrange things such that mozalloc.h is included after the first wrapped STL header is fully preprocessed (and all its includes have been included).
1 parent 60564d7 commit 8855262

File tree

4 files changed

+51
-49
lines changed

4 files changed

+51
-49
lines changed

config/gcc-stl-wrapper.template.h

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,34 @@
1717
// Silence "warning: #include_next is a GCC extension"
1818
#pragma GCC system_header
1919

20+
#if defined(DEBUG) && !defined(_GLIBCXX_DEBUG)
21+
// Enable checked iterators and other goodies
22+
//
23+
// FIXME/bug 551254: gcc's debug STL implementation requires -frtti.
24+
// Figure out how to resolve this with -fno-rtti. Maybe build with
25+
// -frtti in DEBUG builds?
26+
//
27+
// # define _GLIBCXX_DEBUG 1
28+
#endif
29+
2030
// Don't include mozalloc for cstdlib. See bug 1245076.
2131
#ifndef moz_dont_include_mozalloc_for_cstdlib
2232
# define moz_dont_include_mozalloc_for_cstdlib
2333
#endif
24-
#ifndef moz_dont_include_mozalloc_for_${HEADER}
25-
// mozalloc.h wants <new>; break the cycle by always explicitly
26-
// including <new> here. NB: this is a tad sneaky. Sez the gcc docs:
27-
//
28-
// `#include_next' does not distinguish between <file> and "file"
29-
// inclusion, nor does it check that the file you specify has the
30-
// same name as the current file. It simply looks for the file
31-
// named, starting with the directory in the search path after the
32-
// one where the current file was found.
33-
# include_next <new>
3434

35+
// Include mozalloc after the STL header and all other headers it includes
36+
// have been preprocessed.
37+
#if !defined(MOZ_INCLUDE_MOZALLOC_H) && \
38+
!defined(moz_dont_include_mozalloc_for_${HEADER})
39+
# define MOZ_INCLUDE_MOZALLOC_H
40+
# define MOZ_INCLUDE_MOZALLOC_H_FROM_${HEADER}
41+
#endif
42+
43+
#pragma GCC visibility push(default)
44+
#include_next <${HEADER}>
45+
#pragma GCC visibility pop
46+
47+
#ifdef MOZ_INCLUDE_MOZALLOC_H_FROM_${HEADER}
3548
// See if we're in code that can use mozalloc. NB: this duplicates
3649
// code in nscore.h because nscore.h pulls in prtypes.h, and chromium
3750
// can't build with that being included before base/basictypes.h.
@@ -40,23 +53,8 @@
4053
# else
4154
# error "STL code can only be used with infallible ::operator new()"
4255
# endif
43-
44-
#endif
45-
46-
#if defined(DEBUG) && !defined(_GLIBCXX_DEBUG)
47-
// Enable checked iterators and other goodies
48-
//
49-
// FIXME/bug 551254: gcc's debug STL implementation requires -frtti.
50-
// Figure out how to resolve this with -fno-rtti. Maybe build with
51-
// -frtti in DEBUG builds?
52-
//
53-
// # define _GLIBCXX_DEBUG 1
5456
#endif
5557

56-
#pragma GCC visibility push(default)
57-
#include_next <${HEADER}>
58-
#pragma GCC visibility pop
59-
6058
// gcc calls a __throw_*() function from bits/functexcept.h when it
6159
// wants to "throw an exception". functexcept exists nominally to
6260
// support -fno-exceptions, but since we'll always use the system

config/make-stl-wrappers.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ def main(outdir, compiler, template_file, header_list_file):
3030
os.mkdir(outdir)
3131

3232
template = open(template_file, 'r').read()
33-
path_to_new = header_path('new', compiler)
3433

3534
for header in open(header_list_file, 'r'):
3635
header = header.rstrip()
@@ -40,8 +39,7 @@ def main(outdir, compiler, template_file, header_list_file):
4039
path = header_path(header, compiler)
4140
with FileAvoidWrite(os.path.join(outdir, header)) as f:
4241
f.write(string.Template(template).substitute(HEADER=header,
43-
HEADER_PATH=path,
44-
NEW_HEADER_PATH=path_to_new))
42+
HEADER_PATH=path))
4543

4644

4745
if __name__ == '__main__':

config/msvc-stl-wrapper.template.h

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,23 @@
88
#ifndef mozilla_${HEADER}_h
99
#define mozilla_${HEADER}_h
1010

11-
#ifndef MOZ_HAVE_INCLUDED_ALLOC
12-
#define MOZ_HAVE_INCLUDED_ALLOC
13-
1411
#if _HAS_EXCEPTIONS
1512
# error "STL code can only be used with -fno-exceptions"
1613
#endif
1714

15+
// Include mozalloc after the STL header and all other headers it includes
16+
// have been preprocessed.
17+
#if !defined(MOZ_INCLUDE_MOZALLOC_H)
18+
# define MOZ_INCLUDE_MOZALLOC_H
19+
# define MOZ_INCLUDE_MOZALLOC_H_FROM_${HEADER}
20+
#endif
21+
1822
// Code built with !_HAS_EXCEPTIONS calls std::_Throw(), but the win2k
1923
// CRT doesn't export std::_Throw(). So we define it.
2024
#ifndef mozilla_Throw_h
2125
# include "mozilla/throw_msvc.h"
2226
#endif
2327

24-
// Code might include <new> before other wrapped headers, but <new>
25-
// includes <exception> and so we want to wrap it. But mozalloc.h
26-
// wants <new> also, so we break the cycle by always explicitly
27-
// including <new> here.
28-
#include <${NEW_HEADER_PATH}>
29-
30-
// See if we're in code that can use mozalloc. NB: this duplicates
31-
// code in nscore.h because nscore.h pulls in prtypes.h, and chromium
32-
// can't build with that being included before base/basictypes.h.
33-
#if !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC)
34-
# include "mozilla/mozalloc.h"
35-
#else
36-
# error "STL code can only be used with infallible ::operator new()"
37-
#endif
38-
#endif /* MOZ_HAVE_INCLUDED_ALLOC */
39-
4028
#ifdef _DEBUG
4129
// From
4230
// http://msdn.microsoft.com/en-us/library/aa985982%28VS.80%29.aspx
@@ -75,4 +63,15 @@
7563

7664
#pragma warning( pop )
7765

66+
#ifdef MOZ_INCLUDE_MOZALLOC_H_FROM_${HEADER}
67+
// See if we're in code that can use mozalloc. NB: this duplicates
68+
// code in nscore.h because nscore.h pulls in prtypes.h, and chromium
69+
// can't build with that being included before base/basictypes.h.
70+
# if !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC)
71+
# include "mozilla/mozalloc.h"
72+
# else
73+
# error "STL code can only be used with infallible ::operator new()"
74+
# endif
75+
#endif
76+
7877
#endif // if mozilla_${HEADER}_h

memory/mozalloc/mozalloc.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,17 @@
1212
* https://bugzilla.mozilla.org/show_bug.cgi?id=427099
1313
*/
1414

15-
#include <stdlib.h>
16-
#include <string.h>
1715
#if defined(__cplusplus)
1816
# include <new>
17+
// Since libstdc++ 6, including the C headers (e.g. stdlib.h) instead of the
18+
// corresponding C++ header (e.g. cstdlib) can cause confusion in C++ code
19+
// using things defined there. Specifically, with stdlib.h, the use of abs()
20+
// in gfx/graphite2/src/inc/UtfCodec.h somehow ends up picking the wrong abs()
21+
# include <cstdlib>
22+
# include <cstring>
23+
#else
24+
# include <stdlib.h>
25+
# include <string.h>
1926
#endif
2027

2128
#if defined(__cplusplus)

0 commit comments

Comments
 (0)