Skip to content

Commit ed7f7ec

Browse files
author
thk123
committed
Move method for gathering all instantiated types into ci_lazy_methods_needed
1 parent 0c5d6ea commit ed7f7ec

File tree

4 files changed

+135
-148
lines changed

4 files changed

+135
-148
lines changed

jbmc/src/java_bytecode/ci_lazy_methods.cpp

Lines changed: 3 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ bool ci_lazy_methodst::operator()(
113113
{
114114
std::unordered_set<irep_idt> initial_callable_methods;
115115
ci_lazy_methods_neededt initial_lazy_methods(
116-
initial_callable_methods, instantiated_classes, symbol_table);
116+
initial_callable_methods, instantiated_classes, symbol_table, pointer_type_selector);
117117
initialize_instantiated_classes(
118118
methods_to_convert_later, namespacet(symbol_table), initial_lazy_methods);
119119
methods_to_convert_later.insert(
@@ -278,7 +278,7 @@ ci_lazy_methodst::convert_and_analyze_method(
278278
// Note this wraps *references* to methods_to_convert_later &
279279
// instantiated_classes
280280
ci_lazy_methods_neededt needed_methods(
281-
methods_to_convert_later, instantiated_classes, symbol_table);
281+
methods_to_convert_later, instantiated_classes, symbol_table, pointer_type_selector);
282282

283283
const bool could_not_convert_function =
284284
method_converter(mname, needed_methods);
@@ -410,8 +410,7 @@ void ci_lazy_methodst::initialize_instantiated_classes(
410410
if(param.type().id()==ID_pointer)
411411
{
412412
const pointer_typet &original_pointer=to_pointer_type(param.type());
413-
initialize_all_instantiated_classes_from_pointer(
414-
original_pointer, ns, needed_lazy_methods);
413+
needed_lazy_methods.add_all_needed_classes(original_pointer);
415414
}
416415
}
417416
}
@@ -428,75 +427,6 @@ void ci_lazy_methodst::initialize_instantiated_classes(
428427
needed_lazy_methods.add_needed_class("java::" + id2string(id));
429428
}
430429

431-
/// Build up list of methods for types for a pointer and any types it
432-
/// might be subsituted for. See
433-
/// `initialize_instantiated_classes` for more details.
434-
/// \param pointer_type: The type to gather methods for.
435-
/// \param ns: global namespace
436-
/// \param [out] needed_lazy_methods: Populated with all Java reference types
437-
/// whose references may be passed, directly or indirectly, to any of the
438-
/// functions in `entry_points`
439-
void ci_lazy_methodst::initialize_all_instantiated_classes_from_pointer(
440-
const pointer_typet &pointer_type,
441-
const namespacet &ns,
442-
ci_lazy_methods_neededt &needed_lazy_methods)
443-
{
444-
initialize_instantiated_classes_from_pointer(
445-
pointer_type,
446-
ns,
447-
needed_lazy_methods);
448-
449-
// TODO we should be passing here a map that maps generic parameters
450-
// to concrete types in the current context TG-2664
451-
const pointer_typet &subbed_pointer_type =
452-
pointer_type_selector.convert_pointer_type(pointer_type, {}, ns);
453-
454-
if(subbed_pointer_type!=pointer_type)
455-
{
456-
initialize_instantiated_classes_from_pointer(
457-
subbed_pointer_type, ns, needed_lazy_methods);
458-
}
459-
}
460-
461-
/// Build up list of methods for types for a specific pointer type. See
462-
/// `initialize_instantiated_classes` for more details.
463-
/// \param pointer_type: The type to gather methods for.
464-
/// \param ns: global namespace
465-
/// \param [out] needed_lazy_methods: Populated with all Java reference types
466-
/// whose references may be passed, directly or indirectly, to any of the
467-
/// functions in `entry_points`
468-
void ci_lazy_methodst::initialize_instantiated_classes_from_pointer(
469-
const pointer_typet &pointer_type,
470-
const namespacet &ns,
471-
ci_lazy_methods_neededt &needed_lazy_methods)
472-
{
473-
const symbol_typet &class_type=to_symbol_type(pointer_type.subtype());
474-
const auto &param_classid=class_type.get_identifier();
475-
476-
// Note here: different arrays may have different element types, so we should
477-
// explore again even if we've seen this classid before in the array case.
478-
if(needed_lazy_methods.add_needed_class(param_classid) ||
479-
is_java_array_tag(param_classid))
480-
{
481-
gather_field_types(pointer_type.subtype(), ns, needed_lazy_methods);
482-
}
483-
484-
if(is_java_generic_type(pointer_type))
485-
{
486-
// Assume if this is a generic like X<A, B, C>, then any concrete parameters
487-
// will at some point be instantiated.
488-
const auto &generic_args =
489-
to_java_generic_type(pointer_type).generic_type_arguments();
490-
for(const auto &generic_arg : generic_args)
491-
{
492-
if(!is_java_generic_parameter(generic_arg))
493-
{
494-
initialize_instantiated_classes_from_pointer(
495-
generic_arg, ns, needed_lazy_methods);
496-
}
497-
}
498-
}
499-
}
500430

501431
/// Get places where virtual functions are called.
502432
/// \param e: expression tree to search
@@ -591,64 +521,6 @@ void ci_lazy_methodst::gather_needed_globals(
591521
gather_needed_globals(*opit, symbol_table, needed);
592522
}
593523

594-
/// See param needed_lazy_methods
595-
/// \param class_type: root of class tree to search
596-
/// \param ns: global namespace
597-
/// \param [out] needed_lazy_methods: Popualted with all Java reference types
598-
/// reachable starting at `class_type`. For example if `class_type` is
599-
/// `symbol_typet("java::A")` and A has a B field, then `B` (but not `A`) will
600-
/// noted as a needed class.
601-
void ci_lazy_methodst::gather_field_types(
602-
const typet &class_type,
603-
const namespacet &ns,
604-
ci_lazy_methods_neededt &needed_lazy_methods)
605-
{
606-
const auto &underlying_type=to_struct_type(ns.follow(class_type));
607-
if(is_java_array_tag(underlying_type.get_tag()))
608-
{
609-
// If class_type is not a symbol this may be a reference array,
610-
// but we can't tell what type.
611-
if(class_type.id() == ID_symbol)
612-
{
613-
const typet &element_type =
614-
java_array_element_type(to_symbol_type(class_type));
615-
if(element_type.id() == ID_pointer)
616-
{
617-
// This is a reference array -- mark its element type available.
618-
initialize_all_instantiated_classes_from_pointer(
619-
to_pointer_type(element_type), ns, needed_lazy_methods);
620-
}
621-
}
622-
}
623-
else
624-
{
625-
for(const auto &field : underlying_type.components())
626-
{
627-
if(field.type().id() == ID_struct || field.type().id() == ID_symbol)
628-
gather_field_types(field.type(), ns, needed_lazy_methods);
629-
else if(field.type().id() == ID_pointer)
630-
{
631-
if(field.type().subtype().id() == ID_symbol)
632-
{
633-
initialize_all_instantiated_classes_from_pointer(
634-
to_pointer_type(field.type()), ns, needed_lazy_methods);
635-
}
636-
else
637-
{
638-
// If raw structs were possible this would lead to missed
639-
// dependencies, as both array element and specialised generic type
640-
// information cannot be obtained in this case.
641-
// We should therefore only be skipping pointers such as the uint16t*
642-
// in our internal String representation.
643-
INVARIANT(
644-
field.type().subtype().id() != ID_struct,
645-
"struct types should be referred to by symbol at this stage");
646-
}
647-
}
648-
}
649-
}
650-
}
651-
652524
/// Find a virtual callee, if one is defined and the callee type is known to
653525
/// exist.
654526
/// \param instantiated_classes: set of classes that can be instantiated.

jbmc/src/java_bytecode/ci_lazy_methods.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -121,16 +121,6 @@ class ci_lazy_methodst:public messaget
121121
const namespacet &ns,
122122
ci_lazy_methods_neededt &needed_lazy_methods);
123123

124-
void initialize_all_instantiated_classes_from_pointer(
125-
const pointer_typet &pointer_type,
126-
const namespacet &ns,
127-
ci_lazy_methods_neededt &needed_lazy_methods);
128-
129-
void initialize_instantiated_classes_from_pointer(
130-
const pointer_typet &pointer_type,
131-
const namespacet &ns,
132-
ci_lazy_methods_neededt &needed_lazy_methods);
133-
134124
void gather_virtual_callsites(
135125
const exprt &e,
136126
std::unordered_set<exprt, irep_hash> &result);
@@ -146,11 +136,6 @@ class ci_lazy_methodst:public messaget
146136
const symbol_tablet &symbol_table,
147137
symbol_tablet &needed);
148138

149-
void gather_field_types(
150-
const typet &class_type,
151-
const namespacet &ns,
152-
ci_lazy_methods_neededt &needed_lazy_methods);
153-
154139
irep_idt get_virtual_method_target(
155140
const std::unordered_set<irep_idt> &instantiated_classes,
156141
const irep_idt &call_basename,

jbmc/src/java_bytecode/ci_lazy_methods_needed.cpp

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ Author: Chris Smowton, [email protected]
1212
#include "ci_lazy_methods.h"
1313

1414
#include <string>
15+
#include <util/namespace.h>
16+
#include <util/std_types.h>
17+
#include <java_bytecode/select_pointer_type.h>
1518

1619
/// Notes `method_symbol_name` is referenced from some reachable function, and
1720
/// should therefore be elaborated.
@@ -41,3 +44,114 @@ bool ci_lazy_methods_neededt::add_needed_class(
4144

4245
return true;
4346
}
47+
48+
/// Add to the needed classes all class specified, the replacement type if it
49+
/// will be replaced, and all feilds it contains.
50+
/// \param pointer_type: The type to add
51+
void ci_lazy_methods_neededt::add_all_needed_classes(const pointer_typet &pointer_type)
52+
{
53+
namespacet ns{symbol_table};
54+
initialize_instantiated_classes_from_pointer(
55+
pointer_type,
56+
ns);
57+
58+
// TODO we should be passing here a map that maps generic parameters
59+
// to concrete types in the current context TG-2664
60+
const pointer_typet &subbed_pointer_type =
61+
pointer_type_selector.convert_pointer_type(pointer_type, {}, ns);
62+
63+
if(subbed_pointer_type!=pointer_type)
64+
{
65+
initialize_instantiated_classes_from_pointer(
66+
subbed_pointer_type, ns);
67+
}
68+
}
69+
70+
/// Build up list of methods for types for a specific pointer type. See
71+
/// `add_all_needed_classes` for more details.
72+
/// \param pointer_type: The type to gather methods for.
73+
/// \param ns: global namespace
74+
void ci_lazy_methods_neededt::initialize_instantiated_classes_from_pointer(
75+
const pointer_typet &pointer_type,
76+
const namespacet &ns)
77+
{
78+
const symbol_typet &class_type=to_symbol_type(pointer_type.subtype());
79+
const auto &param_classid=class_type.get_identifier();
80+
81+
// Note here: different arrays may have different element types, so we should
82+
// explore again even if we've seen this classid before in the array case.
83+
if(add_needed_class(param_classid) ||
84+
is_java_array_tag(param_classid))
85+
{
86+
gather_field_types(pointer_type.subtype(), ns);
87+
}
88+
89+
if(is_java_generic_type(pointer_type))
90+
{
91+
// Assume if this is a generic like X<A, B, C>, then any concrete parameters
92+
// will at some point be instantiated.
93+
const auto &generic_args =
94+
to_java_generic_type(pointer_type).generic_type_arguments();
95+
for(const auto &generic_arg : generic_args)
96+
{
97+
if(!is_java_generic_parameter(generic_arg))
98+
{
99+
initialize_instantiated_classes_from_pointer(
100+
generic_arg, ns);
101+
}
102+
}
103+
}
104+
}
105+
106+
/// For a given type, gather all fields referenced by that type
107+
/// \param class_type: root of class tree to search
108+
/// \param ns: global namespaces.
109+
void ci_lazy_methods_neededt::gather_field_types(
110+
const typet &class_type,
111+
const namespacet &ns)
112+
{
113+
const auto &underlying_type=to_struct_type(ns.follow(class_type));
114+
if(is_java_array_tag(underlying_type.get_tag()))
115+
{
116+
// If class_type is not a symbol this may be a reference array,
117+
// but we can't tell what type.
118+
if(class_type.id() == ID_symbol)
119+
{
120+
const typet &element_type =
121+
java_array_element_type(to_symbol_type(class_type));
122+
if(element_type.id() == ID_pointer)
123+
{
124+
// This is a reference array -- mark its element type available.
125+
add_all_needed_classes(
126+
to_pointer_type(element_type));
127+
}
128+
}
129+
}
130+
else
131+
{
132+
for(const auto &field : underlying_type.components())
133+
{
134+
if(field.type().id() == ID_struct || field.type().id() == ID_symbol)
135+
gather_field_types(field.type(), ns);
136+
else if(field.type().id() == ID_pointer)
137+
{
138+
if(field.type().subtype().id() == ID_symbol)
139+
{
140+
add_all_needed_classes(
141+
to_pointer_type(field.type()));
142+
}
143+
else
144+
{
145+
// If raw structs were possible this would lead to missed
146+
// dependencies, as both array element and specialised generic type
147+
// information cannot be obtained in this case.
148+
// We should therefore only be skipping pointers such as the uint16t*
149+
// in our internal String representation.
150+
INVARIANT(
151+
field.type().subtype().id() != ID_struct,
152+
"struct types should be referred to by symbol at this stage");
153+
}
154+
}
155+
}
156+
}
157+
}

jbmc/src/java_bytecode/ci_lazy_methods_needed.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,30 @@ Author: Chris Smowton, [email protected]
1717
#include <unordered_set>
1818
#include <util/symbol_table.h>
1919

20+
21+
class select_pointer_typet;
22+
class pointer_typet;
23+
2024
class ci_lazy_methods_neededt
2125
{
2226
public:
2327
ci_lazy_methods_neededt(
2428
std::unordered_set<irep_idt> &_callable_methods,
2529
std::unordered_set<irep_idt> &_instantiated_classes,
26-
symbol_tablet &_symbol_table)
30+
symbol_tablet &_symbol_table,
31+
const select_pointer_typet &pointer_type_selector)
2732
: callable_methods(_callable_methods),
2833
instantiated_classes(_instantiated_classes),
29-
symbol_table(_symbol_table)
34+
symbol_table(_symbol_table),
35+
pointer_type_selector(pointer_type_selector)
3036
{}
3137

3238
void add_needed_method(const irep_idt &);
3339
// Returns true if new
3440
bool add_needed_class(const irep_idt &);
3541

42+
void add_all_needed_classes(const pointer_typet &pointer_type);
43+
3644
private:
3745
// callable_methods is a vector because it's used as a work-list
3846
// which is periodically cleared. It can't be relied upon to
@@ -45,6 +53,14 @@ class ci_lazy_methods_neededt
4553
// repeatedly exploring a class hierarchy.
4654
std::unordered_set<irep_idt> &instantiated_classes;
4755
symbol_tablet &symbol_table;
56+
57+
const select_pointer_typet &pointer_type_selector;
58+
59+
void initialize_instantiated_classes_from_pointer(
60+
const pointer_typet &pointer_type,
61+
const namespacet &ns);
62+
63+
void gather_field_types(const typet &class_type, const namespacet &ns);
4864
};
4965

5066
#endif

0 commit comments

Comments
 (0)