diff --git a/chain/consensus/compute_state.go b/chain/consensus/compute_state.go
index e627a62d2..cf05d612d 100644
--- a/chain/consensus/compute_state.go
+++ b/chain/consensus/compute_state.go
@@ -93,7 +93,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
 	}()
 
 	ctx = blockstore.WithHotView(ctx)
-	makeVm := func(base cid.Cid, e abi.ChainEpoch, timestamp uint64) (vm.Interface, error) {
+	makeVm := func(base cid.Cid, e abi.ChainEpoch, timestamp uint64) (vm.Executor, error) {
 		vmopt := &vm.VMOpts{
 			StateBase:      base,
 			Epoch:          e,
@@ -109,6 +109,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
 			TipSetGetter:   stmgr.TipSetGetterForTipset(sm.ChainStore(), ts),
 			Tracing:        vmTracing,
 			ReturnEvents:   sm.ChainStore().IsStoringEvents(),
+			ExecutionLane:  vm.ExecutionLanePriority,
 		}
 
 		return sm.VMConstructor()(ctx, vmopt)
@@ -116,7 +117,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
 
 	var cronGas int64
 
-	runCron := func(vmCron vm.Interface, epoch abi.ChainEpoch) error {
+	runCron := func(vmCron vm.Executor, epoch abi.ChainEpoch) error {
 		cronMsg := &types.Message{
 			To:         cron.Address,
 			From:       builtin.SystemActorAddr,
@@ -169,13 +170,17 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
 
 			// run cron for null rounds if any
 			if err = runCron(vmCron, i); err != nil {
+				vmCron.Done()
 				return cid.Undef, cid.Undef, xerrors.Errorf("running cron: %w", err)
 			}
 
 			pstate, err = vmCron.Flush(ctx)
 			if err != nil {
+				vmCron.Done()
 				return cid.Undef, cid.Undef, xerrors.Errorf("flushing cron vm: %w", err)
 			}
+
+			vmCron.Done()
 		}
 
 		// handle state forks
@@ -195,6 +200,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
 	if err != nil {
 		return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
 	}
+	defer vmi.Done()
 
 	var (
 		receipts      []*types.MessageReceipt
diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go
index 3e8848021..3ef8de968 100644
--- a/chain/gen/genesis/genesis.go
+++ b/chain/gen/genesis/genesis.go
@@ -496,6 +496,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, sys vm.Sysca
 	if err != nil {
 		return cid.Undef, xerrors.Errorf("failed to create VM: %w", err)
 	}
+	defer vm.Done()
 
 	for mi, m := range template.Miners {
 		for si, s := range m.Sectors {
diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go
index 5f741fd7c..6e5be0b0a 100644
--- a/chain/gen/genesis/miners.go
+++ b/chain/gen/genesis/miners.go
@@ -88,7 +88,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
 		return big.Zero(), nil
 	}
 
-	newVM := func(base cid.Cid) (vm.Interface, error) {
+	newVM := func(base cid.Cid) (vm.Executor, error) {
 		vmopt := &vm.VMOpts{
 			StateBase:      base,
 			Epoch:          0,
@@ -108,6 +108,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
 	if err != nil {
 		return cid.Undef, fmt.Errorf("creating vm: %w", err)
 	}
+	defer genesisVm.Done()
 
 	if len(miners) == 0 {
 		return cid.Undef, xerrors.New("no genesis miners")
@@ -338,6 +339,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
 			return cid.Undef, xerrors.Errorf("flushing state tree: %w", err)
 		}
 
+		genesisVm.Done()
 		genesisVm, err = newVM(nh)
 		if err != nil {
 			return cid.Undef, fmt.Errorf("creating new vm: %w", err)
@@ -410,6 +412,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
 					return cid.Undef, xerrors.Errorf("flushing state tree: %w", err)
 				}
 
+				genesisVm.Done()
 				genesisVm, err = newVM(nh)
 				if err != nil {
 					return cid.Undef, fmt.Errorf("creating new vm: %w", err)
@@ -517,6 +520,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
 						return cid.Undef, xerrors.Errorf("flushing state tree: %w", err)
 					}
 
+					genesisVm.Done()
 					genesisVm, err = newVM(nh)
 					if err != nil {
 						return cid.Undef, fmt.Errorf("creating new vm: %w", err)
diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go
index f91d8997d..d852e2fdd 100644
--- a/chain/stmgr/forks_test.go
+++ b/chain/stmgr/forks_test.go
@@ -56,6 +56,12 @@ const testForkHeight = 40
 type testActor struct {
 }
 
+type mockExecutor struct {
+	vm.Interface
+}
+
+func (*mockExecutor) Done() {}
+
 // must use existing actor that an account is allowed to exec.
 func (testActor) Code() cid.Cid  { return builtin0.PaymentChannelActorCodeID }
 func (testActor) State() cbor.Er { return new(testActorState) }
@@ -178,13 +184,13 @@ func TestForkHeightTriggers(t *testing.T) {
 	registry := builtin.MakeRegistryLegacy([]rtt.VMActor{testActor{}})
 	inv.Register(actorstypes.Version0, nil, registry)
 
-	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
+	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Executor, error) {
 		nvm, err := vm.NewLegacyVM(ctx, vmopt)
 		if err != nil {
 			return nil, err
 		}
 		nvm.SetInvoker(inv)
-		return nvm, nil
+		return &mockExecutor{nvm}, nil
 	})
 
 	cg.SetStateManager(sm)
@@ -296,13 +302,13 @@ func testForkRefuseCall(t *testing.T, nullsBefore, nullsAfter int) {
 	registry := builtin.MakeRegistryLegacy([]rtt.VMActor{testActor{}})
 	inv.Register(actorstypes.Version0, nil, registry)
 
-	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
+	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Executor, error) {
 		nvm, err := vm.NewLegacyVM(ctx, vmopt)
 		if err != nil {
 			return nil, err
 		}
 		nvm.SetInvoker(inv)
-		return nvm, nil
+		return &mockExecutor{nvm}, nil
 	})
 
 	cg.SetStateManager(sm)
@@ -518,13 +524,13 @@ func TestForkPreMigration(t *testing.T) {
 	registry := builtin.MakeRegistryLegacy([]rtt.VMActor{testActor{}})
 	inv.Register(actorstypes.Version0, nil, registry)
 
-	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
+	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Executor, error) {
 		nvm, err := vm.NewLegacyVM(ctx, vmopt)
 		if err != nil {
 			return nil, err
 		}
 		nvm.SetInvoker(inv)
-		return nvm, nil
+		return &mockExecutor{nvm}, nil
 	})
 
 	cg.SetStateManager(sm)
@@ -592,11 +598,11 @@ func TestDisablePreMigration(t *testing.T) {
 	registry := builtin.MakeRegistryLegacy([]rtt.VMActor{testActor{}})
 	inv.Register(actorstypes.Version0, nil, registry)
 
-	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
+	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Executor, error) {
 		nvm, err := vm.NewLegacyVM(ctx, vmopt)
 		require.NoError(t, err)
 		nvm.SetInvoker(inv)
-		return nvm, nil
+		return &mockExecutor{nvm}, nil
 	})
 
 	cg.SetStateManager(sm)
@@ -647,11 +653,11 @@ func TestMigrtionCache(t *testing.T) {
 	registry := builtin.MakeRegistryLegacy([]rtt.VMActor{testActor{}})
 	inv.Register(actorstypes.Version0, nil, registry)
 
-	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
+	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Executor, error) {
 		nvm, err := vm.NewLegacyVM(ctx, vmopt)
 		require.NoError(t, err)
 		nvm.SetInvoker(inv)
-		return nvm, nil
+		return &mockExecutor{nvm}, nil
 	})
 
 	cg.SetStateManager(sm)
@@ -691,11 +697,11 @@ func TestMigrtionCache(t *testing.T) {
 			index.DummyMsgIndex,
 		)
 		require.NoError(t, err)
-		sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
+		sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Executor, error) {
 			nvm, err := vm.NewLegacyVM(ctx, vmopt)
 			require.NoError(t, err)
 			nvm.SetInvoker(inv)
-			return nvm, nil
+			return &mockExecutor{nvm}, nil
 		})
 
 		ctx := context.Background()
diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go
index 827aeeee5..5f201cf32 100644
--- a/chain/stmgr/stmgr.go
+++ b/chain/stmgr/stmgr.go
@@ -125,7 +125,7 @@ type StateManager struct {
 	compWait            map[string]chan struct{}
 	stlk                sync.Mutex
 	genesisMsigLk       sync.Mutex
-	newVM               func(context.Context, *vm.VMOpts) (vm.Interface, error)
+	newVM               func(context.Context, *vm.VMOpts) (vm.Executor, error)
 	Syscalls            vm.SyscallBuilder
 	preIgnitionVesting  []msig0.State
 	postIgnitionVesting []msig0.State
@@ -439,12 +439,12 @@ func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) err
 	return nil
 }
 
-func (sm *StateManager) SetVMConstructor(nvm func(context.Context, *vm.VMOpts) (vm.Interface, error)) {
+func (sm *StateManager) SetVMConstructor(nvm func(context.Context, *vm.VMOpts) (vm.Executor, error)) {
 	sm.newVM = nvm
 }
 
-func (sm *StateManager) VMConstructor() func(context.Context, *vm.VMOpts) (vm.Interface, error) {
-	return func(ctx context.Context, opts *vm.VMOpts) (vm.Interface, error) {
+func (sm *StateManager) VMConstructor() func(context.Context, *vm.VMOpts) (vm.Executor, error) {
+	return func(ctx context.Context, opts *vm.VMOpts) (vm.Executor, error) {
 		return sm.newVM(ctx, opts)
 	}
 }
diff --git a/conformance/driver.go b/conformance/driver.go
index e0d56d074..c3041be71 100644
--- a/conformance/driver.go
+++ b/conformance/driver.go
@@ -158,7 +158,7 @@ func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, params
 		results:  []*vm.ApplyRet{},
 	}
 
-	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
+	sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Executor, error) {
 		vmopt.CircSupplyCalc = func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) {
 			return big.Zero(), nil
 		}