@@ -25,6 +25,7 @@ use std::path::Path;
2525use anyhow:: Context ;
2626use gazebo:: any:: AnyLifetime ;
2727use gazebo:: cast;
28+ use gazebo:: dupe:: Dupe ;
2829use thiserror:: Error ;
2930
3031use crate :: codemap:: FileSpan ;
@@ -49,6 +50,7 @@ use crate::eval::runtime::profile::bc::BcProfile;
4950use crate :: eval:: runtime:: profile:: flame:: FlameProfile ;
5051use crate :: eval:: runtime:: profile:: heap:: HeapProfile ;
5152use crate :: eval:: runtime:: profile:: heap:: HeapProfileFormat ;
53+ use crate :: eval:: runtime:: profile:: or_instrumentation:: ProfileOrInstrumentationMode ;
5254use crate :: eval:: runtime:: profile:: stmt:: StmtProfile ;
5355use crate :: eval:: runtime:: profile:: typecheck:: TypecheckProfile ;
5456use crate :: eval:: runtime:: profile:: ProfileMode ;
@@ -85,6 +87,8 @@ pub(crate) enum EvaluatorError {
8587 BcProfilingNotEnabled ,
8688 #[ error( "Typecheck profiling not enabled" ) ]
8789 TypecheckProfilingNotEnabled ,
90+ #[ error( "Profile or instrumentation already enabled" ) ]
91+ ProfileOrInstrumentationAlreadyEnabled ,
8892 #[ error( "Top frame is not def (internal error)" ) ]
8993 TopFrameNotDef ,
9094 #[ error( "Top second frame is not def (internal error)" ) ]
@@ -124,6 +128,8 @@ pub struct Evaluator<'v, 'a> {
124128 pub ( crate ) verbose_gc : bool ,
125129 // Size of the heap when we should next perform a GC.
126130 pub ( crate ) next_gc_level : usize ,
131+ // Profiling or instrumentation enabled.
132+ pub ( crate ) profile_or_instrumentation_mode : ProfileOrInstrumentationMode ,
127133 // Extra functions to run on each statement, usually empty
128134 pub ( crate ) before_stmt : BeforeStmt < ' a > ,
129135 // Used for line profiling
@@ -174,6 +180,7 @@ impl<'v, 'a> Evaluator<'v, 'a> {
174180 next_gc_level : GC_THRESHOLD ,
175181 disable_gc : false ,
176182 alloca : Alloca :: new ( ) ,
183+ profile_or_instrumentation_mode : ProfileOrInstrumentationMode :: None ,
177184 heap_profile : HeapProfile :: new ( ) ,
178185 stmt_profile : StmtProfile :: new ( ) ,
179186 bc_profile : BcProfile :: new ( ) ,
@@ -212,6 +219,12 @@ impl<'v, 'a> Evaluator<'v, 'a> {
212219 /// Profilers add overhead, and while some profilers can be used together,
213220 /// it's better to run at most one profiler at a time.
214221 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+
215228 match mode {
216229 ProfileMode :: HeapSummary
217230 | ProfileMode :: HeapFlame
@@ -255,6 +268,13 @@ impl<'v, 'a> Evaluator<'v, 'a> {
255268 /// This function need to be called when evaluating a dependency of a module, if a module
256269 /// does profiling in the given mode.
257270 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+
258278 match mode {
259279 ProfileMode :: Bytecode | ProfileMode :: BytecodePairs => {
260280 self . bc_profile . enable_1 ( ) ;
0 commit comments