@@ -455,13 +455,6 @@ public CFG buildCFG() {
455455 return getCFG ();
456456 }
457457
458- // If the scope has already been interpreted once,
459- // the scope can be on the call stack right now.
460- // So, clone instructions before building the CFG.
461- if (state == ScopeState .INTERPED ) {
462- cloneInstrs ();
463- }
464-
465458 CFG newCFG = new CFG (this );
466459 newCFG .build (getInstrs ());
467460 // Clear out instruction list after CFG has been built.
@@ -616,6 +609,19 @@ private void optimizeSimpleScopes() {
616609 }
617610
618611 protected void initScope (boolean jitMode ) {
612+ // FIXME: This is messy and prepareForInterpretation and prepareForCompilation need to
613+ // clean up the lifecycle aspects of creating CFG from instrList and running passes in
614+ // a consistent and predictable way. This is a hack atm to unbreak the fact JIT
615+ // may happen before IC.build count and thus not have cloned the instrs (which then
616+ // modifies instrs IC is using causing weird blowups.
617+ //
618+ // If the scope has already been interpreted once,
619+ // the scope can be on the call stack right now.
620+ // So, clone instructions before modifying them!
621+ if (state != ScopeState .INIT && getCFG () == null ) {
622+ cloneInstrs ();
623+ }
624+
619625 runCompilerPasses (getManager ().getCompilerPasses (this ));
620626
621627 if (!jitMode && RubyInstanceConfig .IR_COMPILER_PASSES == null ) {
@@ -672,14 +678,9 @@ protected void cloneInstrs(SimpleCloneInfo cloneInfo) {
672678 public synchronized InterpreterContext prepareForInterpretation (boolean rebuild ) {
673679 if (interpreterContext == null ) {
674680 this .state = ScopeState .INTERPED ;
681+ } else if (!rebuild || getCFG () != null ) {
682+ return interpreterContext ; // Already prepared/rebuilt
675683 } else {
676- if (!rebuild || getCFG () != null ) {
677- return interpreterContext ; // Already prepared/rebuilt
678- }
679-
680- // If rebuilding, clone instrs before building cfg, running passes, etc.
681- this .cloneInstrs ();
682-
683684 // Build CFG, run passes, etc.
684685 initScope (false );
685686
@@ -698,15 +699,6 @@ public synchronized InterpreterContext prepareForInterpretation(boolean rebuild)
698699
699700 /** Run any necessary passes to get the IR ready for compilation */
700701 public synchronized List <BasicBlock > prepareForCompilation () {
701- // FIXME: This is messy and prepareForInterpretation and prepareForCompilation need to
702- // clean up the lifecycle aspects of creating CFG from instrList and running passes in
703- // a consistent and predictable way. This is a hack atm to unbreak the fact JIT
704- // may happen before IC.build count and thus not have cloned the instrs (which then
705- // modifies instrs IC is using causing weird blowups.
706- if (getCFG () == null ) {
707- cloneInstrs ();
708- }
709-
710702 // Reset linearization, if any exists
711703 resetLinearizationData ();
712704
0 commit comments