@@ -89,32 +89,44 @@ def main():
89
89
# alloc_fns contains all the vanilla allocation/free functions that we look
90
90
# for. Regexp chars are escaped appropriately.
91
91
92
- alloc_fns = [
92
+ operator_news = [
93
93
# Matches |operator new(unsigned T)|, where |T| is |int| or |long|.
94
- r"operator new\ (unsigned" ,
94
+ r"operator new(unsigned" ,
95
95
# Matches |operator new[](unsigned T)|, where |T| is |int| or |long|.
96
- r"operator new\[\]\(unsigned" ,
97
- r"memalign" ,
98
- # These three aren't available on all Linux configurations.
99
- # r'posix_memalign',
100
- # r'aligned_alloc',
101
- # r'valloc',
96
+ r"operator new[](unsigned" ,
102
97
]
103
98
99
+ # operator new may end up inlined and replaced with moz_xmalloc.
100
+ inlined_operator_news = [
101
+ r"moz_xmalloc" ,
102
+ ]
103
+
104
+ alloc_fns = (
105
+ operator_news
106
+ + inlined_operator_news
107
+ + [
108
+ r"memalign" ,
109
+ # These three aren't available on all Linux configurations.
110
+ # r'posix_memalign',
111
+ # r'aligned_alloc',
112
+ # r'valloc',
113
+ ]
114
+ )
115
+
104
116
if args .aggressive :
105
117
alloc_fns += [r"malloc" , r"calloc" , r"realloc" , r"free" , r"strdup" ]
106
118
107
119
# This is like alloc_fns, but regexp chars are not escaped.
108
- alloc_fns_unescaped = [fn . replace ( " \\ " , "" ) for fn in alloc_fns ]
120
+ alloc_fns_escaped = [re . escape ( fn ) for fn in alloc_fns ]
109
121
110
122
# This regexp matches the relevant lines in the output of |nm|, which look
111
123
# like the following.
112
124
#
113
125
# js/src/libjs_static.a:Utility.o: U malloc
114
126
# js/src/libjs_static.a:Utility.o: 00000000000007e0 T js::SetSourceOptions(...)
115
127
#
116
- nm_line_re = re .compile (r"([^:/ ]+):\s*[0-9a-fA-F]*\s+([TU ]) (.*)" )
117
- alloc_fns_re = re .compile (r"|" .join (alloc_fns ))
128
+ nm_line_re = re .compile (r"([^:/ ]+):\s*[0-9a-fA-F]*\s+([TUw ]) (.*)" )
129
+ alloc_fns_re = re .compile (r"|" .join (alloc_fns_escaped ))
118
130
119
131
# This tracks which allocation/free functions have been seen.
120
132
functions = defaultdict (set )
@@ -202,9 +214,24 @@ def main():
202
214
203
215
# Check that all functions we expect are used in util/Utility.cpp. (This
204
216
# will fail if the function-detection code breaks at any point.)
205
- for fn in alloc_fns_unescaped :
217
+ # operator new and its inlined equivalent are mutually exclusive.
218
+ has_operator_news = any (fn in operator_news for fn in util_Utility_cpp )
219
+ has_inlined_operator_news = any (
220
+ fn in inlined_operator_news for fn in util_Utility_cpp
221
+ )
222
+ if has_operator_news and has_inlined_operator_news :
223
+ fail (
224
+ "Both operator new and moz_xmalloc aren't expected in util/Utility.cpp at the same time"
225
+ )
226
+
227
+ for fn in alloc_fns :
206
228
if fn not in util_Utility_cpp :
207
- fail ("'" + fn + "' isn't used as expected in util/Utility.cpp" )
229
+ if (
230
+ (fn in operator_news and not has_inlined_operator_news )
231
+ or (fn in inlined_operator_news and not has_operator_news )
232
+ or (fn not in operator_news and fn not in inlined_operator_news )
233
+ ):
234
+ fail ("'" + fn + "' isn't used as expected in util/Utility.cpp" )
208
235
else :
209
236
util_Utility_cpp .remove (fn )
210
237
@@ -240,7 +267,9 @@ def main():
240
267
#
241
268
# U malloc util/Utility.cpp:117
242
269
#
243
- alloc_lines_re = r"U ((" + r"|" .join (alloc_fns ) + r").*)\s+(\S+:\d+)$"
270
+ alloc_lines_re = (
271
+ r"[Uw] ((" + r"|" .join (alloc_fns_escaped ) + r").*)\s+(\S+:\d+)$"
272
+ )
244
273
245
274
for line in lines :
246
275
m = re .search (alloc_lines_re , line )
0 commit comments