What happened to CompiledMethod>>#numLiterals in Spur?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

What happened to CompiledMethod>>#numLiterals in Spur?

Chris Muller-4
Hi Eliot and all, while moving some serialized objects from a Cog
image into a Spur image, I am encountered an issue materializaing a
CompiledMethod instance in the target Spur image due to the new
implementation of #numLiterals.  In Cog it's:

     numLiterals
          "Answer the number of literals used by the receiver."
          | header |
          ^(header := self header) < 0
               ifTrue: [header bitAnd: 65535]
               ifFalse: [(header bitShift: -9) bitAnd: 16rFF]

but in Spur, only the negative header condition is present:

     numLiterals
          "Answer the number of literals used by the receiver."
          ^self header bitAnd: 65535

The header was positive in the source Cog image, in fact, there are NO
instances of CM's with negative headers in either my Cog or Spur
images.  So after constructing the CompiledMethod for materialization
within the Spur image with the same #header it had in Cog, it reports
the wrong #numLiterals and can't finish the materialization because of
that.

I'm able to force a correct materialization by changing the place
where I access "numLiterals" to the original True condition of Cog --
"(header bitShift: -9) bitAnd: 16rFF".

But that's just "making it work" and not understanding the
implications of what I'm doing.  I know Spur can allow more literals
per CM, but assuming I'm willing to stay with a max of just 255
literals for now, is my override above the best way to handle this
need to be able to transfer objects back-and-forth within a
heterogeneous environment of Cog and Spur images?

Thanks for any advice and insight..

Reply | Threaded
Open this post in threaded view
|

Re: What happened to CompiledMethod>>#numLiterals in Spur?

Chris Muller-4
> where I access "numLiterals" to the original True condition of Cog --

.. to the original *False* condition of Cog -- ...

Reply | Threaded
Open this post in threaded view
|

Re: What happened to CompiledMethod>>#numLiterals in Spur?

Eliot Miranda-2
In reply to this post by Chris Muller-4
Hi Chris,

On Thu, Nov 13, 2014 at 12:24 PM, Chris Muller <[hidden email]> wrote:
Hi Eliot and all, while moving some serialized objects from a Cog
image into a Spur image, I am encountered an issue materializaing a
CompiledMethod instance in the target Spur image due to the new
implementation of #numLiterals.  In Cog it's:

     numLiterals
          "Answer the number of literals used by the receiver."
          | header |
          ^(header := self header) < 0
               ifTrue: [header bitAnd: 65535]
               ifFalse: [(header bitShift: -9) bitAnd: 16rFF]

but in Spur, only the negative header condition is present:

     numLiterals
          "Answer the number of literals used by the receiver."
          ^self header bitAnd: 65535

Right.

The header was positive in the source Cog image, in fact, there are NO
instances of CM's with negative headers in either my Cog or Spur
images.  So after constructing the CompiledMethod for materialization
within the Spur image with the same #header it had in Cog, it reports
the wrong #numLiterals and can't finish the materialization because of
that.

Right.

I'm able to force a correct materialization by changing the place
where I access "numLiterals" to the original True condition of Cog --
"(header bitShift: -9) bitAnd: 16rFF".

Good.  That is the "right thing to do" (tm).  Or rather it is the right thing to do when trying to import methods from Cog to Spur.

But that's just "making it work" and not understanding the
implications of what I'm doing.  I know Spur can allow more literals
per CM, but assuming I'm willing to stay with a max of just 255
literals for now, is my override above the best way to handle this
need to be able to transfer objects back-and-forth within a
heterogeneous environment of Cog and Spur images?

Yes, as long as it is on;y used for porting.  You obviously /don'/ need it when materializing in Spur methods that have been dematerialized in Spur (BTW, I like the "official" terms, "pickled" and "unpickled").

Thanks for any advice and insight..

So the new format was introduced to lift the limit on the number of literals.  I first implemented it for Newspeak a couple of years ago for Cadence.  At this point it used the sign bit to allow both the old and new header formats to coexist:

 numLiterals
          "Answer the number of literals used by the receiver."
          | header |
          ^(header := self header) < 0
               ifTrue: [header bitAnd: 65535]
               ifFalse: [(header bitShift: -9) bitAnd: 16rFF]


The problems with this are
- that sign bit allows choosing between bytecode sets, and so it couples bytecode set choice with literal limit, and
- there is a cost, at least in code density, even if not necessarily much in performance, in the VM using the "mixed" format.

I realised in late summer with Spur that I had a chance of eliminating the coupling and performance issues by insisting on the one format in Spur.  So I decided to eliminate the old format and just go with the simple format (this taken from CompiledMethod's class comment in its Spur version):

The header is a 31-bit signed integer (a SmallInteger) in the following format:

(index 0) 16 bits: number of literals (#numLiterals)
(index 16)  1 bit: has primitive
(index 17)  1 bit: whether a large frame size is needed (#frameSize => either SmallFrame or LargeFrame)
(index 18)  6 bits: number of temporary variables (#numTemps)
(index 24)  4 bits: number of arguments to the method (#numArgs)
(index 28)  2 bits: reserved for an access modifier (00-unused, 01-private, 10-protected, 11-public), although accessors for bit 29 exist (see #flag).
(index 30/63) sign bit: 1 selects the Secondary instruction set (e.g. NewsqueakV4, 0 selects the primary instruction set, e.g. SqueakV3PlusClosures) (#signFlag)

This a) makes the VM slimmer and b) makes it much less complicated to use the two bytecode sets.  The ability to use two bytecode sets provides a smoother transition to Sista when it arrives next year.
--
best,
Eliot