Squeak
  links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
MemoryAccess
Last updated at 11:24 pm UTC on 12 November 2010
This is an addition to VMMaker, contributed by Dave Lewis under MIT license, 18-September-2008.

MemoryAccess is available from http://www.squeaksource.com in package VMMaker.
The original change set is MemoryAccess-dtl.cs (MemoryAccess-dtl.cs.gz compressed)
Platform diffs are in MemoryAccessPlatformDiffs.zip

If you use MemoryAccess, you will also be interested in SlangBrowser, which enables fast in-image browsing of the generated C code in a Squeak browser.

MemoryAccess defines the low level mapping of object memory addresses to the underlying machine address space. It is intended to replace the traditional external definitions in sqMemoryAccess.h. By implementing these methods in Smalltalk, they may be directly translated to C code by the Slang translator, with Slang inlining providing performance similar to that of traditional C preprocessor macros. The resulting C code is directly visible to C debuggers and profiling tools, and the use of real C rather than macros is helpful in exposing problems such as improper type declarations and 32bit/64bit word size issues.

To change the VMMaker configuration to use MemoryAccess or to use the traditional sqMemoryAccess.h macros (or inlines), use these expressions:
MemoryAccess enable ==> cause MemoryAccess Slang generation of memory accessors
MemoryAccess disable ==> used traditional sqMemoryAccess.h memory accessors

The CCodeGenerator will set a macro in interp.h (#define MEMORY_ACCESS_IN_IMAGE 1) to inform external support code of the difference. Some changes to external support code are required for MemoryAccess (no changes are required if MemoryAccess is loaded but disabled).

When MemoryAccess in enabled, the Slang generator must perform extensive inlining in order to achieve performance equivalent to the tradational C macros. To enable inlining, as well as to correct various minor type declaration problems, a number of prerequisite changes are necessary.

External support code requirements:

With MemoryAccess disabled, no changes to support code are required, and code generation is identical to that obtained when MemoryAccess is not loaded in the image (except for changes related to the prerequisite change sets above).

With MemoryAccess enabled, three support code changes are required:
1) sqMemoryAccess.h must have an #ifdef added to prevent use of the memory access macros when MEMORY_ACCESS_IN_IMAGE is true.
2) An additional header file sqPointerForOop.h must be added to provide function prototypes for external support code modules that use some of the memory access functions (these are now generated as functions in interp.c and must be properly declared).
3) Several modules in the unix support code (and possibly elsewhere for other platforms) must include sqPointerForOop.h.

All platform code changes are controlled by the optional flag MEMORY_ACCESS_IN_IMAGE, and are completely backward compatible. The flag is generated automatically by VMMaker, so no configuration changes are required.

Building:

When changing from a VM build with MemoryAccess enabled to a VM build with MemoryAccess disabled, start with a clean build directory to ensure that all support code is recompiled (there is no "make clean" in the unix Makefile).

Performance:

Following are performance comparisons from my 64-bit AMD Linux laptop. Note, I do not trust these numbers, because I have obtained varying results at different times. I suspect that my laptop PC may be controlling CPU clock and polluting my results. Overall I am moderately confident that use of MemoryAccess along with the required Slang inlining fixes produces performance similar to that of the traditional C macros on this particular machine and operating system. Results may vary on other platforms.

Baseline performance, VMMaker-tpr.85.mcz, MemoryAccess not loaded:
Smalltalk garbageCollect. 0 tinyBenchmarks. '146369353 bytecodes/sec; 5268426 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '147891392 bytecodes/sec; 5320116 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '147806004 bytecodes/sec; 5296134 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '143982002 bytecodes/sec; 5308098 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '145124716 bytecodes/sec; 5276313 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '146035367 bytecodes/sec; 5206170 sends/sec'

VMMaker-dtl.97.mcz (Slang inliner fixes), MemoryAccess not loaded:
Smalltalk garbageCollect. 0 tinyBenchmarks. '144225352 bytecodes/sec; 5225467 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '146035367 bytecodes/sec; 5115497 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '143658810 bytecodes/sec; 5071334 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '144144144 bytecodes/sec; 5217731 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '142777467 bytecodes/sec; 4953728 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '144632768 bytecodes/sec; 5056782 sends/sec'

VMMaker-dtl.97.mcz, MemoryAccess loaded and enabled:
Smalltalk garbageCollect. 0 tinyBenchmarks. '146788990 bytecodes/sec; 4510015 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '146035367 bytecodes/sec; 5093320 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '148319814 bytecodes/sec; 5183202 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '146369353 bytecodes/sec; 5194661 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '147126436 bytecodes/sec; 5179393 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '148405797 bytecodes/sec; 5111787 sends/sec'

VMMaker-dtl.97.mcz, MemoryAccess loaded but disabled:
Smalltalk garbageCollect. 0 tinyBenchmarks. '145537237 bytecodes/sec; 5175591 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '147806004 bytecodes/sec; 5122932 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '146957520 bytecodes/sec; 4999400 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '145620022 bytecodes/sec; 5241007 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '144714527 bytecodes/sec; 5190835 sends/sec'
Smalltalk garbageCollect. 0 tinyBenchmarks. '145207033 bytecodes/sec; 5002948 sends/sec'