@@ -25,6 +25,7 @@ use std::path::Path;
25
25
use anyhow:: Context ;
26
26
use gazebo:: any:: AnyLifetime ;
27
27
use gazebo:: cast;
28
+ use gazebo:: dupe:: Dupe ;
28
29
use thiserror:: Error ;
29
30
30
31
use crate :: codemap:: FileSpan ;
@@ -49,6 +50,7 @@ use crate::eval::runtime::profile::bc::BcProfile;
49
50
use crate :: eval:: runtime:: profile:: flame:: FlameProfile ;
50
51
use crate :: eval:: runtime:: profile:: heap:: HeapProfile ;
51
52
use crate :: eval:: runtime:: profile:: heap:: HeapProfileFormat ;
53
+ use crate :: eval:: runtime:: profile:: or_instrumentation:: ProfileOrInstrumentationMode ;
52
54
use crate :: eval:: runtime:: profile:: stmt:: StmtProfile ;
53
55
use crate :: eval:: runtime:: profile:: typecheck:: TypecheckProfile ;
54
56
use crate :: eval:: runtime:: profile:: ProfileMode ;
@@ -85,6 +87,8 @@ pub(crate) enum EvaluatorError {
85
87
BcProfilingNotEnabled ,
86
88
#[ error( "Typecheck profiling not enabled" ) ]
87
89
TypecheckProfilingNotEnabled ,
90
+ #[ error( "Profile or instrumentation already enabled" ) ]
91
+ ProfileOrInstrumentationAlreadyEnabled ,
88
92
#[ error( "Top frame is not def (internal error)" ) ]
89
93
TopFrameNotDef ,
90
94
#[ error( "Top second frame is not def (internal error)" ) ]
@@ -124,6 +128,8 @@ pub struct Evaluator<'v, 'a> {
124
128
pub ( crate ) verbose_gc : bool ,
125
129
// Size of the heap when we should next perform a GC.
126
130
pub ( crate ) next_gc_level : usize ,
131
+ // Profiling or instrumentation enabled.
132
+ pub ( crate ) profile_or_instrumentation_mode : ProfileOrInstrumentationMode ,
127
133
// Extra functions to run on each statement, usually empty
128
134
pub ( crate ) before_stmt : BeforeStmt < ' a > ,
129
135
// Used for line profiling
@@ -174,6 +180,7 @@ impl<'v, 'a> Evaluator<'v, 'a> {
174
180
next_gc_level : GC_THRESHOLD ,
175
181
disable_gc : false ,
176
182
alloca : Alloca :: new ( ) ,
183
+ profile_or_instrumentation_mode : ProfileOrInstrumentationMode :: None ,
177
184
heap_profile : HeapProfile :: new ( ) ,
178
185
stmt_profile : StmtProfile :: new ( ) ,
179
186
bc_profile : BcProfile :: new ( ) ,
@@ -212,6 +219,12 @@ impl<'v, 'a> Evaluator<'v, 'a> {
212
219
/// Profilers add overhead, and while some profilers can be used together,
213
220
/// it's better to run at most one profiler at a time.
214
221
pub fn enable_profile ( & mut self , mode : & ProfileMode ) -> anyhow:: Result < ( ) > {
222
+ if self . profile_or_instrumentation_mode != ProfileOrInstrumentationMode :: None {
223
+ return Err ( EvaluatorError :: ProfileOrInstrumentationAlreadyEnabled . into ( ) ) ;
224
+ }
225
+
226
+ self . profile_or_instrumentation_mode = ProfileOrInstrumentationMode :: Profile ( mode. dupe ( ) ) ;
227
+
215
228
match mode {
216
229
ProfileMode :: HeapSummary
217
230
| ProfileMode :: HeapFlame
@@ -255,6 +268,13 @@ impl<'v, 'a> Evaluator<'v, 'a> {
255
268
/// This function need to be called when evaluating a dependency of a module, if a module
256
269
/// does profiling in the given mode.
257
270
pub fn enable_profile_instrumentation ( & mut self , mode : & ProfileMode ) -> anyhow:: Result < ( ) > {
271
+ if self . profile_or_instrumentation_mode != ProfileOrInstrumentationMode :: None {
272
+ return Err ( EvaluatorError :: ProfileOrInstrumentationAlreadyEnabled . into ( ) ) ;
273
+ }
274
+
275
+ self . profile_or_instrumentation_mode =
276
+ ProfileOrInstrumentationMode :: Instrumentation ( mode. dupe ( ) ) ;
277
+
258
278
match mode {
259
279
ProfileMode :: Bytecode | ProfileMode :: BytecodePairs => {
260
280
self . bc_profile . enable_1 ( ) ;
0 commit comments