wazeroir: less allocations with Labels (#1141)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
@@ -45,19 +45,18 @@ func (c *controlFrame) ensureContinuation() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controlFrame) asBranchTarget() *BranchTarget {
|
||||
func (c *controlFrame) asLabel() Label {
|
||||
switch c.kind {
|
||||
case controlFrameKindBlockWithContinuationLabel,
|
||||
controlFrameKindBlockWithoutContinuationLabel:
|
||||
return &BranchTarget{Label: &Label{FrameID: c.frameID, Kind: LabelKindContinuation}}
|
||||
return Label{FrameID: c.frameID, Kind: LabelKindContinuation}
|
||||
case controlFrameKindLoop:
|
||||
return &BranchTarget{Label: &Label{FrameID: c.frameID, Kind: LabelKindHeader}}
|
||||
return Label{FrameID: c.frameID, Kind: LabelKindHeader}
|
||||
case controlFrameKindFunction:
|
||||
// Note nil target is translated as return.
|
||||
return &BranchTarget{Label: nil}
|
||||
return Label{Kind: LabelKindReturn}
|
||||
case controlFrameKindIfWithElse,
|
||||
controlFrameKindIfWithoutElse:
|
||||
return &BranchTarget{Label: &Label{FrameID: c.frameID, Kind: LabelKindContinuation}}
|
||||
return Label{FrameID: c.frameID, Kind: LabelKindContinuation}
|
||||
}
|
||||
panic(fmt.Sprintf("unreachable: a bug in wazeroir implementation: %v", c.kind))
|
||||
}
|
||||
@@ -469,13 +468,13 @@ operatorSwitch:
|
||||
c.controlFrames.push(frame)
|
||||
|
||||
// Prep labels for inside and the continuation of this loop.
|
||||
loopLabel := &Label{FrameID: frame.frameID, Kind: LabelKindHeader}
|
||||
loopLabel := Label{FrameID: frame.frameID, Kind: LabelKindHeader}
|
||||
c.result.LabelCallers[loopLabel.String()]++
|
||||
|
||||
// Emit the branch operation to enter inside the loop.
|
||||
c.emit(
|
||||
OperationBr{
|
||||
Target: loopLabel.asBranchTarget(),
|
||||
Target: loopLabel,
|
||||
},
|
||||
OperationLabel{Label: loopLabel},
|
||||
)
|
||||
@@ -516,8 +515,8 @@ operatorSwitch:
|
||||
c.controlFrames.push(frame)
|
||||
|
||||
// Prep labels for if and else of this if.
|
||||
thenLabel := &Label{Kind: LabelKindHeader, FrameID: frame.frameID}
|
||||
elseLabel := &Label{Kind: LabelKindElse, FrameID: frame.frameID}
|
||||
thenLabel := Label{Kind: LabelKindHeader, FrameID: frame.frameID}
|
||||
elseLabel := Label{Kind: LabelKindElse, FrameID: frame.frameID}
|
||||
c.result.LabelCallers[thenLabel.String()]++
|
||||
c.result.LabelCallers[elseLabel.String()]++
|
||||
|
||||
@@ -551,7 +550,7 @@ operatorSwitch:
|
||||
|
||||
// We are no longer unreachable in else frame,
|
||||
// so emit the correct label, and reset the unreachable state.
|
||||
elseLabel := &Label{FrameID: frame.frameID, Kind: LabelKindElse}
|
||||
elseLabel := Label{FrameID: frame.frameID, Kind: LabelKindElse}
|
||||
c.resetUnreachable()
|
||||
c.emit(
|
||||
OperationLabel{Label: elseLabel},
|
||||
@@ -576,8 +575,8 @@ operatorSwitch:
|
||||
}
|
||||
|
||||
// Prep labels for else and the continuation of this if block.
|
||||
elseLabel := &Label{FrameID: frame.frameID, Kind: LabelKindElse}
|
||||
continuationLabel := &Label{FrameID: frame.frameID, Kind: LabelKindContinuation}
|
||||
elseLabel := Label{FrameID: frame.frameID, Kind: LabelKindElse}
|
||||
continuationLabel := Label{FrameID: frame.frameID, Kind: LabelKindContinuation}
|
||||
c.result.LabelCallers[continuationLabel.String()]++
|
||||
|
||||
// Emit the instructions for exiting the if loop,
|
||||
@@ -585,7 +584,7 @@ operatorSwitch:
|
||||
c.emit(
|
||||
dropOp,
|
||||
// Jump to the continuation of this block.
|
||||
OperationBr{Target: continuationLabel.asBranchTarget()},
|
||||
OperationBr{Target: continuationLabel},
|
||||
// Initiate the else block.
|
||||
OperationLabel{Label: elseLabel},
|
||||
)
|
||||
@@ -606,14 +605,14 @@ operatorSwitch:
|
||||
c.stackPush(wasmValueTypeToUnsignedType(t))
|
||||
}
|
||||
|
||||
continuationLabel := &Label{FrameID: frame.frameID, Kind: LabelKindContinuation}
|
||||
continuationLabel := Label{FrameID: frame.frameID, Kind: LabelKindContinuation}
|
||||
if frame.kind == controlFrameKindIfWithoutElse {
|
||||
// Emit the else label.
|
||||
elseLabel := &Label{Kind: LabelKindElse, FrameID: frame.frameID}
|
||||
elseLabel := Label{Kind: LabelKindElse, FrameID: frame.frameID}
|
||||
c.result.LabelCallers[continuationLabel.String()]++
|
||||
c.emit(
|
||||
OperationLabel{Label: elseLabel},
|
||||
OperationBr{Target: continuationLabel.asBranchTarget()},
|
||||
OperationBr{Target: continuationLabel},
|
||||
OperationLabel{Label: continuationLabel},
|
||||
)
|
||||
} else {
|
||||
@@ -647,30 +646,29 @@ operatorSwitch:
|
||||
// Return from function.
|
||||
c.emit(
|
||||
dropOp,
|
||||
// Pass empty target instead of nil to avoid misinterpretation as "return"
|
||||
OperationBr{Target: &BranchTarget{}},
|
||||
OperationBr{Target: Label{Kind: LabelKindReturn}},
|
||||
)
|
||||
case controlFrameKindIfWithoutElse:
|
||||
// This case we have to emit "empty" else label.
|
||||
elseLabel := &Label{Kind: LabelKindElse, FrameID: frame.frameID}
|
||||
continuationLabel := &Label{Kind: LabelKindContinuation, FrameID: frame.frameID}
|
||||
elseLabel := Label{Kind: LabelKindElse, FrameID: frame.frameID}
|
||||
continuationLabel := Label{Kind: LabelKindContinuation, FrameID: frame.frameID}
|
||||
c.result.LabelCallers[continuationLabel.String()] += 2
|
||||
c.emit(
|
||||
dropOp,
|
||||
OperationBr{Target: continuationLabel.asBranchTarget()},
|
||||
OperationBr{Target: continuationLabel},
|
||||
// Emit the else which soon branches into the continuation.
|
||||
OperationLabel{Label: elseLabel},
|
||||
OperationBr{Target: continuationLabel.asBranchTarget()},
|
||||
OperationBr{Target: continuationLabel},
|
||||
// Initiate the continuation.
|
||||
OperationLabel{Label: continuationLabel},
|
||||
)
|
||||
case controlFrameKindBlockWithContinuationLabel,
|
||||
controlFrameKindIfWithElse:
|
||||
continuationLabel := &Label{Kind: LabelKindContinuation, FrameID: frame.frameID}
|
||||
continuationLabel := Label{Kind: LabelKindContinuation, FrameID: frame.frameID}
|
||||
c.result.LabelCallers[continuationLabel.String()]++
|
||||
c.emit(
|
||||
dropOp,
|
||||
OperationBr{Target: continuationLabel.asBranchTarget()},
|
||||
OperationBr{Target: continuationLabel},
|
||||
OperationLabel{Label: continuationLabel},
|
||||
)
|
||||
case controlFrameKindLoop, controlFrameKindBlockWithoutContinuationLabel:
|
||||
@@ -697,8 +695,8 @@ operatorSwitch:
|
||||
targetFrame := c.controlFrames.get(int(targetIndex))
|
||||
targetFrame.ensureContinuation()
|
||||
dropOp := OperationDrop{Depth: c.getFrameDropRange(targetFrame, false)}
|
||||
target := targetFrame.asBranchTarget()
|
||||
c.result.LabelCallers[target.Label.String()]++
|
||||
target := targetFrame.asLabel()
|
||||
c.result.LabelCallers[target.String()]++
|
||||
c.emit(
|
||||
dropOp,
|
||||
OperationBr{Target: target},
|
||||
@@ -722,14 +720,14 @@ operatorSwitch:
|
||||
targetFrame := c.controlFrames.get(int(targetIndex))
|
||||
targetFrame.ensureContinuation()
|
||||
drop := c.getFrameDropRange(targetFrame, false)
|
||||
target := targetFrame.asBranchTarget()
|
||||
c.result.LabelCallers[target.Label.String()]++
|
||||
target := targetFrame.asLabel()
|
||||
c.result.LabelCallers[target.String()]++
|
||||
|
||||
continuationLabel := &Label{FrameID: c.nextID(), Kind: LabelKindHeader}
|
||||
continuationLabel := Label{FrameID: c.nextID(), Kind: LabelKindHeader}
|
||||
c.result.LabelCallers[continuationLabel.String()]++
|
||||
c.emit(
|
||||
OperationBrIf{
|
||||
Then: &BranchTargetDrop{ToDrop: drop, Target: target},
|
||||
Then: BranchTargetDrop{ToDrop: drop, Target: target},
|
||||
Else: continuationLabel.asBranchTargetDrop(),
|
||||
},
|
||||
// Start emitting else block operations.
|
||||
@@ -770,9 +768,9 @@ operatorSwitch:
|
||||
targetFrame := c.controlFrames.get(int(l))
|
||||
targetFrame.ensureContinuation()
|
||||
drop := c.getFrameDropRange(targetFrame, false)
|
||||
target := &BranchTargetDrop{ToDrop: drop, Target: targetFrame.asBranchTarget()}
|
||||
target := &BranchTargetDrop{ToDrop: drop, Target: targetFrame.asLabel()}
|
||||
targets[i] = target
|
||||
c.result.LabelCallers[target.Target.Label.String()]++
|
||||
c.result.LabelCallers[target.Target.String()]++
|
||||
}
|
||||
|
||||
// Prep default target control frame.
|
||||
@@ -784,8 +782,8 @@ operatorSwitch:
|
||||
defaultTargetFrame := c.controlFrames.get(int(l))
|
||||
defaultTargetFrame.ensureContinuation()
|
||||
defaultTargetDrop := c.getFrameDropRange(defaultTargetFrame, false)
|
||||
defaultTarget := defaultTargetFrame.asBranchTarget()
|
||||
c.result.LabelCallers[defaultTarget.Label.String()]++
|
||||
defaultTarget := defaultTargetFrame.asLabel()
|
||||
c.result.LabelCallers[defaultTarget.String()]++
|
||||
|
||||
c.emit(
|
||||
OperationBrTable{
|
||||
@@ -806,7 +804,7 @@ operatorSwitch:
|
||||
// Cleanup the stack and then jmp to function frame's continuation (meaning return).
|
||||
c.emit(
|
||||
dropOp,
|
||||
OperationBr{Target: functionFrame.asBranchTarget()},
|
||||
OperationBr{Target: functionFrame.asLabel()},
|
||||
)
|
||||
|
||||
// Return operation is stack-polymorphic, and mark the state as unreachable.
|
||||
|
||||
Reference in New Issue
Block a user