Skip to content

Commit 3548d99

Browse files
author
Thomas Kiley
authored
Merge pull request diffblue#1917 from owen-jones-diffblue/owen-jones-diffblue/lazy-methods-do-not-create-stubs-when-resolving-virtual-calls
Do not create stubs when resolving virtual calls
2 parents e7a6769 + b87661e commit 3548d99

File tree

5 files changed

+66
-77
lines changed

5 files changed

+66
-77
lines changed

src/goto-programs/resolve_inherited_component.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ resolve_inherited_componentt::resolve_inherited_componentt(
4040
/// \param class_id: The name of the class the function is being called on
4141
/// \param component_name: The base name of the component (i.e. without the
4242
/// class specifier)
43-
/// \param include_interfaces: If true, consider inheritence from interfaces
43+
/// \param include_interfaces: If true, consider inheritance from interfaces
4444
/// (parent types other than the first listed)
4545
/// \return The concrete component that has been resolved
4646
resolve_inherited_componentt::inherited_componentt

src/java_bytecode/ci_lazy_methods.cpp

+47-58
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
/// \param main_jar_classes: specify main class of jar if \p main_class is empty
2323
/// \param lazy_methods_extra_entry_points: entry point functions to use
2424
/// \param java_class_loader: the Java class loader to use
25-
/// \param extra_needed_classes: list of class identifiers which are considered
26-
/// to be required and therefore their methods should not be removed via
27-
/// `lazy-methods`. Example of use: `ArrayList` as general implementation for
28-
/// `List` interface.
25+
/// \param extra_instantiated_classes: list of class identifiers which are
26+
/// considered to be required and therefore their methods should not be
27+
/// removed via `lazy-methods`. Example of use: `ArrayList` as general
28+
/// implementation for `List` interface.
2929
/// \param pointer_type_selector: selector to handle correct pointer types
3030
/// \param message_handler: the message handler to use for output
3131
ci_lazy_methodst::ci_lazy_methodst(
@@ -34,7 +34,7 @@ ci_lazy_methodst::ci_lazy_methodst(
3434
const std::vector<irep_idt> &main_jar_classes,
3535
const std::vector<irep_idt> &lazy_methods_extra_entry_points,
3636
java_class_loadert &java_class_loader,
37-
const std::vector<irep_idt> &extra_needed_classes,
37+
const std::vector<irep_idt> &extra_instantiated_classes,
3838
const select_pointer_typet &pointer_type_selector,
3939
message_handlert &message_handler,
4040
const synthetic_methods_mapt &synthetic_methods)
@@ -43,7 +43,7 @@ ci_lazy_methodst::ci_lazy_methodst(
4343
main_jar_classes(main_jar_classes),
4444
lazy_methods_extra_entry_points(lazy_methods_extra_entry_points),
4545
java_class_loader(java_class_loader),
46-
extra_needed_classes(extra_needed_classes),
46+
extra_instantiated_classes(extra_instantiated_classes),
4747
pointer_type_selector(pointer_type_selector),
4848
synthetic_methods(synthetic_methods)
4949
{
@@ -110,22 +110,22 @@ bool ci_lazy_methodst::operator()(
110110
extra_entry_points.begin(),
111111
extra_entry_points.end());
112112

113-
std::set<irep_idt> needed_classes;
113+
std::set<irep_idt> instantiated_classes;
114114

115115
{
116-
std::vector<irep_idt> initial_needed_methods;
116+
std::vector<irep_idt> initial_callable_methods;
117117
ci_lazy_methods_neededt initial_lazy_methods(
118-
initial_needed_methods,
119-
needed_classes,
118+
initial_callable_methods,
119+
instantiated_classes,
120120
symbol_table);
121-
initialize_needed_classes(
121+
initialize_instantiated_classes(
122122
method_worklist2,
123123
namespacet(symbol_table),
124124
initial_lazy_methods);
125125
method_worklist2.insert(
126126
method_worklist2.end(),
127-
initial_needed_methods.begin(),
128-
initial_needed_methods.end());
127+
initial_callable_methods.begin(),
128+
initial_callable_methods.end());
129129
}
130130

131131
std::set<irep_idt> methods_already_populated;
@@ -146,9 +146,10 @@ bool ci_lazy_methodst::operator()(
146146
if(
147147
method_converter(
148148
mname,
149-
// Note this wraps *references* to method_worklist2 & needed_classes
149+
// Note this wraps *references* to method_worklist2 &
150+
// instantiated_classes
150151
ci_lazy_methods_neededt(
151-
method_worklist2, needed_classes, symbol_table)))
152+
method_worklist2, instantiated_classes, symbol_table)))
152153
{
153154
// Couldn't convert this function
154155
continue;
@@ -174,7 +175,7 @@ bool ci_lazy_methodst::operator()(
174175
// This will also create a stub if a virtual callsite has no targets.
175176
get_virtual_method_targets(
176177
*callsite,
177-
needed_classes,
178+
instantiated_classes,
178179
method_worklist2,
179180
symbol_table);
180181
}
@@ -275,7 +276,7 @@ void ci_lazy_methodst::resolve_method_names(
275276
/// \param [out] needed_lazy_methods: Populated with all Java reference types
276277
/// whose references may be passed, directly or indirectly, to any of the
277278
/// functions in `entry_points`.
278-
void ci_lazy_methodst::initialize_needed_classes(
279+
void ci_lazy_methodst::initialize_instantiated_classes(
279280
const std::vector<irep_idt> &entry_points,
280281
const namespacet &ns,
281282
ci_lazy_methods_neededt &needed_lazy_methods)
@@ -289,7 +290,7 @@ void ci_lazy_methodst::initialize_needed_classes(
289290
if(param.type().id()==ID_pointer)
290291
{
291292
const pointer_typet &original_pointer=to_pointer_type(param.type());
292-
initialize_all_needed_classes_from_pointer(
293+
initialize_all_instantiated_classes_from_pointer(
293294
original_pointer, ns, needed_lazy_methods);
294295
}
295296
}
@@ -303,24 +304,27 @@ void ci_lazy_methodst::initialize_needed_classes(
303304
needed_lazy_methods.add_needed_class("java::java.lang.Object");
304305

305306
// As in class_loader, ensure these classes stay available
306-
for(const auto &id : extra_needed_classes)
307+
for(const auto &id : extra_instantiated_classes)
307308
needed_lazy_methods.add_needed_class("java::" + id2string(id));
308309
}
309310

310311
/// Build up list of methods for types for a pointer and any types it
311312
/// might be subsituted for. See
312-
/// `initialize_needed_classes` for more details.
313+
/// `initialize_instantiated_classes` for more details.
313314
/// \param pointer_type: The type to gather methods for.
314315
/// \param ns: global namespace
315316
/// \param [out] needed_lazy_methods: Populated with all Java reference types
316317
/// whose references may be passed, directly or indirectly, to any of the
317318
/// functions in `entry_points`
318-
void ci_lazy_methodst::initialize_all_needed_classes_from_pointer(
319+
void ci_lazy_methodst::initialize_all_instantiated_classes_from_pointer(
319320
const pointer_typet &pointer_type,
320321
const namespacet &ns,
321322
ci_lazy_methods_neededt &needed_lazy_methods)
322323
{
323-
initialize_needed_classes_from_pointer(pointer_type, ns, needed_lazy_methods);
324+
initialize_instantiated_classes_from_pointer(
325+
pointer_type,
326+
ns,
327+
needed_lazy_methods);
324328

325329
// TODO we should be passing here a map that maps generic parameters
326330
// to concrete types in the current context TG-2664
@@ -329,19 +333,19 @@ void ci_lazy_methodst::initialize_all_needed_classes_from_pointer(
329333

330334
if(subbed_pointer_type!=pointer_type)
331335
{
332-
initialize_needed_classes_from_pointer(
336+
initialize_instantiated_classes_from_pointer(
333337
subbed_pointer_type, ns, needed_lazy_methods);
334338
}
335339
}
336340

337341
/// Build up list of methods for types for a specific pointer type. See
338-
/// `initialize_needed_classes` for more details.
342+
/// `initialize_instantiated_classes` for more details.
339343
/// \param pointer_type: The type to gather methods for.
340344
/// \param ns: global namespace
341345
/// \param [out] needed_lazy_methods: Populated with all Java reference types
342346
/// whose references may be passed, directly or indirectly, to any of the
343347
/// functions in `entry_points`
344-
void ci_lazy_methodst::initialize_needed_classes_from_pointer(
348+
void ci_lazy_methodst::initialize_instantiated_classes_from_pointer(
345349
const pointer_typet &pointer_type,
346350
const namespacet &ns,
347351
ci_lazy_methods_neededt &needed_lazy_methods)
@@ -367,7 +371,7 @@ void ci_lazy_methodst::initialize_needed_classes_from_pointer(
367371
{
368372
if(!is_java_generic_parameter(generic_arg))
369373
{
370-
initialize_needed_classes_from_pointer(
374+
initialize_instantiated_classes_from_pointer(
371375
generic_arg, ns, needed_lazy_methods);
372376
}
373377
}
@@ -401,16 +405,16 @@ void ci_lazy_methodst::gather_virtual_callsites(
401405
/// instantiated.
402406
/// \param c: function call whose potential target functions should
403407
/// be determined.
404-
/// \param needed_classes: set of classes that can be instantiated. Any
408+
/// \param instantiated_classes: set of classes that can be instantiated. Any
405409
/// potential callee not in this set will be ignored.
406410
/// \param symbol_table: global symbol table
407-
/// \param [out] needed_methods: Populated with all possible `c` callees, taking
408-
/// `needed_classes` into account (virtual function overrides defined on
409-
/// classes that are not 'needed' are ignored)
411+
/// \param [out] callable_methods: Populated with all possible `c` callees,
412+
/// taking `instantiated_classes` into account (virtual function overrides
413+
/// defined on classes that are not 'needed' are ignored)
410414
void ci_lazy_methodst::get_virtual_method_targets(
411415
const code_function_callt &c,
412-
const std::set<irep_idt> &needed_classes,
413-
std::vector<irep_idt> &needed_methods,
416+
const std::set<irep_idt> &instantiated_classes,
417+
std::vector<irep_idt> &callable_methods,
414418
symbol_tablet &symbol_table)
415419
{
416420
const auto &called_function=c.function();
@@ -424,41 +428,26 @@ void ci_lazy_methodst::get_virtual_method_targets(
424428
!call_basename.empty(),
425429
"Virtual function must have a reasonable name after removing class");
426430

427-
auto old_size=needed_methods.size();
428-
429431
const irep_idt &self_method=
430432
get_virtual_method_target(
431-
needed_classes, call_basename, call_class, symbol_table);
433+
instantiated_classes, call_basename, call_class, symbol_table);
432434

433435
if(!self_method.empty())
434436
{
435-
needed_methods.push_back(self_method);
437+
callable_methods.push_back(self_method);
436438
}
437439

438440
const auto child_classes=class_hierarchy.get_children_trans(call_class);
439441
for(const auto &child_class : child_classes)
440442
{
441443
const auto child_method=
442444
get_virtual_method_target(
443-
needed_classes,
445+
instantiated_classes,
444446
call_basename,
445447
child_class,
446448
symbol_table);
447449
if(!child_method.empty())
448-
needed_methods.push_back(child_method);
449-
}
450-
451-
if(needed_methods.size()==old_size)
452-
{
453-
// Didn't find any candidate callee. Generate a stub.
454-
std::string stubname=id2string(call_class)+"."+id2string(call_basename);
455-
symbolt symbol;
456-
symbol.name=stubname;
457-
symbol.base_name=call_basename;
458-
symbol.type=c.function().type();
459-
symbol.value.make_nil();
460-
symbol.mode=ID_java;
461-
symbol_table.add(symbol);
450+
callable_methods.push_back(child_method);
462451
}
463452
}
464453

@@ -517,7 +506,7 @@ void ci_lazy_methodst::gather_field_types(
517506
if(element_type.id() == ID_pointer)
518507
{
519508
// This is a reference array -- mark its element type available.
520-
initialize_all_needed_classes_from_pointer(
509+
initialize_all_instantiated_classes_from_pointer(
521510
to_pointer_type(element_type), ns, needed_lazy_methods);
522511
}
523512
}
@@ -532,7 +521,7 @@ void ci_lazy_methodst::gather_field_types(
532521
{
533522
if(field.type().subtype().id() == ID_symbol)
534523
{
535-
initialize_all_needed_classes_from_pointer(
524+
initialize_all_instantiated_classes_from_pointer(
536525
to_pointer_type(field.type()), ns, needed_lazy_methods);
537526
}
538527
else
@@ -553,24 +542,24 @@ void ci_lazy_methodst::gather_field_types(
553542

554543
/// Find a virtual callee, if one is defined and the callee type is known to
555544
/// exist.
556-
/// \param needed_classes: set of classes that can be instantiated.
545+
/// \param instantiated_classes: set of classes that can be instantiated.
557546
/// Any potential callee not in this set will be ignored.
558547
/// \param call_basename: unqualified function name with type signature (e.g.
559548
/// "f:(I)")
560549
/// \param classname: class name that may define or override a function named
561550
/// `call_basename`.
562551
/// \param symbol_table: global symtab
563552
/// \return Returns the fully qualified name of `classname`'s definition of
564-
/// `call_basename` if found and `classname` is present in `needed_classes`,
565-
/// or irep_idt() otherwise.
553+
/// `call_basename` if found and `classname` is present in
554+
/// `instantiated_classes`, or irep_idt() otherwise.
566555
irep_idt ci_lazy_methodst::get_virtual_method_target(
567-
const std::set<irep_idt> &needed_classes,
556+
const std::set<irep_idt> &instantiated_classes,
568557
const irep_idt &call_basename,
569558
const irep_idt &classname,
570559
const symbol_tablet &symbol_table)
571560
{
572561
// Program-wide, is this class ever instantiated?
573-
if(!needed_classes.count(classname))
562+
if(!instantiated_classes.count(classname))
574563
return irep_idt();
575564

576565
resolve_inherited_componentt call_resolver(symbol_table, class_hierarchy);

src/java_bytecode/ci_lazy_methods.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class ci_lazy_methodst:public messaget
9898
const std::vector<irep_idt> &main_jar_classes,
9999
const std::vector<irep_idt> &lazy_methods_extra_entry_points,
100100
java_class_loadert &java_class_loader,
101-
const std::vector<irep_idt> &extra_needed_classes,
101+
const std::vector<irep_idt> &extra_instantiated_classes,
102102
const select_pointer_typet &pointer_type_selector,
103103
message_handlert &message_handler,
104104
const synthetic_methods_mapt &synthetic_methods);
@@ -114,17 +114,17 @@ class ci_lazy_methodst:public messaget
114114
std::vector<irep_idt> &methods,
115115
const symbol_tablet &symbol_table);
116116

117-
void initialize_needed_classes(
117+
void initialize_instantiated_classes(
118118
const std::vector<irep_idt> &entry_points,
119119
const namespacet &ns,
120120
ci_lazy_methods_neededt &needed_lazy_methods);
121121

122-
void initialize_all_needed_classes_from_pointer(
122+
void initialize_all_instantiated_classes_from_pointer(
123123
const pointer_typet &pointer_type,
124124
const namespacet &ns,
125125
ci_lazy_methods_neededt &needed_lazy_methods);
126126

127-
void initialize_needed_classes_from_pointer(
127+
void initialize_instantiated_classes_from_pointer(
128128
const pointer_typet &pointer_type,
129129
const namespacet &ns,
130130
ci_lazy_methods_neededt &needed_lazy_methods);
@@ -135,8 +135,8 @@ class ci_lazy_methodst:public messaget
135135

136136
void get_virtual_method_targets(
137137
const code_function_callt &c,
138-
const std::set<irep_idt> &needed_classes,
139-
std::vector<irep_idt> &needed_methods,
138+
const std::set<irep_idt> &instantiated_classes,
139+
std::vector<irep_idt> &callable_methods,
140140
symbol_tablet &symbol_table);
141141

142142
void gather_needed_globals(
@@ -150,7 +150,7 @@ class ci_lazy_methodst:public messaget
150150
ci_lazy_methods_neededt &needed_lazy_methods);
151151

152152
irep_idt get_virtual_method_target(
153-
const std::set<irep_idt> &needed_classes,
153+
const std::set<irep_idt> &instantiated_classes,
154154
const irep_idt &call_basename,
155155
const irep_idt &classname,
156156
const symbol_tablet &symbol_table);
@@ -164,7 +164,7 @@ class ci_lazy_methodst:public messaget
164164
std::vector<irep_idt> main_jar_classes;
165165
std::vector<irep_idt> lazy_methods_extra_entry_points;
166166
java_class_loadert &java_class_loader;
167-
const std::vector<irep_idt> &extra_needed_classes;
167+
const std::vector<irep_idt> &extra_instantiated_classes;
168168
const select_pointer_typet &pointer_type_selector;
169169
const synthetic_methods_mapt &synthetic_methods;
170170
};

src/java_bytecode/ci_lazy_methods_needed.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Author: Chris Smowton, [email protected]
2020
void ci_lazy_methods_neededt::add_needed_method(
2121
const irep_idt &method_symbol_name)
2222
{
23-
needed_methods.push_back(method_symbol_name);
23+
callable_methods.push_back(method_symbol_name);
2424
}
2525

2626
/// Notes class `class_symbol_name` will be instantiated, or a static field
@@ -32,7 +32,7 @@ void ci_lazy_methods_neededt::add_needed_method(
3232
bool ci_lazy_methods_neededt::add_needed_class(
3333
const irep_idt &class_symbol_name)
3434
{
35-
if(!needed_classes.insert(class_symbol_name).second)
35+
if(!instantiated_classes.insert(class_symbol_name).second)
3636
return false;
3737

3838
const std::string &class_name_string = id2string(class_symbol_name);

0 commit comments

Comments
 (0)