Skip to content

Commit 30bc2b6

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 67a02e6 commit 30bc2b6

File tree

3 files changed

+75
-15
lines changed

3 files changed

+75
-15
lines changed

jbmc/src/java_bytecode/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,10 +674,11 @@ determine which loading strategy to use.
674674
If [lazy_methods_mode](\ref java_bytecode_languaget::lazy_methods_mode) is
675675
\ref java_bytecode_languaget::LAZY_METHODS_MODE_EAGER then eager loading is
676676
used. Under eager loading
677-
\ref java_bytecode_languaget::convert_single_method(const irep_idt &, symbol_table_baset &)
677+
\ref java_bytecode_languaget::convert_single_method(const irep_idt &, symbol_table_baset &, lazy_class_to_declared_symbols_mapt &)
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: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,23 @@ static prefix_filtert get_context(const optionst &options)
115115
return prefix_filtert(std::move(context_include), std::move(context_exclude));
116116
}
117117

118+
std::unordered_multimap<irep_idt, symbolt> &
119+
lazy_class_to_declared_symbols_mapt::get(const symbol_tablet &symbol_table)
120+
{
121+
if(!initialized)
122+
{
123+
map = class_to_declared_symbols(symbol_table);
124+
initialized = true;
125+
}
126+
return map;
127+
}
128+
129+
void lazy_class_to_declared_symbols_mapt::reinitialize()
130+
{
131+
initialized = false;
132+
map.clear();
133+
}
134+
118135
/// Consume options that are java bytecode specific.
119136
void java_bytecode_languaget::set_language_options(const optionst &options)
120137
{
@@ -874,6 +891,8 @@ bool java_bytecode_languaget::typecheck(
874891
threading_support,
875892
static_values_json.has_value());
876893

894+
lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
895+
877896
// Now incrementally elaborate methods
878897
// that are reachable from this entry point.
879898
switch(lazy_methods_mode)
@@ -895,18 +914,21 @@ bool java_bytecode_languaget::typecheck(
895914
for(const auto &function_id_and_type : synthetic_methods)
896915
{
897916
convert_single_method(
898-
function_id_and_type.first, journalling_symbol_table);
917+
function_id_and_type.first,
918+
journalling_symbol_table,
919+
class_to_declared_symbols);
899920
}
900921
// Convert all methods for which we have bytecode now
901922
for(const auto &method_sig : method_bytecode)
902923
{
903-
convert_single_method(method_sig.first, journalling_symbol_table);
924+
convert_single_method(
925+
method_sig.first, journalling_symbol_table, class_to_declared_symbols);
904926
}
905927
// Now convert all newly added string methods
906928
for(const auto &fn_name : journalling_symbol_table.get_inserted())
907929
{
908930
if(string_preprocess.implements_function(fn_name))
909-
convert_single_method(fn_name, symbol_table);
931+
convert_single_method(fn_name, symbol_table, class_to_declared_symbols);
910932
}
911933
}
912934
break;
@@ -1001,12 +1023,17 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
10011023
symbol_table_buildert symbol_table_builder =
10021024
symbol_table_buildert::wrap(symbol_table);
10031025

1026+
lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
1027+
10041028
const method_convertert method_converter =
1005-
[this, &symbol_table_builder](
1029+
[this, &symbol_table_builder, &class_to_declared_symbols](
10061030
const irep_idt &function_id,
10071031
ci_lazy_methods_neededt lazy_methods_needed) {
10081032
return convert_single_method(
1009-
function_id, symbol_table_builder, std::move(lazy_methods_needed));
1033+
function_id,
1034+
symbol_table_builder,
1035+
std::move(lazy_methods_needed),
1036+
class_to_declared_symbols);
10101037
};
10111038

10121039
ci_lazy_methodst method_gather(
@@ -1069,7 +1096,8 @@ void java_bytecode_languaget::convert_lazy_method(
10691096
journalling_symbol_tablet symbol_table=
10701097
journalling_symbol_tablet::wrap(symtab);
10711098

1072-
convert_single_method(function_id, symbol_table);
1099+
lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
1100+
convert_single_method(function_id, symbol_table, class_to_declared_symbols);
10731101

10741102
// Instrument runtime exceptions (unless symbol is a stub)
10751103
if(symbol.value.is_not_nil())
@@ -1137,10 +1165,13 @@ static void notify_static_method_calls(
11371165
/// \param symbol_table: global symbol table
11381166
/// \param needed_lazy_methods: optionally a collection of needed methods to
11391167
/// update with any methods touched during the conversion
1168+
/// \param class_to_declared_symbols: maps classes to the symbols that
1169+
/// they declare.
11401170
bool java_bytecode_languaget::convert_single_method(
11411171
const irep_idt &function_id,
11421172
symbol_table_baset &symbol_table,
1143-
optionalt<ci_lazy_methods_neededt> needed_lazy_methods)
1173+
optionalt<ci_lazy_methods_neededt> needed_lazy_methods,
1174+
lazy_class_to_declared_symbols_mapt &class_to_declared_symbols)
11441175
{
11451176
// Do not convert if method is not in context
11461177
if(method_in_context && !(*method_in_context)(id2string(function_id)))
@@ -1218,16 +1249,14 @@ bool java_bytecode_languaget::convert_single_method(
12181249
class_name, "user_specified_clinit must be declared by a class.");
12191250
INVARIANT(
12201251
static_values_json.has_value(), "static-values JSON must be available");
1221-
const auto class_to_declared_symbols_map =
1222-
class_to_declared_symbols(symbol_table);
12231252
writable_symbol.value = get_user_specified_clinit_body(
12241253
*class_name,
12251254
*static_values_json,
12261255
symbol_table,
12271256
needed_lazy_methods,
12281257
max_user_array_length,
12291258
references,
1230-
class_to_declared_symbols_map);
1259+
class_to_declared_symbols.get(symbol_table));
12311260
break;
12321261
}
12331262
case synthetic_method_typet::STUB_CLASS_STATIC_INITIALIZER:

jbmc/src/java_bytecode/java_bytecode_language.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,31 @@ enum lazy_methods_modet
121121
LAZY_METHODS_MODE_EXTERNAL_DRIVER
122122
};
123123

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

126151
class java_bytecode_languaget:public languaget
@@ -205,15 +230,20 @@ class java_bytecode_languaget:public languaget
205230
protected:
206231
void convert_single_method(
207232
const irep_idt &function_id,
208-
symbol_table_baset &symbol_table)
233+
symbol_table_baset &symbol_table,
234+
lazy_class_to_declared_symbols_mapt &class_to_declared_symbols)
209235
{
210236
convert_single_method(
211-
function_id, symbol_table, optionalt<ci_lazy_methods_neededt>());
237+
function_id,
238+
symbol_table,
239+
optionalt<ci_lazy_methods_neededt>(),
240+
class_to_declared_symbols);
212241
}
213242
bool convert_single_method(
214243
const irep_idt &function_id,
215244
symbol_table_baset &symbol_table,
216-
optionalt<ci_lazy_methods_neededt> needed_lazy_methods);
245+
optionalt<ci_lazy_methods_neededt> needed_lazy_methods,
246+
lazy_class_to_declared_symbols_mapt &class_to_declared_symbols);
217247

218248
bool do_ci_lazy_method_conversion(symbol_tablet &);
219249
const select_pointer_typet &get_pointer_type_selector() const;

0 commit comments

Comments
 (0)