1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2012 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
21 private import rapid_type_analysis
22 private import metrics_base
25 redef class ToolContext
26 var rta_metrics_phase
= new RTAMetricsPhase(self, null)
29 private class RTAMetricsPhase
31 redef fun process_mainmodule
(mainmodule
)
33 if not toolcontext
.opt_rta
.value
and not toolcontext
.opt_all
.value
then return
34 compute_rta_metrics
(toolcontext
.modelbuilder
, mainmodule
)
38 redef class RapidTypeAnalysis
39 redef fun add_type
(mtype
)
42 mtype
.mclass
.nlvt
+= 1
43 mtype
.mclass
.live_types
.add
(mtype
)
47 redef fun add_cast_type
(mtype
)
50 mtype
.mclass
.nlct
+= 1
51 mtype
.mclass
.cast_types
.add
(mtype
)
60 fun is_user_defined
: Bool do
62 if mtype
isa MNullableType then mtype
= mtype
.mtype
63 return self.as(MClassType).mclass
.is_user_defined
68 if mtype
isa MNullableType then mtype
= mtype
.mtype
69 if not mtype
isa MGenericType then return 0
72 for ft
in mtype
.arguments
do
73 if ft
.get_depth
> depth
then depth
= ft
.get_depth
82 var live_types
: Set[MType] = new HashSet[MType]
83 var cast_types
: Set[MType] = new HashSet[MType]
86 # Run a runtime type analysis and print metrics
87 fun compute_rta_metrics
(modelbuilder
: ModelBuilder, mainmodule
: MModule)
89 var analysis
= modelbuilder
.do_rapid_type_analysis
(mainmodule
)
91 var nlvt
= 0 # NLVT Number of Live Type
92 var nlvtg
= 0 # NLVTG Number of Generic Live Type
93 var nlvtslud
= 0 # NLCTSLUD Number of Live Type defined in SL and init in UD
94 var nlvtgslud
= 0 # NLVTGSLUD Number of Generic Live Type defined in SL and init in UD
95 var nlvtudud
= 0 # NLVTUDUD Number of Live Type defined in UD and init in UD
96 var nlvtgudud
= 0 # NLVTGUDUD Number of Generic Live Type defined in UD and init in UD
98 var nlct
= 0 # NLCT Number of Live Cast Type
99 var nlctg
= 0 # NLCTG Number of Generic Live Cast Type
100 var nlctslud
= 0 # NLCTSLUD Number of Live Cast Type defined in SL and init in UD
101 var nlctgslud
= 0 # NLCTGSLUD Number of Generic Live Cast Type defined in SL and init in UD
102 var nlctudud
= 0 # NLCTUDUD Number of Live Cast Type defined in UD and init in UD
103 var nlctgudud
= 0 # NLCTGUDUD Number of Generic Live Cast Type defined in UD and init in UD
105 var mtypes
= new HashSet[MClassType]
107 for mtype
in analysis
.live_types
do
110 if mtype
isa MGenericType then nlvtg
+= 1
111 if mtype
.is_user_defined
then
113 if mtype
isa MGenericType then nlvtgudud
+= 1
116 if mtype
isa MGenericType then nlvtgslud
+= 1
120 for mtype
in analysis
.live_cast_types
do
123 if mtype
isa MGenericType then nlctg
+= 1
124 if mtype
.is_user_defined
then
126 if mtype
isa MGenericType then nlctgudud
+= 1
129 if mtype
isa MGenericType then nlctgslud
+= 1
134 if modelbuilder
.toolcontext
.opt_generate_csv
.value
then
135 var summaryCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_sum_metrics.csv"))
136 summaryCSV
.set_header
("scope", "NLVT", "NLVTG", "NLCT", "NLVCTG")
137 summaryCSV
.add_line
("global", nlvt
, nlvtg
, nlct
, nlctg
)
138 summaryCSV
.add_line
("SLUD", nlvtslud
, nlvtgslud
, nlctslud
, nlctgslud
)
139 summaryCSV
.add_line
("UDUD", nlvtudud
, nlvtgudud
, nlctudud
, nlctgudud
)
142 var scalarCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_scalar_metrics.csv"))
143 var udscalarCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_ud_scalar_metrics.csv"))
144 scalarCSV
.set_header
("Type", "AGS", "DGS", "NLVT", "NLCT")
145 udscalarCSV
.set_header
("Type", "AGS", "DGS", "NLVT", "NLCT")
147 for mtype
in mtypes
do
149 if mtype
isa MGenericType then arity
= mtype
.arguments
.length
150 if mtype
.is_user_defined
then
151 udscalarCSV
.add_line
(mtype
, arity
, mtype
.get_depth
, mtype
.nlvt
, mtype
.nlct
)
153 scalarCSV
.add_line
(mtype
, arity
, mtype
.get_depth
, mtype
.nlvt
, mtype
.nlct
)
158 scalarCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_scalar_class_metrics.csv"))
159 udscalarCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_ud_scalar_class_metrics.csv"))
160 scalarCSV
.set_header
("Class", "AGS", "NLVV", "NLVT")
161 udscalarCSV
.set_header
("Class", "AGS", "NLVV", "inst")
163 for mclass
in modelbuilder
.model
.mclasses
do
164 if not mclass
.is_class
or mclass
.is_abstract
then continue
165 if mclass
.is_user_defined
then
166 udscalarCSV
.add_line
(mclass
.mclass_type
, mclass
.arity
, mclass
.live_types
.length
, mclass
.nlvt
)
168 scalarCSV
.add_line
(mclass
.mclass_type
, mclass
.arity
, mclass
.live_types
.length
, mclass
.nlvt
)
174 print
"--- RTA metrics ---"
175 print
"Number of live runtime types (instantied resolved type): {analysis.live_types.length}"
176 if analysis
.live_types
.length
< 8 then print
"\t{analysis.live_types.join(" ")}"
177 print
"Number of live method definitions: {analysis.live_methoddefs.length}"
178 if analysis
.live_methoddefs
.length
< 8 then print
"\t{analysis.live_methoddefs.join(" ")}"
179 print
"Number of live customized method definitions: {analysis.live_customized_methoddefs.length}"
180 if analysis
.live_customized_methoddefs
.length
< 8 then print
"\t{analysis.live_customized_methoddefs.join(" ")}"
181 print
"Number of live runtime cast types (ie used in as and isa): {analysis.live_cast_types.length}"
182 if analysis
.live_cast_types
.length
< 8 then print
"\t{analysis.live_cast_types.join(" ")}"