@@ -111,7 +111,7 @@ class Collect_export_references : public Traverse
111
111
: Traverse(traverse_expressions
112
112
| traverse_types),
113
113
exp_(exp), exports_(exports), imports_(imports),
114
- inline_fcn_worklist_(NULL )
114
+ inline_fcn_worklist_(NULL ), exports_finalized_( false )
115
115
{ }
116
116
117
117
// Initial entry point; performs a walk to expand the exports set.
@@ -121,7 +121,7 @@ class Collect_export_references : public Traverse
121
121
// Second entry point (called after the method above), to find
122
122
// all types referenced by exports.
123
123
void
124
- prepare_types ();
124
+ prepare_types (const std::vector<Named_object*>& sorted_exports );
125
125
126
126
protected:
127
127
// Override of parent class method.
@@ -141,6 +141,13 @@ class Collect_export_references : public Traverse
141
141
traverse_named_type (Named_type*);
142
142
143
143
private:
144
+
145
+ // Add a named object to the exports set (during expand_exports()).
146
+ // Returns TRUE if a new object was added to the exports set,
147
+ // FALSE otherwise.
148
+ bool
149
+ add_to_exports (Named_object*);
150
+
144
151
// The exporter.
145
152
Export* exp_;
146
153
// The set of named objects to export.
@@ -152,6 +159,8 @@ class Collect_export_references : public Traverse
152
159
// Worklist of functions we are exporting with inline bodies that need
153
160
// to be checked.
154
161
std::vector<Named_object*>* inline_fcn_worklist_;
162
+ // Set to true if expand_exports() has been called and is complete.
163
+ bool exports_finalized_;
155
164
};
156
165
157
166
void
@@ -172,6 +181,18 @@ Collect_export_references::expand_exports(std::vector<Named_object*>* fcns)
172
181
}
173
182
}
174
183
this ->inline_fcn_worklist_ = NULL ;
184
+ this ->exports_finalized_ = true ;
185
+ }
186
+
187
+ bool
188
+ Collect_export_references::add_to_exports (Named_object* no)
189
+ {
190
+ std::pair<Unordered_set (Named_object*)::iterator, bool > ins =
191
+ this ->exports_ ->insert (no);
192
+ // If the export list has been finalized, then we should not be
193
+ // adding anything new to the exports set.
194
+ go_assert (!this ->exports_finalized_ || !ins.second );
195
+ return ins.second ;
175
196
}
176
197
177
198
int
@@ -189,7 +210,7 @@ Collect_export_references::expression(Expression** pexpr)
189
210
if (var_package != NULL )
190
211
this ->imports_ ->insert (var_package);
191
212
192
- this ->exports_ -> insert (no);
213
+ this ->add_to_exports (no);
193
214
no->var_value ()->set_is_referenced_by_inline ();
194
215
}
195
216
return TRAVERSE_CONTINUE;
@@ -210,17 +231,16 @@ Collect_export_references::expression(Expression** pexpr)
210
231
211
232
if (this ->inline_fcn_worklist_ != NULL )
212
233
{
213
- std::pair<Unordered_set (Named_object*)::iterator, bool > ins =
214
- this ->exports_ ->insert (no);
234
+ bool added = this ->add_to_exports (no);
215
235
216
236
if (no->is_function ())
217
237
no->func_value ()->set_is_referenced_by_inline ();
218
238
219
- // If ins.second is false then this object was already in
239
+ // If 'added' is false then this object was already in
220
240
// exports_, in which case it was already added to
221
241
// check_inline_refs_ the first time we added it to exports_, so
222
242
// we don't need to add it again.
223
- if (ins. second
243
+ if (added
224
244
&& no->is_function ()
225
245
&& no->func_value ()->export_for_inlining ())
226
246
this ->inline_fcn_worklist_ ->push_back (no);
@@ -238,11 +258,11 @@ Collect_export_references::expression(Expression** pexpr)
238
258
// exported inline function from another package).
239
259
240
260
void
241
- Collect_export_references::prepare_types ()
261
+ Collect_export_references::prepare_types (const std::vector<Named_object*>& sorted_exports )
242
262
{
243
263
// Iterate through the exported objects and traverse any types encountered.
244
- for (Unordered_set ( Named_object*)::iterator p = this -> exports_ -> begin ();
245
- p != this -> exports_ -> end ();
264
+ for (std::vector< Named_object*>::const_iterator p = sorted_exports. begin ();
265
+ p != sorted_exports. end ();
246
266
++p)
247
267
{
248
268
Named_object* no = *p;
@@ -506,7 +526,8 @@ Export::export_globals(const std::string& package_name,
506
526
const std::map<std::string, Package*>& imports,
507
527
const std::string& import_init_fn,
508
528
const Import_init_set& imported_init_fns,
509
- const Bindings* bindings)
529
+ const Bindings* bindings,
530
+ Unordered_set (Named_object*)* functions_marked_inline)
510
531
{
511
532
// If there have been any errors so far, don't try to export
512
533
// anything. That way the export code doesn't have to worry about
@@ -520,35 +541,21 @@ Export::export_globals(const std::string& package_name,
520
541
// CHECK_INLINE_REFS is also on EXPORTS.
521
542
Unordered_set (Named_object*) exports;
522
543
std::vector<Named_object*> check_inline_refs;
544
+ check_inline_refs.reserve (functions_marked_inline->size ());
545
+
546
+ // Add all functions/methods from the "marked inlined" set to the
547
+ // CHECK_INLINE_REFS worklist.
548
+ for (Unordered_set (Named_object*)::const_iterator p = functions_marked_inline->begin ();
549
+ p != functions_marked_inline->end ();
550
+ ++p)
551
+ check_inline_refs.push_back (*p);
523
552
524
553
for (Bindings::const_definitions_iterator p = bindings->begin_definitions ();
525
554
p != bindings->end_definitions ();
526
555
++p)
527
556
{
528
557
if (should_export (*p))
529
- {
530
- exports.insert (*p);
531
-
532
- if ((*p)->is_function ()
533
- && (*p)->func_value ()->export_for_inlining ())
534
- check_inline_refs.push_back (*p);
535
- else if ((*p)->is_type ())
536
- {
537
- const Bindings* methods = (*p)->type_value ()->local_methods ();
538
- if (methods != NULL )
539
- {
540
- for (Bindings::const_definitions_iterator pm =
541
- methods->begin_definitions ();
542
- pm != methods->end_definitions ();
543
- ++pm)
544
- {
545
- Function* fn = (*pm)->func_value ();
546
- if (fn->export_for_inlining ())
547
- check_inline_refs.push_back (*pm);
548
- }
549
- }
550
- }
551
- }
558
+ exports.insert (*p);
552
559
}
553
560
554
561
for (Bindings::const_declarations_iterator p =
@@ -593,7 +600,7 @@ Export::export_globals(const std::string& package_name,
593
600
594
601
// Collect up the set of types mentioned in things we're exporting,
595
602
// and any packages that may be referred to indirectly.
596
- collect.prepare_types ();
603
+ collect.prepare_types (sorted_exports );
597
604
598
605
// Assign indexes to all exported types and types referenced by
599
606
// things we're exporting. Return value is index of first non-exported
0 commit comments