[Vm-dev] VM Maker Inbox: BytecodeSets.spur-eem.81.mcz

Marcel Taeumel marcel.taeumel at hpi.de
Fri Apr 8 13:53:23 UTC 2022


Hi Eliot, hi all --

What's the current use of this Inbox proposal? We have ImplicitLiteralInstructionClientHook in Trunk at the moment.

Should we merge BytecodeSets.spur-eem.81 ?

Best,
Marcel
Am 13.09.2021 07:20:42 schrieb commits at source.squeak.org <commits at source.squeak.org>:

Eliot Miranda uploaded a new version of BytecodeSets to project VM Maker Inbox:
http://source.squeak.org/VMMakerInbox/BytecodeSets.spur-eem.81.mcz

==================== Summary ====================

Name: BytecodeSets.spur-eem.81
Author: eem
Time: 12 September 2021, 10:20:31.001161 pm
UUID: d4391f21-0790-4132-9ae4-97941c8e3809
Ancestors: BytecodeSets.spur-eem.80

Proposed fix for CompiledCode>>#allLiteralsDo: by adding pushSpecialConstant:/sendSpecial:numArgs:.

=============== Diff against BytecodeSets.spur-eem.80 ===============

Item was changed:
----- Method: InstructionStream>>interpretNSV4ExtendedPush:for: (in category '*BytecodeSets-NewsqueakV4-decoding') -----
interpretNSV4ExtendedPush: extB for: client
"Implement the extended push for non-zero extensions."
"77 01001101 Push false [* 1:true, 2:nil, 3:thisContext, ..., -N: pushExplicitOuter: N, N = Extend B]"
extB < 0 ifTrue:
[^client pushExplicitOuter: extB negated].
extB < 2 ifTrue:
+ [^client pushSpecialConstant: extB = 1].
- [^client pushConstant: extB = 1].
extB = 2 ifTrue:
+ [^client pushSpecialConstant: nil].
- [^client pushConstant: nil].
extB = 3 ifTrue:
[^client pushActiveContext].
self error: 'undefined extended push'!

Item was changed:
----- Method: InstructionStream>>interpretNext2ByteNSV4Instruction:for:extA:extB:startPC: (in category '*BytecodeSets-NewsqueakV4-decoding') -----
interpretNext2ByteNSV4Instruction: bytecode for: client extA: extA extB: extB startPC: startPC
"Send to the argument, client, a message that specifies the next instruction.
This method handles the two-byte codes.
For a table of the bytecode set, see EncoderForNewsqueakV4's class comment."

| byte method |
method := self method.
byte := self method at: pc.
pc := pc + 1.
"We do an inline quasi-binary search on bytecode"
bytecode < 235 ifTrue:
[bytecode < 231 ifTrue:
[bytecode < 229 ifTrue:
[| literal |
bytecode = 226 ifTrue:
[^client pushReceiverVariable: (extA bitShift: 8) + byte].
literal := method literalAt: (extA bitShift: 8) + byte + 1.
bytecode = 227 ifTrue:
[^client pushLiteralVariable: literal].
^client pushConstant: literal].
bytecode = 229 ifTrue:
+ [^client pushSpecialConstant: (extB bitShift: 8) + byte].
- [^client pushConstant: (extB bitShift: 8) + byte].
^client pushTemporaryVariable: byte].
bytecode = 231 ifTrue:
[^byte < 128
ifTrue: [client pushNewArrayOfSize: byte]
ifFalse: [client pushConsArrayWithElements: byte - 128]].
bytecode = 232 ifTrue:
[^client storeIntoReceiverVariable: (extA bitShift: 8) + byte].
bytecode = 233 ifTrue:
[^client storeIntoLiteralVariable: (method literalAt: (extA bitShift: 8) + byte + 1)].
^client storeIntoTemporaryVariable: byte].
bytecode < 238 ifTrue:
[bytecode = 235 ifTrue:
[^client popIntoReceiverVariable: (extA bitShift: 8) + byte].
bytecode = 236 ifTrue:
[^client popIntoLiteralVariable: (method literalAt: (extA bitShift: 8) + byte + 1)].
^client popIntoTemporaryVariable: byte].
bytecode < 242 ifTrue:
[| selector numArgs |
selector := method literalAt: (extA bitShift: 5) + (byte // 8) + 1.
numArgs := (extB bitShift: 3) + (byte \\ 8).
bytecode = 238 ifTrue:
[^client send: selector super: false numArgs: numArgs].
bytecode = 239 ifTrue:
[^client send: selector super: true numArgs: numArgs].
bytecode = 240 ifTrue:
[^client sendToAbsentImplicitReceiver: selector numArgs: numArgs].
^client sendToAbsentDynamicSuperclass: selector numArgs: numArgs].
bytecode < 245 ifTrue:
[bytecode = 242 ifTrue:
[^client jump: (extB bitShift: 8) + byte].
^client jump: (extB bitShift: 8) + byte if: bytecode = 243].
bytecode = 245 ifTrue:
[| selector numArgs |
selector := method literalAt: (extA bitShift: 5) + (byte // 8) + 1.
numArgs := (extB bitShift: 3) + (byte \\ 8).
^client sendToAbsentSelf: selector numArgs: numArgs].
"246-247 1111011 i xxxxxxxx UNASSIGNED
248-249 1111100 i xxxxxxxx UNASSIGNED"
^self unusedBytecode: client at: startPC!

Item was changed:
----- Method: InstructionStream>>interpretNextNSV3InstructionFor: (in category '*BytecodeSets-NewsqueakV3-decoding') -----
interpretNextNSV3InstructionFor: client
"Send to the argument, client, a message that specifies the type of the
next instruction."

| byte type offset method |
method := self method.
byte := method at: pc.
type := byte // 16.
offset := byte \\ 16.
pc := pc+1.
"We do an inline binary search on each of the possible 16 values of type."
type < 8 ifTrue:
[type < 4 ifTrue:
[type < 2 ifTrue:
[type = 0 ifTrue:
[^ client pushReceiverVariable: offset].
^ client pushTemporaryVariable: offset]. "type = 1"
type = 2 ifTrue:
[^ client pushConstant: (method literalAt: offset + 1)].
^ client pushConstant: (method literalAt: offset + 17)]. "type = 3"
type < 6 ifTrue:
[type = 4 ifTrue:
[^ client pushLiteralVariable: (method literalAt: offset + 1)].
^ client pushLiteralVariable: (method literalAt: offset + 17)]."type = 5"
type = 6 ifTrue:
[offset < 8 ifTrue:
[^ client popIntoReceiverVariable: offset].
^ client popIntoTemporaryVariable: offset - 8].
"type = 7"
offset = 0 ifTrue: [^ client pushReceiver].
+ offset < 8 ifTrue: [^ client pushSpecialConstant: (SpecialConstants at: offset)].
- offset < 8 ifTrue: [^ client pushConstant: (SpecialConstants at: offset)].
offset = 8 ifTrue: [^ client methodReturnReceiver].
offset < 12 ifTrue: [^ client methodReturnConstant: (SpecialConstants at: offset - 8)].
offset = 12 ifTrue: [^ client methodReturnTop].
offset = 13 ifTrue: [^ client blockReturnTop].
offset = 14 ifTrue:
[| byte2 |
byte := method at: pc.
pc := pc+1.
byte2 := method at: pc.
pc := pc+1.
^ client sendToDynamicSuperclass: (method literalAt: byte2 + 1) numArgs: byte].
"offset = 15"
byte := method at: pc.
pc := pc+1.
^ client pushImplicitReceiverForMessage: (method literalAt: byte + 1)].
type < 12 ifTrue:
[type < 10 ifTrue:
[type = 8 ifTrue:
[^ self
interpretNSV3Extension: offset
in: method
for: client].
"type = 9 (short jumps)"
offset < 8 ifTrue: [^ client jump: offset + 1].
^ client jump: offset - 8 + 1 if: false].
type = 10 ifTrue: "(long jumps)"
[byte := method at: pc.
pc := pc + 1.
offset < 8 ifTrue: [^ client jump: offset - 4 * 256 + byte].
^ client jump: (offset bitAnd: 3) * 256 + byte if: offset < 12].
"type = 11; arithmetic special selector sends"
^ client
+ sendSpecial: (Smalltalk specialSelectorAt: offset + 1)
- send: (Smalltalk specialSelectorAt: offset + 1)
- super: false
numArgs: (Smalltalk specialNargsAt: offset + 1)].
type = 12 ifTrue: "non-arithmetic special selector sends"
[^ client
+ sendSpecial: (Smalltalk specialSelectorAt: offset + 17)
- send: (Smalltalk specialSelectorAt: offset + 17)
- super: false
numArgs: (Smalltalk specialNargsAt: offset + 17)].
"type = 13, 14 or 15"
^ client
send: (method literalAt: offset + 1)
super: false
numArgs: type - 13 "0, 1 & 2"!

Item was changed:
----- Method: InstructionStream>>interpretNextNSV4InstructionFor: (in category '*BytecodeSets-NewsqueakV4-decoding') -----
interpretNextNSV4InstructionFor: client
"Send to the argument, client, a message that specifies the next instruction."

| byte div16 offset method extA extB savedPC |
method := self method.
"For a table of the bytecode set, see EncoderForNewsqueakV4's class comment."
"consume and compute any extensions first."
extA := extB := 0.
savedPC := pc.
[byte := self method at: pc.
pc := pc + 1.
byte >= 224 and: [byte <= 225]] whileTrue:
[| extByte |
extByte := self method at: pc.
pc := pc + 1.
byte = 224
ifTrue:
[extA := (extA bitShift: 8) + extByte]
ifFalse:
[extB := (extB = 0 and: [extByte > 127])
ifTrue: [extByte - 256]
ifFalse: [(extB bitShift: 8) + extByte]]].
div16 := byte // 16.
offset := byte \\ 16.
"We do an inline quasi-binary search on each of the possible 16 values of div16"
div16 < 12 ifTrue:
[div16 < 4 ifTrue:
[div16 < 2 ifTrue:
[div16 = 0 ifTrue:
[^client pushReceiverVariable: offset].
^client pushLiteralVariable: (method literalAt: offset + 1)]. "div16 = 1"
^client pushConstant: (method literalAt: byte \\ 32 + 1)].
div16 = 4 ifTrue:
[offset < 12 ifTrue:
[^client pushTemporaryVariable: offset].
offset < 14 ifTrue:
[offset = 12 ifTrue:
[^client pushReceiver].
extB = 0 ifTrue:
+ [^client pushSpecialConstant: false].
- [^client pushConstant: false].
^self interpretNSV4ExtendedPush: extB for: client].
+ ^client pushSpecialConstant: offset - 14]. "0 & 1"
- ^client pushConstant: offset - 14]. "0 & 1"
"short sends"
div16 < 7 ifTrue: "special selector sends"
[div16 = 5 ifTrue:
[^client
+ sendSpecial: (Smalltalk specialSelectorAt: offset + 1)
- send: (Smalltalk specialSelectorAt: offset + 1)
- super: false
numArgs: (Smalltalk specialNargsAt: offset + 1)].
^client
+ sendSpecial: (Smalltalk specialSelectorAt: offset + 17)
- send: (Smalltalk specialSelectorAt: offset + 17)
- super: false
numArgs: (Smalltalk specialNargsAt: offset + 17)].
div16 < 10 ifTrue: "vanilla sends, div16 = 7, 8 & 9"
[^client
send: (method literalAt: offset + 1)
super: false
numArgs: div16 - 7].
"implicit receiver send, div16 = 10"
div16 = 10 ifTrue:
[^client
sendToAbsentImplicitReceiver: (method literalAt: offset + 1)
numArgs: 0].
"short store pops"
offset < 8 ifTrue:
[^client popIntoReceiverVariable: offset].
^client popIntoTemporaryVariable: offset - 8].
"div16 >= 12"
div16 < 14 ifTrue:
[div16 = 12 ifTrue:
[offset < 8 ifTrue:
[^client jump: offset + 1].
^client jump: offset - 7 if: true].
offset < 8 ifTrue:
[^client jump: offset + 1 if: false].
offset < 11 ifTrue:
[offset = 8 ifTrue: [^client methodReturnReceiver].
offset = 9 ifTrue: [^client methodReturnTop].
extA > 0 ifTrue:
[^client blockReturnTopFromLevel: extA].
^client blockReturnTop].
offset = 11 ifTrue:
[^client doDup].
offset = 12 ifTrue:
[^client doPop].
offset = 13 ifTrue:
[^client doNop].
"222 11011110 break ? could have blockCopy: send break, but need a receiver and a pop result"
"223 11011111 UNASSIGNED"
^self unusedBytecode: client at: savedPC].
"2 byte and 3 byte codes"
byte < 249 ifTrue:
[^self interpretNext2ByteNSV4Instruction: byte for: client extA: extA extB: extB startPC: savedPC].
^self interpretNext3ByteNSV4Instruction: byte for: client extA: extA extB: extB startPC: savedPC!

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20220408/c5e3e131/attachment-0001.html>


More information about the Vm-dev mailing list