Skip to content

Commit 5450149

Browse files
Declare a lazy_class_to_declared_symbols_mapt class
This is to avoid computing the map several times and make sure it is never computed if it is not actually needed.
1 parent 2381ce4 commit 5450149

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

jbmc/src/java_bytecode/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,8 @@ used. Under eager loading
677677
\ref java_bytecode_languaget::convert_single_method(const irep_idt &, symbol_table_baset &)
678678
is called once for each method listed in method_bytecode (described above). This
679679
then calls
680-
\ref java_bytecode_languaget::convert_single_method(const irep_idt &, symbol_table_baset &, optionalt<ci_lazy_methods_neededt>)
680+
\ref java_bytecode_languaget::convert_single_method(const irep_idt &, symbol_table_baset &, optionalt<ci_lazy_methods_neededt>, lazy_class_to_declared_symbols_mapt &);
681+
681682
without a ci_lazy_methods_neededt object, which calls
682683
\ref java_bytecode_convert_method, passing in the method parse tree. This in
683684
turn uses \ref java_bytecode_convert_methodt to turn the bytecode into symbols

jbmc/src/java_bytecode/java_bytecode_language.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,23 @@ static prefix_filtert get_context(const optionst &options)
112112
return prefix_filtert(std::move(context_include), std::move(context_exclude));
113113
}
114114

115+
std::unordered_multimap<irep_idt, symbolt> &
116+
lazy_class_to_declared_symbols_mapt::get(const symbol_tablet &symbol_table)
117+
{
118+
if(!initialized)
119+
{
120+
map = class_to_declared_symbols(symbol_table);
121+
initialized = true;
122+
}
123+
return map;
124+
}
125+
126+
void lazy_class_to_declared_symbols_mapt::reinitialize()
127+
{
128+
initialized = false;
129+
map.clear();
130+
}
131+
115132
/// Consume options that are java bytecode specific.
116133
void java_bytecode_languaget::set_language_options(const optionst &options)
117134
{
@@ -995,12 +1012,17 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
9951012
symbol_table_buildert symbol_table_builder =
9961013
symbol_table_buildert::wrap(symbol_table);
9971014

1015+
lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
1016+
9981017
const method_convertert method_converter =
999-
[this, &symbol_table_builder](
1018+
[this, &symbol_table_builder, &class_to_declared_symbols](
10001019
const irep_idt &function_id,
10011020
ci_lazy_methods_neededt lazy_methods_needed) {
10021021
return convert_single_method(
1003-
function_id, symbol_table_builder, std::move(lazy_methods_needed));
1022+
function_id,
1023+
symbol_table_builder,
1024+
std::move(lazy_methods_needed),
1025+
class_to_declared_symbols);
10041026
};
10051027

10061028
ci_lazy_methodst method_gather(
@@ -1131,10 +1153,13 @@ static void notify_static_method_calls(
11311153
/// \param symbol_table: global symbol table
11321154
/// \param needed_lazy_methods: optionally a collection of needed methods to
11331155
/// update with any methods touched during the conversion
1156+
/// \param class_to_declared_symbols: maps classes to the symbols that
1157+
/// they declare.
11341158
bool java_bytecode_languaget::convert_single_method(
11351159
const irep_idt &function_id,
11361160
symbol_table_baset &symbol_table,
1137-
optionalt<ci_lazy_methods_neededt> needed_lazy_methods)
1161+
optionalt<ci_lazy_methods_neededt> needed_lazy_methods,
1162+
lazy_class_to_declared_symbols_mapt &class_to_declared_symbols)
11381163
{
11391164
// Do not convert if method is not in context
11401165
if(method_in_context && !(*method_in_context)(id2string(function_id)))
@@ -1212,16 +1237,14 @@ bool java_bytecode_languaget::convert_single_method(
12121237
class_name, "user_specified_clinit must be declared by a class.");
12131238
INVARIANT(
12141239
static_values_json.has_value(), "static-values JSON must be available");
1215-
const auto class_to_declared_symbols_map =
1216-
class_to_declared_symbols(symbol_table);
12171240
writable_symbol.value = get_user_specified_clinit_body(
12181241
*class_name,
12191242
*static_values_json,
12201243
symbol_table,
12211244
needed_lazy_methods,
12221245
max_user_array_length,
12231246
references,
1224-
class_to_declared_symbols_map);
1247+
class_to_declared_symbols.get(symbol_table));
12251248
break;
12261249
}
12271250
case synthetic_method_typet::STUB_CLASS_STATIC_INITIALIZER:

jbmc/src/java_bytecode/java_bytecode_language.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,31 @@ enum lazy_methods_modet
115115
LAZY_METHODS_MODE_EXTERNAL_DRIVER
116116
};
117117

118+
/// Map classes to the symbols they declare but is only computed once it is
119+
/// needed and the map is then kept.
120+
/// Note that it only includes function and field symbols (and not for example,
121+
/// local variables), these are produced in the convert-class phase.
122+
/// Calling `get` before the symbol table is properly filled with these symbols,
123+
/// would make later calls return an outdated map. The
124+
/// lazy_class_to_declared_symbols_mapt would then need to be reinitialized.
125+
/// Similarly if some transformation creates or deletes function or field
126+
/// symbols in the symbol table, then the map would get out of date and would
127+
/// need to be reinitialized.
128+
class lazy_class_to_declared_symbols_mapt
129+
{
130+
public:
131+
lazy_class_to_declared_symbols_mapt() = default;
132+
133+
std::unordered_multimap<irep_idt, symbolt> &
134+
get(const symbol_tablet &symbol_table);
135+
136+
void reinitialize();
137+
138+
private:
139+
bool initialized = false;
140+
std::unordered_multimap<irep_idt, symbolt> map;
141+
};
142+
118143
#define JAVA_CLASS_MODEL_SUFFIX "@class_model"
119144

120145
class java_bytecode_languaget:public languaget
@@ -201,13 +226,18 @@ class java_bytecode_languaget:public languaget
201226
const irep_idt &function_id,
202227
symbol_table_baset &symbol_table)
203228
{
229+
lazy_class_to_declared_symbols_mapt class_to_declared_symbols{};
204230
convert_single_method(
205-
function_id, symbol_table, optionalt<ci_lazy_methods_neededt>());
231+
function_id,
232+
symbol_table,
233+
optionalt<ci_lazy_methods_neededt>(),
234+
class_to_declared_symbols);
206235
}
207236
bool convert_single_method(
208237
const irep_idt &function_id,
209238
symbol_table_baset &symbol_table,
210-
optionalt<ci_lazy_methods_neededt> needed_lazy_methods);
239+
optionalt<ci_lazy_methods_neededt> needed_lazy_methods,
240+
lazy_class_to_declared_symbols_mapt &class_to_declared_symbols);
211241

212242
bool do_ci_lazy_method_conversion(symbol_tablet &);
213243
const select_pointer_typet &get_pointer_type_selector() const;

0 commit comments

Comments
 (0)