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
24 redef class RapidTypeAnalysis
25 redef fun add_type
(mtype
)
28 mtype
.mclass
.nlvt
+= 1
29 mtype
.mclass
.live_types
.add
(mtype
)
33 redef fun add_cast_type
(mtype
)
36 mtype
.mclass
.nlct
+= 1
37 mtype
.mclass
.cast_types
.add
(mtype
)
43 private var nlvt
: Int = 0
44 private var nlct
: Int = 0
46 private fun is_user_defined
: Bool do
48 if mtype
isa MNullableType then mtype
= mtype
.mtype
49 return self.as(MClassType).mclass
.is_user_defined
52 private fun get_depth
: Int do
54 if mtype
isa MNullableType then mtype
= mtype
.mtype
55 if not mtype
isa MGenericType then return 0
58 for ft
in mtype
.arguments
do
59 if ft
.get_depth
> depth
then depth
= ft
.get_depth
66 private var nlvt
: Int = 0
67 private var nlct
: Int = 0
68 private var live_types
: Set[MType] = new HashSet[MType]
69 private var cast_types
: Set[MType] = new HashSet[MType]
72 # Run a runtime type analysis and print metrics
73 fun compute_rta_metrics
(modelbuilder
: ModelBuilder, mainmodule
: MModule)
75 var analysis
= modelbuilder
.do_rapid_type_analysis
(mainmodule
)
77 var nlvt
= 0 # NLVT Number of Live Type
78 var nlvtg
= 0 # NLVTG Number of Generic Live Type
79 var nlvtslud
= 0 # NLCTSLUD Number of Live Type defined in SL and init in UD
80 var nlvtgslud
= 0 # NLVTGSLUD Number of Generic Live Type defined in SL and init in UD
81 var nlvtudud
= 0 # NLVTUDUD Number of Live Type defined in UD and init in UD
82 var nlvtgudud
= 0 # NLVTGUDUD Number of Generic Live Type defined in UD and init in UD
84 var nlct
= 0 # NLCT Number of Live Cast Type
85 var nlctg
= 0 # NLCTG Number of Generic Live Cast Type
86 var nlctslud
= 0 # NLCTSLUD Number of Live Cast Type defined in SL and init in UD
87 var nlctgslud
= 0 # NLCTGSLUD Number of Generic Live Cast Type defined in SL and init in UD
88 var nlctudud
= 0 # NLCTUDUD Number of Live Cast Type defined in UD and init in UD
89 var nlctgudud
= 0 # NLCTGUDUD Number of Generic Live Cast Type defined in UD and init in UD
91 var mtypes
= new HashSet[MClassType]
93 for mtype
in analysis
.live_types
do
96 if mtype
isa MGenericType then nlvtg
+= 1
97 if mtype
.is_user_defined
then
99 if mtype
isa MGenericType then nlvtgudud
+= 1
102 if mtype
isa MGenericType then nlvtgslud
+= 1
106 for mtype
in analysis
.live_cast_types
do
109 if mtype
isa MGenericType then nlctg
+= 1
110 if mtype
.is_user_defined
then
112 if mtype
isa MGenericType then nlctgudud
+= 1
115 if mtype
isa MGenericType then nlctgslud
+= 1
120 if modelbuilder
.toolcontext
.opt_generate_csv
.value
then
121 var summaryCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_sum_metrics.csv"))
122 summaryCSV
.set_header
("scope", "NLVT", "NLVTG", "NLCT", "NLVCTG")
123 summaryCSV
.add_line
("global", nlvt
, nlvtg
, nlct
, nlctg
)
124 summaryCSV
.add_line
("SLUD", nlvtslud
, nlvtgslud
, nlctslud
, nlctgslud
)
125 summaryCSV
.add_line
("UDUD", nlvtudud
, nlvtgudud
, nlctudud
, nlctgudud
)
128 var scalarCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_scalar_metrics.csv"))
129 var udscalarCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_ud_scalar_metrics.csv"))
130 scalarCSV
.set_header
("Type", "AGS", "DGS", "NLVT", "NLCT")
131 udscalarCSV
.set_header
("Type", "AGS", "DGS", "NLVT", "NLCT")
133 for mtype
in mtypes
do
135 if mtype
isa MGenericType then arity
= mtype
.arguments
.length
136 if mtype
.is_user_defined
then
137 udscalarCSV
.add_line
(mtype
, arity
, mtype
.get_depth
, mtype
.nlvt
, mtype
.nlct
)
139 scalarCSV
.add_line
(mtype
, arity
, mtype
.get_depth
, mtype
.nlvt
, mtype
.nlct
)
144 scalarCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_scalar_class_metrics.csv"))
145 udscalarCSV
= new CSVDocument(modelbuilder
.toolcontext
.output_dir
.join_path
("rta_ud_scalar_class_metrics.csv"))
146 scalarCSV
.set_header
("Class", "AGS", "NLVV", "NLVT")
147 udscalarCSV
.set_header
("Class", "AGS", "NLVV", "inst")
149 for mclass
in modelbuilder
.model
.mclasses
do
150 if not mclass
.is_class
or mclass
.is_abstract
then continue
151 if mclass
.is_user_defined
then
152 udscalarCSV
.add_line
(mclass
.mclass_type
, mclass
.arity
, mclass
.live_types
.length
, mclass
.nlvt
)
154 scalarCSV
.add_line
(mclass
.mclass_type
, mclass
.arity
, mclass
.live_types
.length
, mclass
.nlvt
)
160 print
"--- RTA metrics ---"
161 print
"Number of live runtime types (instantied resolved type): {analysis.live_types.length}"
162 if analysis
.live_types
.length
< 8 then print
"\t{analysis.live_types.join(" ")}"
163 print
"Number of live method definitions: {analysis.live_methoddefs.length}"
164 if analysis
.live_methoddefs
.length
< 8 then print
"\t{analysis.live_methoddefs.join(" ")}"
165 print
"Number of live customized method definitions: {analysis.live_customized_methoddefs.length}"
166 if analysis
.live_customized_methoddefs
.length
< 8 then print
"\t{analysis.live_customized_methoddefs.join(" ")}"
167 print
"Number of live runtime cast types (ie used in as and isa): {analysis.live_cast_types.length}"
168 if analysis
.live_cast_types
.length
< 8 then print
"\t{analysis.live_cast_types.join(" ")}"