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@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@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