40 const std::vector<irep_idt> &main_jar_classes,
41 const std::vector<load_extra_methodst> &lazy_methods_extra_entry_points,
43 const std::vector<irep_idt> &extra_instantiated_classes,
48 main_class(main_class),
49 main_jar_classes(main_jar_classes),
50 lazy_methods_extra_entry_points(lazy_methods_extra_entry_points),
51 java_class_loader(java_class_loader),
52 extra_instantiated_classes(extra_instantiated_classes),
53 pointer_type_selector(pointer_type_selector),
54 synthetic_methods(synthetic_methods)
73 it->type() == class_type &&
105 std::unordered_set<irep_idt> methods_to_convert_later =
112 std::vector<irep_idt> extra_methods =
113 extra_function_generator(symbol_table);
114 methods_to_convert_later.insert(extra_methods.begin(), extra_methods.end());
117 std::unordered_set<irep_idt> instantiated_classes;
120 std::unordered_set<irep_idt> initial_callable_methods;
122 initial_callable_methods,
123 instantiated_classes,
127 methods_to_convert_later,
namespacet(symbol_table), initial_lazy_methods);
128 methods_to_convert_later.insert(
129 initial_callable_methods.begin(), initial_callable_methods.end());
132 std::unordered_set<irep_idt> methods_already_populated;
133 std::unordered_set<class_method_descriptor_exprt, irep_hash>
134 called_virtual_functions;
135 bool class_initializer_seen =
false;
137 bool any_new_classes =
true;
138 while(any_new_classes)
140 bool any_new_methods =
true;
141 while(any_new_methods)
143 any_new_methods =
false;
144 while(!methods_to_convert_later.empty())
146 std::unordered_set<irep_idt> methods_to_convert;
147 std::swap(methods_to_convert, methods_to_convert_later);
148 for(
const auto &mname : methods_to_convert)
152 methods_already_populated,
153 class_initializer_seen,
156 methods_to_convert_later,
157 instantiated_classes,
158 called_virtual_functions);
159 any_new_methods |= conversion_result.new_method_seen;
160 class_initializer_seen |= conversion_result.class_initializer_seen;
167 debug() <<
"CI lazy methods: add virtual method targets ("
168 << called_virtual_functions.size() <<
" callsites)" <<
eom;
171 called_virtual_functions)
174 called_virtual_function,
175 instantiated_classes,
176 methods_to_convert_later,
182 methods_to_convert_later,
183 instantiated_classes,
184 called_virtual_functions,
194 for(
const auto &sym : symbol_table.
symbols)
198 if(sym.second.is_static_lifetime)
200 if(sym.second.type.id()==ID_code)
207 !methods_already_populated.count(sym.first))
214 keep_symbols.
add(sym.second);
217 debug() <<
"CI lazy methods: removed "
219 <<
" unreachable methods and globals" <<
eom;
221 symbol_table.
swap(keep_symbols);
234 std::unordered_set<irep_idt> &methods_to_convert_later,
235 std::unordered_set<irep_idt> &instantiated_classes,
236 const std::unordered_set<class_method_descriptor_exprt, irep_hash>
241 methods_to_convert_later,
242 instantiated_classes,
246 bool any_new_classes =
false;
249 std::unordered_set<irep_idt> candidate_target_methods;
252 instantiated_classes,
253 candidate_target_methods,
256 if(!candidate_target_methods.empty())
266 const irep_idt &call_class = virtual_function.class_id();
267 bool was_missing = instantiated_classes.count(call_class) == 0;
269 any_new_classes =
true;
274 type_try_dynamic_cast<pointer_typet>(this_type))
281 bool still_missing = instantiated_classes.count(call_class) == 0;
289 type_try_dynamic_cast<pointer_typet>(return_type))
295 const irep_idt &method_name = virtual_function.mangled_method_name();
297 instantiated_classes, method_name, call_class, symbol_table);
301 methods_to_convert_later.insert(method_id);
303 return any_new_classes;
318 std::unordered_set<irep_idt> &methods_already_populated,
319 const bool class_initializer_already_seen,
322 std::unordered_set<irep_idt> &methods_to_convert_later,
323 std::unordered_set<irep_idt> &instantiated_classes,
324 std::unordered_set<class_method_descriptor_exprt, irep_hash>
325 &called_virtual_functions)
328 if(!methods_already_populated.insert(method_name).second)
331 debug() <<
"CI lazy methods: elaborate " << method_name <<
eom;
336 methods_to_convert_later,
337 instantiated_classes,
341 if(method_converter(method_name, needed_methods))
349 result.class_initializer_seen =
true;
350 const irep_idt initializer_signature =
352 if(symbol_table.
has_symbol(initializer_signature))
353 methods_to_convert_later.insert(initializer_signature);
355 result.new_method_seen =
true;
364 std::unordered_set<irep_idt>
367 std::unordered_set<irep_idt> methods_to_convert_later;
375 std::vector<irep_idt> reachable_classes;
377 reachable_classes.push_back(this->
main_class);
380 for(
const irep_idt &class_name : reachable_classes)
382 const auto &methods =
385 for(
const auto &method : methods)
390 methods_to_convert_later.insert(methodid);
396 return methods_to_convert_later;
408 const std::unordered_set<irep_idt> &entry_points,
412 for(
const auto &mname : entry_points)
414 const auto &symbol=ns.
lookup(mname);
416 for(
const auto ¶m : mtype.parameters())
418 if(param.type().id()==ID_pointer)
444 std::unordered_set<class_method_descriptor_exprt, irep_hash> &result)
476 const std::unordered_set<irep_idt> &instantiated_classes,
477 std::unordered_set<irep_idt> &callable_methods,
480 const auto &call_class = called_function.
class_id();
485 self_and_child_classes.push_back(call_class);
487 for(
const irep_idt &class_name : self_and_child_classes)
490 instantiated_classes, method_name, class_name, symbol_table);
491 if(!method_id.
empty())
492 callable_methods.insert(method_id);
506 if(e.
id()==ID_symbol)
514 if(findit!=symbol_table.
symbols.end() &&
515 findit->second.is_static_lifetime)
517 needed.
add(findit->second);
540 const std::unordered_set<irep_idt> &instantiated_classes,
546 if(!instantiated_classes.count(classname))
553 return resolved_call->get_full_component_identifier();