Skip to content

Commit fabc99e

Browse files
author
Matthias Güdemann
authored
Merge pull request #1563 from NathanJPhillips/feature/lazy-loading
Lazy function loading
2 parents 2d67e42 + a2cf16d commit fabc99e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1128
-331
lines changed

regression/jbmc-strings/StaticCharMethods05/test.desc

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ StaticCharMethods05.class
33
--refine-strings --string-max-length 1000
44
^EXIT=10$
55
^SIGNAL=0$
6-
null-pointer-exception\.14\] Throw null: FAILURE
76
^\[.*assertion\.1\] .* line 12 .* FAILURE$
87
^\[.*assertion\.2\] .* line 22 .* FAILURE$
98
^VERIFICATION FAILED$

src/clobber/clobber_parse_options.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Author: Daniel Kroening, [email protected]
3232
#include <goto-programs/link_to_library.h>
3333
#include <goto-programs/goto_inline.h>
3434
#include <goto-programs/xml_goto_trace.h>
35+
#include <goto-programs/remove_java_new.h>
3536

3637
#include <goto-instrument/dump_c.h>
3738

@@ -207,6 +208,8 @@ bool clobber_parse_optionst::process_goto_program(
207208
goto_modelt &goto_model)
208209
{
209210
{
211+
remove_java_new(goto_model, get_message_handler());
212+
210213
// do partial inlining
211214
status() << "Partial Inlining" << eom;
212215
goto_partial_inline(goto_model, get_message_handler());

src/goto-analyzer/goto_analyzer_parse_options.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Author: Daniel Kroening, [email protected]
3737
#include <goto-programs/read_goto_binary.h>
3838
#include <goto-programs/goto_inline.h>
3939
#include <goto-programs/link_to_library.h>
40+
#include <goto-programs/remove_java_new.h>
4041

4142
#include <analyses/is_threaded.h>
4243
#include <analyses/goto_check.h>
@@ -735,6 +736,8 @@ bool goto_analyzer_parse_optionst::process_goto_program(
735736
link_to_library(goto_model, ui_message_handler);
736737
#endif
737738

739+
remove_java_new(goto_model, get_message_handler());
740+
738741
// remove function pointers
739742
status() << "Removing function pointers and virtual functions" << eom;
740743
remove_function_pointers(

src/goto-cc/compile.cpp

+4-11
Original file line numberDiff line numberDiff line change
@@ -483,14 +483,7 @@ bool compilet::parse(const std::string &file_name)
483483

484484
languagep->set_message_handler(get_message_handler());
485485

486-
language_filet language_file;
487-
488-
std::pair<language_filest::file_mapt::iterator, bool>
489-
res=language_files.file_map.insert(
490-
std::pair<std::string, language_filet>(file_name, language_file));
491-
492-
language_filet &lf=res.first->second;
493-
lf.filename=file_name;
486+
language_filet &lf=language_files.add_file(file_name);
494487
lf.language=std::move(languagep);
495488

496489
if(mode==PREPROCESS_ONLY)
@@ -640,7 +633,7 @@ bool compilet::parse_source(const std::string &file_name)
640633
return true;
641634

642635
// so we remove it from the list afterwards
643-
language_files.file_map.erase(file_name);
636+
language_files.remove_file(file_name);
644637
return false;
645638
}
646639

@@ -691,7 +684,7 @@ void compilet::add_compiler_specific_defines(configt &config) const
691684

692685
void compilet::convert_symbols(goto_functionst &dest)
693686
{
694-
goto_convert_functionst converter(symbol_table, dest, get_message_handler());
687+
goto_convert_functionst converter(symbol_table, get_message_handler());
695688

696689
// the compilation may add symbols!
697690

@@ -724,7 +717,7 @@ void compilet::convert_symbols(goto_functionst &dest)
724717
s_it->second.value.is_not_nil())
725718
{
726719
debug() << "Compiling " << s_it->first << eom;
727-
converter.convert_function(s_it->first);
720+
converter.convert_function(s_it->first, dest.function_map[s_it->first]);
728721
symbol_table.get_writeable_ref(*it).value=exprt("compiled");
729722
}
730723
}

src/goto-diff/goto_diff_parse_options.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Author: Peter Schrammel
3737
#include <goto-programs/string_instrumentation.h>
3838
#include <goto-programs/loop_ids.h>
3939
#include <goto-programs/link_to_library.h>
40+
#include <goto-programs/remove_java_new.h>
4041

4142
#include <pointer-analysis/add_failed_symbols.h>
4243

@@ -394,9 +395,11 @@ bool goto_diff_parse_optionst::process_goto_program(
394395
{
395396
namespacet ns(symbol_table);
396397

398+
remove_java_new(goto_model, get_message_handler());
399+
397400
// Remove inline assembler; this needs to happen before
398401
// adding the library.
399-
remove_asm(symbol_table, goto_functions);
402+
remove_asm(goto_model);
400403

401404
// add the library
402405
link_to_library(symbol_table, goto_functions, ui_message_handler);

src/goto-programs/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ SRC = basic_blocks.cpp \
2727
interpreter.cpp \
2828
interpreter_evaluate.cpp \
2929
json_goto_trace.cpp \
30+
lazy_goto_model.cpp \
3031
link_goto_model.cpp \
3132
link_to_library.cpp \
3233
loop_ids.cpp \
@@ -44,6 +45,7 @@ SRC = basic_blocks.cpp \
4445
remove_exceptions.cpp \
4546
remove_function_pointers.cpp \
4647
remove_instanceof.cpp \
48+
remove_java_new.cpp \
4749
remove_returns.cpp \
4850
remove_skip.cpp \
4951
remove_static_init_loops.cpp \

src/goto-programs/builtin_functions.cpp

+1-62
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Author: Daniel Kroening, [email protected]
3333
#include <ansi-c/string_constant.h>
3434

3535
#include "format_strings.h"
36+
#include "class_identifier.h"
3637

3738
void goto_convertt::do_prob_uniform(
3839
const exprt &lhs,
@@ -539,68 +540,6 @@ void goto_convertt::do_cpp_new(
539540
dest.destructive_append(tmp_initializer);
540541
}
541542

542-
void set_class_identifier(
543-
struct_exprt &expr,
544-
const namespacet &ns,
545-
const symbol_typet &class_type)
546-
{
547-
const struct_typet &struct_type=
548-
to_struct_type(ns.follow(expr.type()));
549-
const struct_typet::componentst &components=struct_type.components();
550-
551-
if(components.empty())
552-
return;
553-
assert(!expr.operands().empty());
554-
555-
if(components.front().get_name()=="@class_identifier")
556-
{
557-
assert(expr.op0().id()==ID_constant);
558-
expr.op0()=constant_exprt(class_type.get_identifier(), string_typet());
559-
}
560-
else
561-
{
562-
assert(expr.op0().id()==ID_struct);
563-
set_class_identifier(to_struct_expr(expr.op0()), ns, class_type);
564-
}
565-
}
566-
567-
void goto_convertt::do_java_new(
568-
const exprt &lhs,
569-
const side_effect_exprt &rhs,
570-
goto_programt &dest)
571-
{
572-
PRECONDITION(!lhs.is_nil());
573-
PRECONDITION(rhs.operands().empty());
574-
PRECONDITION(rhs.type().id() == ID_pointer);
575-
source_locationt location=rhs.source_location();
576-
typet object_type=rhs.type().subtype();
577-
578-
// build size expression
579-
exprt object_size=size_of_expr(object_type, ns);
580-
CHECK_RETURN(object_size.is_not_nil());
581-
582-
// we produce a malloc side-effect, which stays
583-
side_effect_exprt malloc_expr(ID_allocate);
584-
malloc_expr.copy_to_operands(object_size);
585-
// could use true and get rid of the code below
586-
malloc_expr.copy_to_operands(false_exprt());
587-
malloc_expr.type()=rhs.type();
588-
589-
goto_programt::targett t_n=dest.add_instruction(ASSIGN);
590-
t_n->code=code_assignt(lhs, malloc_expr);
591-
t_n->source_location=location;
592-
593-
// zero-initialize the object
594-
dereference_exprt deref(lhs, object_type);
595-
exprt zero_object=
596-
zero_initializer(object_type, location, ns, get_message_handler());
597-
set_class_identifier(
598-
to_struct_expr(zero_object), ns, to_symbol_type(object_type));
599-
goto_programt::targett t_i=dest.add_instruction(ASSIGN);
600-
t_i->code=code_assignt(deref, zero_object);
601-
t_i->source_location=location;
602-
}
603-
604543
void goto_convertt::do_java_new_array(
605544
const exprt &lhs,
606545
const side_effect_exprt &rhs,

src/goto-programs/class_identifier.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,39 @@ exprt get_class_identifier_field(
7171
exprt deref=dereference_exprt(this_expr, this_expr.type().subtype());
7272
return build_class_identifier(deref, ns);
7373
}
74+
75+
/// If expr has its components filled in then sets the `@class_identifier`
76+
/// member of the struct
77+
/// \remarks Follows through base class members until it gets to the object
78+
/// type that contains the `@class_identifier` member
79+
/// \param expr: An expression that represents a struct
80+
/// \param ns: The namespace used to resolve symbol referencess in the type of
81+
/// the struct
82+
/// \param class_type: A symbol whose identifier is the name of the class
83+
void set_class_identifier(
84+
struct_exprt &expr,
85+
const namespacet &ns,
86+
const symbol_typet &class_type)
87+
{
88+
const struct_typet &struct_type=to_struct_type(ns.follow(expr.type()));
89+
const struct_typet::componentst &components=struct_type.components();
90+
91+
if(components.empty())
92+
// Presumably this means the type has not yet been determined
93+
return;
94+
PRECONDITION(!expr.operands().empty());
95+
96+
if(components.front().get_name()=="@class_identifier")
97+
{
98+
INVARIANT(
99+
expr.op0().id()==ID_constant, "@class_identifier must be a constant");
100+
expr.op0()=constant_exprt(class_type.get_identifier(), string_typet());
101+
}
102+
else
103+
{
104+
// The first member must be the base class
105+
INVARIANT(
106+
expr.op0().id()==ID_struct, "Non @class_identifier must be a structure");
107+
set_class_identifier(to_struct_expr(expr.op0()), ns, class_type);
108+
}
109+
}

src/goto-programs/class_identifier.h

+6
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@ Author: Chris Smowton, [email protected]
1515
class exprt;
1616
class namespacet;
1717
class symbol_typet;
18+
class struct_exprt;
1819

1920
exprt get_class_identifier_field(
2021
const exprt &this_expr,
2122
const symbol_typet &suggested_type,
2223
const namespacet &ns);
2324

25+
void set_class_identifier(
26+
struct_exprt &expr,
27+
const namespacet &ns,
28+
const symbol_typet &class_type);
29+
2430
#endif

src/goto-programs/goto_convert.cpp

+1-4
Original file line numberDiff line numberDiff line change
@@ -756,10 +756,7 @@ void goto_convertt::convert_assign(
756756
else if(rhs.id()==ID_side_effect &&
757757
rhs.get(ID_statement)==ID_java_new)
758758
{
759-
Forall_operands(it, rhs)
760-
clean_expr(*it, dest);
761-
762-
do_java_new(lhs, to_side_effect_expr(rhs), dest);
759+
copy(code, ASSIGN, dest);
763760
}
764761
else if(rhs.id()==ID_side_effect &&
765762
rhs.get(ID_statement)==ID_java_new_array)

src/goto-programs/goto_convert_class.h

-5
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,6 @@ class goto_convertt:public messaget
142142
const side_effect_exprt &rhs,
143143
goto_programt &dest);
144144

145-
void do_java_new(
146-
const exprt &lhs,
147-
const side_effect_exprt &rhs,
148-
goto_programt &dest);
149-
150145
void do_java_new_array(
151146
const exprt &lhs,
152147
const side_effect_exprt &rhs,

src/goto-programs/goto_convert_functions.cpp

+11-13
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,16 @@ Date: June 2003
2121

2222
goto_convert_functionst::goto_convert_functionst(
2323
symbol_tablet &_symbol_table,
24-
goto_functionst &_functions,
2524
message_handlert &_message_handler):
26-
goto_convertt(_symbol_table, _message_handler),
27-
functions(_functions)
25+
goto_convertt(_symbol_table, _message_handler)
2826
{
2927
}
3028

3129
goto_convert_functionst::~goto_convert_functionst()
3230
{
3331
}
3432

35-
void goto_convert_functionst::goto_convert()
33+
void goto_convert_functionst::goto_convert(goto_functionst &functions)
3634
{
3735
// warning! hash-table iterators are not stable
3836

@@ -53,7 +51,7 @@ void goto_convert_functionst::goto_convert()
5351

5452
for(const auto &id : symbol_list)
5553
{
56-
convert_function(id);
54+
convert_function(id, functions.function_map[id]);
5755
}
5856

5957
functions.compute_location_numbers();
@@ -135,10 +133,11 @@ void goto_convert_functionst::add_return(
135133
t->source_location=source_location;
136134
}
137135

138-
void goto_convert_functionst::convert_function(const irep_idt &identifier)
136+
void goto_convert_functionst::convert_function(
137+
const irep_idt &identifier,
138+
goto_functionst::goto_functiont &f)
139139
{
140140
const symbolt &symbol=ns.lookup(identifier);
141-
goto_functionst::goto_functiont &f=functions.function_map[identifier];
142141

143142
if(f.body_available())
144143
return; // already converted
@@ -240,12 +239,11 @@ void goto_convert(
240239
const unsigned errors_before=
241240
message_handler.get_message_count(messaget::M_ERROR);
242241

243-
goto_convert_functionst goto_convert_functions(
244-
symbol_table, functions, message_handler);
242+
goto_convert_functionst goto_convert_functions(symbol_table, message_handler);
245243

246244
try
247245
{
248-
goto_convert_functions.goto_convert();
246+
goto_convert_functions.goto_convert(functions);
249247
}
250248

251249
catch(int)
@@ -276,12 +274,12 @@ void goto_convert(
276274
const unsigned errors_before=
277275
message_handler.get_message_count(messaget::M_ERROR);
278276

279-
goto_convert_functionst goto_convert_functions(
280-
symbol_table, functions, message_handler);
277+
goto_convert_functionst goto_convert_functions(symbol_table, message_handler);
281278

282279
try
283280
{
284-
goto_convert_functions.convert_function(identifier);
281+
goto_convert_functions.convert_function(
282+
identifier, functions.function_map[identifier]);
285283
}
286284

287285
catch(int)

src/goto-programs/goto_convert_functions.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Date: June 2003
1616

1717
#include "goto_model.h"
1818
#include "goto_convert_class.h"
19+
#include "goto_functions.h"
1920

2021
// convert it all!
2122
void goto_convert(
@@ -38,19 +39,18 @@ void goto_convert(
3839
class goto_convert_functionst:public goto_convertt
3940
{
4041
public:
41-
void goto_convert();
42-
void convert_function(const irep_idt &identifier);
42+
void goto_convert(goto_functionst &functions);
43+
void convert_function(
44+
const irep_idt &identifier,
45+
goto_functionst::goto_functiont &result);
4346

4447
goto_convert_functionst(
4548
symbol_tablet &_symbol_table,
46-
goto_functionst &_functions,
4749
message_handlert &_message_handler);
4850

4951
virtual ~goto_convert_functionst();
5052

5153
protected:
52-
goto_functionst &functions;
53-
5454
static bool hide(const goto_programt &);
5555

5656
//

src/goto-programs/goto_functions_template.h

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ class goto_functions_templatet
121121
return *this;
122122
}
123123

124+
void unload(const irep_idt &name) { function_map.erase(name); }
125+
124126
void clear()
125127
{
126128
function_map.clear();

0 commit comments

Comments
 (0)