250 likes | 391 Views
Leandro & Valeria at Caesar Systems. Inspecting smalltalk. Smalltalk inspect. Smalltalk asDomain. Compiled Methods. Compiled Method. literal frame. globals constants selectors. bytecodes. native code. class. selector. source. info (bit fields). Smalltalk compiler.
E N D
Leandro & Valeria at Caesar Systems Inspecting smalltalk
Smalltalk inspect Smalltalk asDomain
Compiled Methods Compiled Method literalframe globals constants selectors bytecodes nativecode class selector source info(bit fields) Smalltalkcompiler JIT compiler(Nativizer) source & annotations # blocks # args # temps
Demo • Method inspector (literal frame)
VM Architecture Model • A Smalltalk Virtual Machine Architectural Model – Allen Wirfs-Brock & Pat Caudill @ Instantiations (1999) • Stack + Register Architecture • Execution Stack • Receiver/Result Register R • Argument Register A • Stack Frames, Program Counter, etc.
Message-Send Internals Push all arguments (if any) • Stack imbalance = # args Load register R with the receiver Send the message • The stack recovers its balance Get the result in R
PetitParser (Lukas 2010) Compiled Method method bytecodes 085 010 226 072 Petit Parser push argument 1 , load self , send selector 1 , return self
Bytecodes CompiledMethod >> #messageCount | parser | parser:= PPBytecodeParseron: self. ^parsermessageCount • push self • load assoc 1 • send selector 1 • store temp 1 • load temp 1 • send selector 2 • return 1 (1)push self 2 (1)load assoc 1 3 (0)send selector 1 4 (0)store temporary 1 5 (0)load temporary 1 6 (0)send selector 2 7 (0)return PPBytecodeParser on: self parser := parser messageCount ^
The Other Way Around 1 (1) push argument 1 2 (1) load self 3 (0) send selector 1 4 (0) return self method: argument • self selector: argument
Finding Numbers – Why? • Hunting for magic constants • Machine-dependent code • Radix independent service • Named constants (PoolDictionaries)
Finding SmallIntegers Problem • SmallIntegers are not in the literal frame • LargeIntegers and Floats are, but… • SmallIntegersare inside the bytecodes
Where Are the SmallIntegers? hiddenInteger ^self doSomethingWith: 127 1 (1) push SmallInteger 127 4 (1) load self 5 (0) send selector 1 6 (0) return #doSomethingWith: 025 254 001 010 226 072
Bytecodes to the Rescue Problem • SmallIntegers are not in the literal frame For every bytecode bc in a method m do: If bc is binary send or push/load SmallInteger Extract integer argument from bc Collect m if the integer matches
Proximity & Proportionality CompiledMethod >> #messageCount | parser | parser:= PPBytecodeParseron: self. ^parsermessageCount Smalltalk Compiler 1 (1) push self 2 (1) load assoc 1 3 (0) send selector 1 4 (0) store temporary 1 5 (0) load temporary 1 6 (0) send selector 2 7 (0) return prolog (class check, etc.) push ESI ; PushSelf mov EAX, [100F1C60] ; LoadAssoc1 call D50207 ; SendSelector1 mov [EBP-C], EAX ; StoreTemporary1 mov EAX, [EBP-C] ; LoadTemporary1 call D50206 ; SendSelector2 JIT Compiler(Nativizer) epilog (return, etc.)
Demo • Method inspector (executableCode)
Smalltalk Processes method4 implicit temps method temps implicit temps other stuff method temps method3 environment environment return address arguments method2 arguments Virtual Stack Real Stack method1
Process Frames ProcessFrame caller callee args return receiver method env temps implicit temporariesaccessedfrom blocks actual programcounteroffset self namedtemps unnamedtemps
A Model for Process Frames ProcessFrame return caller callee TopFrame SendFrame implicit temporaries environment method receiver return arguments BlockFrame MethodFrame InterruptFrame
Demo • Process Inspector
Native Stack Manipulation bytes! changed! top frame3 top new frame frame2 frame1 Smalltalk Stack Native Stack Native Stack
Applications • Block asProcess (VM) • Continuations (VM) • New Debugger (VM) • Education (Learn & Teach) • …
Sending Messages top top new frame msg send top frame3 frame3 frame3 frame2 frame2 frame2 frame1 frame1 frame1 aProcess aProcess aProcess aProcess send: selector to: receiver with: arg Message >> #send ^receiver perform: selector with: argument receiverselectorarg aMessage (msg)
Continuations top will return to frame3 with value K return: value K return: value top frame3 frame3 frame2 frame2 frame1 frame1 aProcess Copy aProcess #value: value user defined Continuation (K)