Skip to content

Commit 3709f42

Browse files
author
Matthias Güdemann
committed
Add force loading parameter --java-load-class-list
This parameter force loads the specified classes and prevents their methods from being removed by lazy-methods. This allows to add classes that provide an implementations for interfaces, where the classes themselves are not referenced.
1 parent dd7ebd3 commit 3709f42

File tree

6 files changed

+43
-1
lines changed

6 files changed

+43
-1
lines changed

src/java_bytecode/ci_lazy_methods.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ ci_lazy_methodst::ci_lazy_methodst(
2424
const std::vector<irep_idt> &main_jar_classes,
2525
const std::vector<irep_idt> &lazy_methods_extra_entry_points,
2626
java_class_loadert &java_class_loader,
27+
const std::vector<irep_idt> &java_load_classes,
2728
const select_pointer_typet &pointer_type_selector,
2829
message_handlert &message_handler):
2930
messaget(message_handler),
3031
main_class(main_class),
3132
main_jar_classes(main_jar_classes),
3233
lazy_methods_extra_entry_points(lazy_methods_extra_entry_points),
3334
java_class_loader(java_class_loader),
35+
java_load_classes(java_load_classes),
3436
pointer_type_selector(pointer_type_selector)
3537
{
3638
// build the class hierarchy
@@ -279,6 +281,14 @@ void ci_lazy_methodst::initialize_needed_classes(
279281
lazy_methods.add_needed_class("java::java.lang.String");
280282
lazy_methods.add_needed_class("java::java.lang.Class");
281283
lazy_methods.add_needed_class("java::java.lang.Object");
284+
285+
// As in class_loader, ensure these classes stay available
286+
std::for_each(
287+
java_load_classes.begin(),
288+
java_load_classes.end(),
289+
[&](const irep_idt &id) {
290+
lazy_methods.add_needed_class("java::" + id2string(id));
291+
});
282292
}
283293

284294
/// Build up list of methods for types for a pointer and any types it

src/java_bytecode/ci_lazy_methods.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class ci_lazy_methodst:public messaget
4848
const std::vector<irep_idt> &main_jar_classes,
4949
const std::vector<irep_idt> &lazy_methods_extra_entry_points,
5050
java_class_loadert &java_class_loader,
51+
const std::vector<irep_idt> &java_load_classes,
5152
const select_pointer_typet &pointer_type_selector,
5253
message_handlert &message_handler);
5354

@@ -111,6 +112,7 @@ class ci_lazy_methodst:public messaget
111112
std::vector<irep_idt> main_jar_classes;
112113
std::vector<irep_idt> lazy_methods_extra_entry_points;
113114
java_class_loadert &java_class_loader;
115+
const std::vector<irep_idt> &java_load_classes;
114116
const select_pointer_typet &pointer_type_selector;
115117
};
116118

src/java_bytecode/java_bytecode_language.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ void java_bytecode_languaget::get_language_options(const cmdlinet &cmd)
6161
else
6262
lazy_methods_mode=LAZY_METHODS_MODE_EAGER;
6363

64+
if(cmd.isset("java-load-class-list"))
65+
{
66+
for(const auto &c : cmd.get_values("java-load-class-list"))
67+
java_load_classes.push_back(c);
68+
}
69+
6470
const std::list<std::string> &extra_entry_points=
6571
cmd.get_values("lazy-methods-extra-entry-point");
6672
lazy_methods_extra_entry_points.insert(
@@ -128,6 +134,7 @@ bool java_bytecode_languaget::parse(
128134
PRECONDITION(language_options_initialized);
129135
java_class_loader.set_message_handler(get_message_handler());
130136
java_class_loader.set_java_cp_include_files(java_cp_include_files);
137+
java_class_loader.add_load_classes(java_load_classes);
131138

132139
// look at extension
133140
if(has_suffix(path, ".class"))
@@ -323,6 +330,7 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
323330
main_jar_classes,
324331
lazy_methods_extra_entry_points,
325332
java_class_loader,
333+
java_load_classes,
326334
get_pointer_type_selector(),
327335
get_message_handler());
328336

src/java_bytecode/java_bytecode_language.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ Author: Daniel Kroening, [email protected]
2929
"(java-max-vla-length):" \
3030
"(java-cp-include-files):" \
3131
"(lazy-methods)" \
32-
"(lazy-methods-extra-entry-point):"
32+
"(lazy-methods-extra-entry-point):" \
33+
"(java-load-class-list):"
3334

3435
#define JAVA_BYTECODE_LANGUAGE_OPTIONS_HELP /*NOLINT*/ \
3536
" --java-assume-inputs-non-null never initialize reference-typed parameter to the\n" \
@@ -177,6 +178,9 @@ class java_bytecode_languaget:public languaget
177178
java_string_library_preprocesst string_preprocess;
178179
std::string java_cp_include_files;
179180

181+
// list of classes to force load even without reference from the entry point
182+
std::vector<irep_idt> java_load_classes;
183+
180184
private:
181185
const std::unique_ptr<const select_pointer_typet> pointer_type_selector;
182186
};

src/java_bytecode/java_class_loader.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ java_bytecode_parse_treet &java_class_loadert::operator()(
3636
queue.push("java.lang.Throwable");
3737
queue.push(class_name);
3838

39+
// Require often used library classes that implement widely used interfaces
40+
std::for_each(
41+
java_load_classes.begin(),
42+
java_load_classes.end(),
43+
[&](const irep_idt &id) { queue.push(id); });
44+
3945
java_class_loader_limitt class_loader_limit(
4046
get_message_handler(), java_cp_include_files);
4147

@@ -278,3 +284,13 @@ jar_filet &java_class_loadert::jar_pool(
278284
else
279285
return it->second;
280286
}
287+
288+
/// Adds the list of classes to the load queue, forcing them to be loaded even
289+
/// without explicit reference
290+
/// \param classes: list of class identifiers
291+
void java_class_loadert::add_load_classes(std::vector<irep_idt> &classes)
292+
{
293+
std::for_each(classes.begin(), classes.end(), [&](const irep_idt &id) {
294+
java_load_classes.push_back(id);
295+
});
296+
}

src/java_bytecode/java_class_loader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class java_class_loadert:public messaget
2626
java_bytecode_parse_treet &operator()(const irep_idt &);
2727

2828
void set_java_cp_include_files(std::string &);
29+
void add_load_classes(std::vector<irep_idt> &);
2930

3031
static std::string file_to_class_name(const std::string &);
3132
static std::string class_name_to_file(const irep_idt &);
@@ -94,6 +95,7 @@ class java_class_loadert:public messaget
9495
std::string java_cp_include_files;
9596
private:
9697
std::map<std::string, jar_filet> m_archives;
98+
std::vector<irep_idt> java_load_classes;
9799
};
98100

99101
#endif // CPROVER_JAVA_BYTECODE_JAVA_CLASS_LOADER_H

0 commit comments

Comments
 (0)