39 const std::vector<irep_idt> &main_jar_classes,
40 const std::vector<load_extra_methodst> &lazy_methods_extra_entry_points,
42 const std::vector<irep_idt> &extra_instantiated_classes,
45 : main_class(main_class),
46 main_jar_classes(main_jar_classes),
47 lazy_methods_extra_entry_points(lazy_methods_extra_entry_points),
48 java_class_loader(java_class_loader),
49 extra_instantiated_classes(extra_instantiated_classes),
50 pointer_type_selector(pointer_type_selector),
51 synthetic_methods(synthetic_methods)
70 it->type() == class_type &&
104 std::unordered_set<irep_idt> methods_to_convert_later =
111 std::vector<irep_idt> extra_methods =
112 extra_function_generator(symbol_table);
113 methods_to_convert_later.insert(extra_methods.begin(), extra_methods.end());
116 std::unordered_set<irep_idt> instantiated_classes;
119 std::unordered_set<irep_idt> initial_callable_methods;
121 initial_callable_methods,
122 instantiated_classes,
126 methods_to_convert_later,
namespacet(symbol_table), initial_lazy_methods);
127 methods_to_convert_later.insert(
128 initial_callable_methods.begin(), initial_callable_methods.end());
131 std::unordered_set<irep_idt> methods_already_populated;
132 std::unordered_set<class_method_descriptor_exprt, irep_hash>
133 called_virtual_functions;
134 bool class_initializer_seen =
false;
138 bool any_new_classes =
true;
139 while(any_new_classes)
141 bool any_new_methods =
true;
142 while(any_new_methods)
144 any_new_methods =
false;
145 while(!methods_to_convert_later.empty())
147 std::unordered_set<irep_idt> methods_to_convert;
148 std::swap(methods_to_convert, methods_to_convert_later);
149 for(
const auto &mname : methods_to_convert)
153 methods_already_populated,
154 class_initializer_seen,
157 methods_to_convert_later,
158 instantiated_classes,
159 called_virtual_functions,
161 any_new_methods |= conversion_result.new_method_seen;
162 class_initializer_seen |= conversion_result.class_initializer_seen;
169 log.debug() <<
"CI lazy methods: add virtual method targets ("
170 << called_virtual_functions.size() <<
" callsites)"
174 called_virtual_functions)
177 called_virtual_function,
178 instantiated_classes,
179 methods_to_convert_later,
185 methods_to_convert_later,
186 instantiated_classes,
187 called_virtual_functions,
197 for(
const auto &sym : symbol_table.
symbols)
201 if(sym.second.is_static_lifetime)
203 if(sym.second.type.id()==ID_code)
210 !methods_already_populated.count(sym.first))
217 keep_symbols.
add(sym.second);
220 log.debug() <<
"CI lazy methods: removed "
224 symbol_table.
swap(keep_symbols);
237 std::unordered_set<irep_idt> &methods_to_convert_later,
238 std::unordered_set<irep_idt> &instantiated_classes,
239 const std::unordered_set<class_method_descriptor_exprt, irep_hash>
244 methods_to_convert_later,
245 instantiated_classes,
249 bool any_new_classes =
false;
252 std::unordered_set<irep_idt> candidate_target_methods;
255 instantiated_classes,
256 candidate_target_methods,
259 if(!candidate_target_methods.empty())
269 const irep_idt &call_class = virtual_function.class_id();
270 bool was_missing = instantiated_classes.count(call_class) == 0;
272 any_new_classes =
true;
277 type_try_dynamic_cast<pointer_typet>(this_type))
284 bool still_missing = instantiated_classes.count(call_class) == 0;
292 type_try_dynamic_cast<pointer_typet>(return_type))
298 const irep_idt &method_name = virtual_function.mangled_method_name();
300 instantiated_classes, method_name, call_class, symbol_table);
304 methods_to_convert_later.insert(method_id);
306 return any_new_classes;
321 std::unordered_set<irep_idt> &methods_already_populated,
322 const bool class_initializer_already_seen,
325 std::unordered_set<irep_idt> &methods_to_convert_later,
326 std::unordered_set<irep_idt> &instantiated_classes,
327 std::unordered_set<class_method_descriptor_exprt, irep_hash>
328 &called_virtual_functions,
332 if(!methods_already_populated.insert(method_name).second)
336 log.debug() <<
"CI lazy methods: elaborate " << method_name <<
messaget::eom;
341 methods_to_convert_later,
342 instantiated_classes,
346 if(method_converter(method_name, needed_methods))
355 const irep_idt initializer_signature =
357 if(symbol_table.
has_symbol(initializer_signature))
358 methods_to_convert_later.insert(initializer_signature);
373 std::unordered_set<irep_idt> methods_to_convert_later;
381 std::vector<irep_idt> reachable_classes;
383 reachable_classes.push_back(this->
main_class);
386 for(
const irep_idt &class_name : reachable_classes)
388 const auto &methods =
391 for(
const auto &method : methods)
396 methods_to_convert_later.insert(methodid);
402 return methods_to_convert_later;
414 const std::unordered_set<irep_idt> &entry_points,
418 for(
const auto &mname : entry_points)
420 const auto &symbol=ns.
lookup(mname);
422 for(
const auto ¶m : mtype.parameters())
424 if(param.type().id()==ID_pointer)
450 std::unordered_set<class_method_descriptor_exprt, irep_hash> &result)
482 const std::unordered_set<irep_idt> &instantiated_classes,
483 std::unordered_set<irep_idt> &callable_methods,
486 const auto &call_class = called_function.
class_id();
491 self_and_child_classes.push_back(call_class);
493 for(
const irep_idt &class_name : self_and_child_classes)
496 instantiated_classes, method_name, class_name, symbol_table);
497 if(!method_id.
empty())
498 callable_methods.insert(method_id);
512 if(e.
id()==ID_symbol)
520 if(findit!=symbol_table.
symbols.end() &&
521 findit->second.is_static_lifetime)
523 needed.
add(findit->second);
546 const std::unordered_set<irep_idt> &instantiated_classes,
552 if(!instantiated_classes.count(classname))
559 return resolved_call->get_full_component_identifier();