Skip to content

Commit dac3e16

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 dac3e16

File tree

3 files changed

+76
-14
lines changed

3 files changed

+76
-14
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: 41 additions & 10 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
{
@@ -868,6 +885,8 @@ bool java_bytecode_languaget::typecheck(
868885
threading_support,
869886
static_values_json.has_value());
870887

888+
lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
889+
871890
// Now incrementally elaborate methods
872891
// that are reachable from this entry point.
873892
switch(lazy_methods_mode)
@@ -889,18 +908,23 @@ bool java_bytecode_languaget::typecheck(
889908
for(const auto &function_id_and_type : synthetic_methods)
890909
{
891910
convert_single_method(
892-
function_id_and_type.first, journalling_symbol_table);
911+
function_id_and_type.first,
912+
journalling_symbol_table,
913+
class_to_declared_symbols);
893914
}
894915
// Convert all methods for which we have bytecode now
895916
for(const auto &method_sig : method_bytecode)
896917
{
897-
convert_single_method(method_sig.first, journalling_symbol_table);
918+
convert_single_method(
919+
method_sig.first,
920+
journalling_symbol_table,
921+
class_to_declared_symbols);
898922
}
899923
// Now convert all newly added string methods
900924
for(const auto &fn_name : journalling_symbol_table.get_inserted())
901925
{
902926
if(string_preprocess.implements_function(fn_name))
903-
convert_single_method(fn_name, symbol_table);
927+
convert_single_method(fn_name, symbol_table, class_to_declared_symbols);
904928
}
905929
}
906930
break;
@@ -995,12 +1019,17 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
9951019
symbol_table_buildert symbol_table_builder =
9961020
symbol_table_buildert::wrap(symbol_table);
9971021

1022+
lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
1023+
9981024
const method_convertert method_converter =
999-
[this, &symbol_table_builder](
1025+
[this, &symbol_table_builder, &class_to_declared_symbols](
10001026
const irep_idt &function_id,
10011027
ci_lazy_methods_neededt lazy_methods_needed) {
10021028
return convert_single_method(
1003-
function_id, symbol_table_builder, std::move(lazy_methods_needed));
1029+
function_id,
1030+
symbol_table_builder,
1031+
std::move(lazy_methods_needed),
1032+
class_to_declared_symbols);
10041033
};
10051034

10061035
ci_lazy_methodst method_gather(
@@ -1063,7 +1092,8 @@ void java_bytecode_languaget::convert_lazy_method(
10631092
journalling_symbol_tablet symbol_table=
10641093
journalling_symbol_tablet::wrap(symtab);
10651094

1066-
convert_single_method(function_id, symbol_table);
1095+
lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
1096+
convert_single_method(function_id, symbol_table, class_to_declared_symbols);
10671097

10681098
// Instrument runtime exceptions (unless symbol is a stub)
10691099
if(symbol.value.is_not_nil())
@@ -1131,10 +1161,13 @@ static void notify_static_method_calls(
11311161
/// \param symbol_table: global symbol table
11321162
/// \param needed_lazy_methods: optionally a collection of needed methods to
11331163
/// update with any methods touched during the conversion
1164+
/// \param class_to_declared_symbols: maps classes to the symbols that
1165+
/// they declare.
11341166
bool java_bytecode_languaget::convert_single_method(
11351167
const irep_idt &function_id,
11361168
symbol_table_baset &symbol_table,
1137-
optionalt<ci_lazy_methods_neededt> needed_lazy_methods)
1169+
optionalt<ci_lazy_methods_neededt> needed_lazy_methods,
1170+
lazy_class_to_declared_symbols_mapt &class_to_declared_symbols)
11381171
{
11391172
// Do not convert if method is not in context
11401173
if(method_in_context && !(*method_in_context)(id2string(function_id)))
@@ -1212,16 +1245,14 @@ bool java_bytecode_languaget::convert_single_method(
12121245
class_name, "user_specified_clinit must be declared by a class.");
12131246
INVARIANT(
12141247
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);
12171248
writable_symbol.value = get_user_specified_clinit_body(
12181249
*class_name,
12191250
*static_values_json,
12201251
symbol_table,
12211252
needed_lazy_methods,
12221253
max_user_array_length,
12231254
references,
1224-
class_to_declared_symbols_map);
1255+
class_to_declared_symbols.get(symbol_table));
12251256
break;
12261257
}
12271258
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
@@ -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
@@ -199,15 +224,20 @@ class java_bytecode_languaget:public languaget
199224
protected:
200225
void convert_single_method(
201226
const irep_idt &function_id,
202-
symbol_table_baset &symbol_table)
227+
symbol_table_baset &symbol_table,
228+
lazy_class_to_declared_symbols_mapt &class_to_declared_symbols)
203229
{
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)