[Vm-dev] [SqueakJS] Faster JIT ideas

Florin Mateoc florin.mateoc at gmail.com
Mon Mar 15 01:27:56 UTC 2021


I almost forgot: this is how my console looks like when trying to start via
Chrome


   - MemoryInfo {totalJSHeapSize: 2685131, usedJSHeapSize: 1667135,
   jsHeapSizeLimit: 4294705152}

startupBrowser.mjs:23
Loading initial glue code
startupBrowser.mjs:26
Loading translated Squeak image 4.5
startupBrowser.mjs:29
Loading generated classes (all the code, plus minimal reflection data)
startupBrowser.mjs:34
Elapsed 42074ms
startupBrowser.mjs:36
Loading manual overrides for the generated code
startupBrowser.mjs:39
Loading more glue code
startupBrowser.mjs:43

   - MemoryInfo {totalJSHeapSize: 195878416, usedJSHeapSize: 176798312,
   jsHeapSizeLimit: 4294705152}

startupBrowser.mjs:44
Loading serialized image state
SmalltalkGlobals.js:254
reified compiledMethod for method _notEqEq of class _ProtoObject has not
been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _eqEq of class _ProtoObject has not been
set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _class of class _Object has not been set
up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _lookup_ of class _Symbol class has not
been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _rehash of class _Symbol class has not
been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _allSymbolTablesDo_ of class _Symbol
class has not been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _compactSymbolTable of class _Symbol
class has not been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _allSymbols of class _Symbol class has
not been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _allSymbolTablesDo_after_ of class
_Symbol class has not been set up, the method might be a manual JavaScript
override
SmalltalkGlobals.js:254
reified compiledMethod for method _intern_ of class _Symbol class has not
been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _minVal of class _SmallInteger class has
not been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _maxVal of class _SmallInteger class has
not been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _installLowSpaceWatcher of class
_SmalltalkImage has not been set up, the method might be a manual
JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _signal of class _Exception has not been
set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _return_ of class _Exception has not been
set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _resumeUnchecked_ of class _Exception has
not been set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _pass of class _Exception has not been
set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _retry of class _Exception has not been
set up, the method might be a manual JavaScript override
SmalltalkGlobals.js:254
reified compiledMethod for method _outer of class _Exception has not been
set up, the method might be a manual JavaScript override
startupBrowser.mjs:47
Elapsed 105913ms
startupBrowser.mjs:49

   - MemoryInfo {totalJSHeapSize: 462667346, usedJSHeapSize: 438684470,
   jsHeapSizeLimit: 4294705152}

startupBrowser.mjs:51

   - MemoryInfo {totalJSHeapSize: 453213778, usedJSHeapSize: 373908346,
   jsHeapSizeLimit: 4294705152}

startupBrowser.mjs:52
Loading VM/scheduler
SmalltalkVM.js:81
cleaning up
SmalltalkVM.js:141

   - MemoryInfo {totalJSHeapSize: 409552989, usedJSHeapSize: 371929977,
   jsHeapSizeLimit: 4294705152}

SmalltalkVM.js:146

   - MemoryInfo {totalJSHeapSize: 409815133, usedJSHeapSize: 371860153,
   jsHeapSizeLimit: 4294705152}

SmalltalkVM.js:177
setting up the scheduler loop
SmalltalkVM.js:195
start known processes
SmalltalkVM.js:196
_Delay._startTimerEventLoop
SmalltalkVM.js:199
_Delay._startUp_(true)
SmalltalkVM.js:201
_ProcessorScheduler._startUp_(true)
SmalltalkVM.js:203
_WeakArray._startUp_(true)
SmalltalkVM.js:205
finished starting non-UI known processes
startUI_browser.mjs:25
starting EventSensor
startUI_browser.mjs:27
spawning primordial UI process
SmalltalkVM.js:180
entering new active process with priority 80
SmalltalkVM.js:184
primitive 86 semaphore wait
SmalltalkVM.js:180
entering new active process with priority 60
SmalltalkVM.js:184
primitive 86 semaphore wait
SmalltalkVM.js:180
entering new active process with priority 60
SmalltalkVM.js:184
primitive 85 semaphore signal
SmalltalkVM.js:180
entering new active process with priority 80
SmalltalkVM.js:184
primitive 86 semaphore wait
SmalltalkVM.js:180
entering new active process with priority 60
SmalltalkVM.js:184
primitive 86 semaphore wait
SmalltalkVM.js:180
entering new active process with priority 50
SmalltalkVM.js:184
primitive 86 semaphore wait
SmalltalkVM.js:180
entering new active process with priority 40
_DisplayScreen.js:843
Uncaught TypeError: Cannot read property 'width' of undefined

On Sun, Mar 14, 2021 at 9:18 PM Florin Mateoc <florin.mateoc at gmail.com>
wrote:

> Hi Vanessa,
>
> Sorry for the delay in responding - as somebody who has been inspired by
> your SqueakJS project, I think I should mention that I am working on a
> related project, for now tentatively called JsSqueak.
> In addition to the inspiration provided by SqueakJS, it also scratches my
> longstanding itch about compiling (transpiling) Squeak.
>
> I hesitated to talk about it, as it is still a work in progress - after
> small bits and pieces that I worked on over a long period, I had the
> opportunity to spend a significant and uninterrupted chunk of time on it
> last summer, when I was unemployed for 3 months, and I was able to make
> good progress. I was optimistically thinking of releasing a first version
> before the end of last year, but after I started working on my new job,
> progress on JsSqueak has slowed down significantly. I must confess that I
> (and especially my wife) hesitate in recreating that productive unemployed
> situation :)
>
> I started with Squeak 4.5 - I already had code transforming Smalltalk code
> to a form more suitable for translation - and I also started with
> VMMakerJS-dtl.18 for the plugin generation part. Of course, I had to
> heavily modify it, since I have to get rid of the stack usage for
> arguments/receiver and returns.
> Both of these big parts are working. I also implemented most numbered
> primitives by hand - they are inlined at generation time in the methods
> calling them.
> I am also taking advantage of the latest and greatest additions to
> JavaScript. I am, of course, using classes, and the parallel class-side
> hierarchy is implemented using statics. To implement green threads/process
> switching, all translated methods are implemented as generator functions,
> and all calls are through yield* expressions. The preemption/interrupt
> check points are inlined. With this, a process switch is achieved by simply
> yield-ing (in the process/semaphore primitives).
> With this, the Integer>>#benchFib method is translated (as a method in
> Number.prototype, there is one more, simpler, implementation in BigInt) as:
>
> *_benchFib() {
>    if (Number.isSafeInteger(this.valueOf())) { // Effective (inherited or local) source for #benchFib in SmallInteger
>       /*Handy send-heavy benchmark*/
>    /*(result // seconds to run) = approx calls per second*/
>    /* | r t |
>      t := Time millisecondsToRun: [r := 26 benchFib].
>      (r // 1000) // t*/
>    /*138000 on a Mac 8100//100*/
>    if (GlobalActivationCounter-- < 0) yield* GlobalCheckForInterrupts();
>
>    return (yield* this._lt( 2)).booleanValueOf("questionMark:colon:") ? (1) : (yield* (yield* (yield* (yield* this._sub( 1))._benchFib())._add( yield* (yield* this._sub( 2))._benchFib()))._add( 1));
> } else // No implementation for #benchFib in Float hierarchy, trigger a DNU
>       return yield* super._benchFib()
> }
>
> The top-level check for smallIntegers is because both SmallInteger and Float are mapped to Number.
>
> The booleanValueOf call is for implementing the mustBeBoolean machinery (it actually translates directly to DNU, like it is done nowadays in Squeak).
>
> Of course, in Boolean, booleanValueOf is just an alias for valueOf
>
> As you can see, though, this is not terribly efficient, but there is room for improvement/optimizations. With more work, in this case, the _lt call could be replaced by the < operator, and even the _sub and _add calls could be optimized,
> although not completely, since their result can morph into LargeInteger (mapped to BigInt).
>
> As hinted above, SmallInteger is mapped to Number (in the safeInteger range), Float is mapped to Number as well, and LargeInteger is mapped to BigInt.
>
> BlockClosure is mapped to Function, Boolean is mapped to Boolean, Character is mapped to String, weak references are implemented via WeakRef.
> I have briefly considered also doing slightly higher-level mappings, for IdentitySet to Set and IdentityDictionary to Map, but this is not a priority.
>
> The image is serialized sort of like a JavaScript storeString. No processes or contexts though, or rather they are not brought back in on the JavaScript side. Blocks are both stored and loaded.
>
> Non-local returns, unwind blocks, resumable and restartable exceptions are implemented via JavaScript exception handling plus explicit handler block chains associated with the processes.
>
> The "image" starts with the global state loaded, but all processes are started from scratch instead of resumed. A non-UI image is thus trivially started.
>
> One major todo left is hooking up the UI/browser. I did take vm.display.browser.js from SqueakJS and adapted the code in order to implement its numbered primitives, but I still have to work through squeak.js from the same to initialize
> and hook up the display.
>
> Florin
>
>
>
>
> On Sun, Mar 7, 2021 at 11:17 PM Vanessa Freudenberg <vanessa at codefrau.net>
> wrote:
>
>>
>> Hi all,
>>
>> ideas for a faster SqueakJS JIT have been swirling around in my head for
>> many years. This weekend I took the time to write some of them down:
>>
>> https://squeak.js.org/docs/jit.md.html
>>
>> Feedback welcome!
>>
>> Vanessa
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20210314/38c3e262/attachment-0001.html>


More information about the Vm-dev mailing list