1 % (c) 2018-2024 Lehrstuhl fuer Softwaretechnik und Programmiersprachen,
2 % Heinrich Heine Universitaet Duesseldorf
3 % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html)
4
5 :- module(source_profiler,[reset_source_profiler/0, source_profiler_enabled/0,
6 add_source_location_hits/2,
7 opt_add_source_location_hits/2, % only add if source_profiler_enabled
8 %tcltk_get_source_profile_info/1,
9 show_source_profile_in_bbresults/0,
10 print_source_profile/0,
11 tcltk_get_source_hit_location/5]).
12
13
14 :- use_module(module_information,[module_info/2]).
15 :- module_info(group,profiling).
16 :- module_info(description,'This module provides a simple B model source profiler.').
17
18 :- load_files(library(system), [when(compile_time), imports([environ/2])]).
19
20 :- use_module(preferences,[preference/2,get_preference/2]).
21
22 :- if(environ(prob_src_profile, false)).
23 opt_add_source_location_hits(_,_).
24 source_profiler_enabled :- source_hits(_,_,_),!. % enabled if add_source_location_hits was called
25 :- else.
26 source_profiler_enabled :- get_preference(prob_source_profiling_on,true).
27 opt_add_source_location_hits(_,_) :- preference(prob_source_profiling_on,false),!.
28 opt_add_source_location_hits(SourceSpan,Nr) :-
29 add_source_location_hits(SourceSpan,Nr).
30 :- endif.
31
32 :- volatile source_hits/3.
33 :- dynamic source_hits/3.
34
35 reset_source_profiler :-
36 retractall(source_hits(_,_,_)).
37
38 :- use_module(eventhandling,[register_event_listener/3]).
39 :- register_event_listener(clear_specification,reset_source_profiler,
40 'Reset source location profiler.').
41
42 :- use_module(library(terms),[term_hash/2]).
43 add_source_location_hits(SourceSpan,Nr) :-
44 %error_manager:extract_span_description(SourceSpan,M), print(M),nl,
45 term_hash(SourceSpan,Hash),
46 (retract(source_hits(Hash,SourceSpan,Old)) -> New is Old+Nr ; New is Nr),
47 assertz(source_hits(Hash,SourceSpan,New)).
48
49 :- use_module(library(lists)).
50 :- use_module(error_manager,[extract_file_line_col/6, extract_line_col_for_main_file/5]).
51
52 print_source_profile :-
53 source_profiler_enabled,!,
54 format('----Source Location Profiler Information----~n',[]),
55 format('----Tracks number of times B statements (aka substitutions) are hit~n',[]),
56 % TO DO: also cover function calls, and other types of hits
57 findall(src_loc_msg(Nr,FullFilename,Line,Col,EndLine,EndCol),
58 source_hit(FullFilename,Line,Col,EndLine,EndCol,Nr),
59 Ls),
60 sort(Ls,Sorted),
61 maplist(print_src,Sorted),
62 format('----~n',[]).
63 print_source_profile :-
64 print('No source profiling information available'),nl,
65 print('Set preference SOURCE_PROFILING_INFO to TRUE'),nl. % and possible remove compile time flag
66
67 :- use_module(tools_commands,[show_source_locations_with_bb_results/1]).
68 show_source_profile_in_bbresults :-
69 findall(src_loc_msg(Nr,FullFilename,Line,Col,EndLine,EndCol),
70 source_hit(FullFilename,Line,Col,EndLine,EndCol,Nr),
71 Ls),
72 (Ls=[] -> print('No source profiling information available'),nl
73 ; sort(Ls,Sorted), reverse(Sorted,RS),
74 show_source_locations_with_bb_results(RS)).
75
76 source_hit(FullFilename,Line,Col,EndLine,EndCol,Nr) :-
77 source_hits(_,SourceSpan,Nr),
78 extract_file_line_col(SourceSpan,FullFilename,Line,Col,EndLine,EndCol).
79
80 print_src(src_loc_msg(Nr,FullFilename,Line,Col,EndLine,EndCol)) :-
81 format(' ~w hits at ~w:~w -- ~w:~w in ~w~n',[Nr,Line,Col,EndLine,EndCol,FullFilename]).
82
83 % can be used in a while loop:
84 tcltk_get_source_hit_location(Nr,Srow,Scol,Erow,Ecol) :-
85 retract(source_hits(_,Span,Nr)),
86 extract_line_col_for_main_file(Span,Srow,Scol,Erow,Ecol).
87