Edit Rename Changes History Upload Download Back to Top

The Squeak Plugin Primitives Port

VisualWorks 7.2 introduces a port of the Squeak Plugin Primitive framework. This framework is used to develop high-performance C implementations of algorithms for use as primitives dynamically-loaded into the virtual machine.

The cool things about the framework are that

The uncool things about the framework are that The Squeak framework is well docuemnted in a chapter of the Squeak Book. The "Extending the Squeak Virtual Machine" chapter by Andrew Greenberg describes the system. Since there are differences the VisualWorks system is documented separately here.

Algorithms as Primitives

To architect an algorithm as a primitive one typically splits the work into a Smalltalk class, an instance of which specifies an invocation of the algorithm, such as an instance of BitBlt or RasterOp for a bitmapped graphics operation, and a primitive method on the instance of the class that invokes the operation. Inside the primitive's implementation the instance and any arguments are checked for validity, failing the primitive if they are invalid, and the parameters for the operation are extracted from the instance. Then compiled C code actually performs the operation before the primitive returns any results.

In the plugin primitive framework, one creates the Smalltalk class that specifies the operation whereever in the class hierarchy is most convenient, but the Smalltalk implementation of the primitive must fit into the framework.

Development

The development side of the framework has two elements, the first being a hierarchy in which one codes one's algorithm as a class inheriting from InterpreterPlugin. InterpreterPlugin has an instance variable called interpreterProxy which holds an instance of InterpreterProxy, which implements the VM's object manipulation facilities. These facilities are used to validate the operation specification instance and arguments. One adds instance variables and methods to the InterpreterPlugin subclass to actually implement the primitive(s). When the plugin primitive is translated to C the instance variables become global C variables, and the methods become C functions in the C module produced. Once the module is compiled and dynamically loaded the algorithm(s) can be invoked via the relevant primitive method on an operation specification instance.

        Object
            InterpreterPlugin (interpreterProxy instance of InterpreterProxy)
                MyPluginClass (what ever global variables required)
The second element of the framework is the system that translates the primitive plugin's Smalltalk code to C. This framework is effectively a black box and should be expected to "just work". However, one typically has to annotate the Plugin Primitive's Smalltalk code to specify the types of C variables. By default all variables are assumed to be integers of C's int type. Annotations are necessary to define variables as arrays, pointers and so on.

_________________________________________________________________________

Edit: Skrishnamachari: 23 Nov 2004 13 June 2005

Squeak has had the framework for creating its entire VM in Smalltalk. This framework is now ported very nearly as is and hooked back to the VM access procedures.

Context for this framework:

Develop higher-performance C implementations of code sections for use as primitives. Development of primitive functions is done entirely as Smalltalk methods. Benefit from both the worlds…

    Smalltalk coding is the easiest…
    Compiled C code is better in performance…
as also
    Creating a modular Visualworks VM 

   For mathematically intensive calculations as in various algorithms like FFT or even Vector as well as for high memory 
swapping as in BitBlt, image handling, mpeg or sound algorithms it is highly efficient to use C primitive code access 
from Smalltalk.
   Currently these extensions are possible through the DLLCC framework, this can now be achieved through the new named 
primitives access.

Implementation Macro Overview:


Primitives:

Numbered        < primitive: 123>
For Extensions otherwise use:
DLLCC           < c: void func( int …)>
  new 
Named           < primitive: ‘func01’ module: ‘dllName’ >

Primarily the implementation depends on creation of the Smalltalk class and methods as per API specified. This can be debugged and finalized within Smalltalk and then exported as a C file. If everything is proper it will compile automatically with the vwntoeimport.lib linked and the {VW}/bin/src/include set as a INCLUDE folder. Link this dll functions back to Smalltalk through the primitive prgama.
To understand the framework, will currently require understanding the Smalltalk object structure and some VM fundamentals as well as probably a rudimentary C coding / compilation understanding.
Currently see it as implementable for Windows/ Unix* OS.. need to check for Mac.

Possibilities it opens up:
  1. Easier to create and link primitives. Extend VM far more easily than is done now 
  2. Combines the benefit of numbered primitives: Send in the reciever as an argument by default, link from any class and DLLCC link: Create your own primitive and link 
  3. Do the entire dev on Smalltalk coding with its ease of debugging etc and then export to a C file. Always use the ST memory manager to relieve your end of unnecessary memory handling.
  4. Bigger benefits is as stated in Squeak: Can look at creating a modular VM that is encased in the Smalltalk image ( or as a separate parcel loadable if reqd.) Need not distribute a complete src code CD...
  5. Modular VM can open up further possibilities of much smaller VM for any specific reqmt that includes only the basic compiler, memory manager and selected set of primitives. Can we look at less than 1 MB VM's custom built
  6. Named primitives are easier to comprehend, by their nomenclature and implementation in Smalltalk
  7. Port Squeak named primtive code to Visualworks for various algorithms already done therein.
A Simple example:

Smalltalk.HPSVM defineClass: #VMPluginTest
	superclass: #{HPSVM.InterpreterPlugin} 	indexedType: #none
	private: false			instanceVariableNames: ''
	classInstanceVariableNames: ''	imports: ''
	category: 'VMMaker-Plugins'

"instance method"
        returnGivenValue: anIntegerRcvr
	| anInt |
	self export: true.
	anInt := interpreterProxy integerValueOf: anInteger.
	^interpreterProxy integerObjectOf: anInt

Test with:  VMPluginTest new returnGivenValue: 123 OR
            VMPluginTest doPrimitive: #returnGivenValue receiver: (anyClass new) withArguments: #( 123)  if you have a 

"Class side method"
        selectorForPrimitive: aPrimKey
        "you can create key-primitive method symbol mappings if you wish"
        ^aPrimKey
Demo of this framework:

Refer to this powerpoint presentation to begin with unarchived from: STS2005_Skrish_VMPrimMaker.zip

1. Get the latest HPSVM parcels in VW7.3
2. Run through the demo as per the readme file in the archives


The speed tests on the plugin dlls on a PIII Dell Inspiron Laptop:
For Vector Add
	Internal:  154ms  DLLCC:  60ms  Interpreter:  373ms   PluginDll:   42ms 
For Vector CrossProduct Normal
	Internal:  469ms  DLLCC:  62ms  Interpreter:  399ms   PluginDll:   42ms
For FFT: Fast Fourier Transformation
       Interpreter: 110ms Plugin: 2ms  a whopping 55 times faster..!!..
Extended documentation being compiled is linked here: VMPrimitiveMaker01.pdf The contents of the doc are:
VM Plugin process and procedure in VisualWorks Smalltalk	
Use Scenario:	
Constructing the basic Plugin class	
Steps to create a plugin class:	
Another generic example of code:                 
  In Smalltalk:	
  In C Code: The above Smalltalk code is compiled to:	
More in Depth on the primitive method calls  
  1. Arguments:	
  2. ReturnType of function	
  3. Variable type definition	
  4. Object Access method calls	
  5. InlineC-Language Code	
Basic Example: VectorPlugin01	
Create external plugin dll	
Other Issues


Edit Rename Changes History Upload Download Back to Top