Feeds:
Posts
Comments

Archive for the ‘squeak’ Category

Squeak Help rant

I am currently writing some Help for the PostgresV3 package and I am reminded why I dislike the Squeak Help infrastructure.

In no particular order, my beefs:

  1. I am coding Help instead of Writing Help. I.e.
  2. I am thinking about Coding instead of thinking about the Subject Matter
  3. (Why did I start using 1700 Writing conventions of capitalizing Odd Words? Nevermind, it is late)
  4. The Help is limited to the Squeak environment.
  5. I cannot use the linux tools: ‘man’ , ‘info’, ’emacs org-mode’ .
  6. The “documents” are small. That is, I am forced into navigating many small pages of text instead of one big page of text.
  7. The Search bar works, and is appreciated.
  8. Navigation depends on the left side tree.
  9. When I click on a sub-topic (with the book icon) there is no content displayed in the content pane.

Rant off.

Advertisements

Read Full Post »

Here are the command line commands I used to get CogSpur running with a VMMaker image and the CMakeVMakerSqueak package starting from scratch.

#Do an svn checkout

svn co http://www.squeakvm.org/svn/squeak/branches/Cog

#run Eliot’s bash script to get the VMMaker image up and configured.

cd Cog/image
cat README
./ buildspurtrunkvmmakerimage.sh
./ cogspurlinuxht/squeak  SpurVMMaker.image  &

#Install the CMakeVMMakerSqueak package and see the documentation
Monticello browser
Repository http://source.squeak.org/VMMaker
CMakeVMMaker (latest) load
CMakeVMMakerSqueak (latest) load
HelpBrowser topic CMakeVMMakerSqueak

save and quit

#set up my personal working environment

#put the executable cog/spur in my PATH

mv cogspurlinuxht /home/tty/usr/bin/

#set up a development area independent of the Cog svn source tree
cd ../../
mkdir cogspurVMMaker
mv Cog/image/SpurVMMaker.* cogspurVMMaker/
mv Cog/image/SqueakV50.sources cogspurVMMaker/

#the tools are installed. now we need to put the Cog source tree
#in a subdirectory of the .image file. The directory is named ‘oscogvm’

cd cogspurVMMaker
mkdir oscogvm
rsync -Carv  –exclude=”image*”  ../Cog/ cogspurVMMaker/

#the resulting work environment directory tree looks like this

tree -d -L 2  cogspurVMMaker/
cogspurVMMaker/
`– oscogvm
|– build.linux32ARM
|– build.linux32x86
|– build.linux64x64
|– build.macos32x86
|– build.macos64x64
|– build.win32x86
|– history
|– nsspursrc
|– nsspurstack64src
|– nsspurstacksrc
|– nssrc
|– platforms
|– processors
|– products
|– scripts
|– sources
|– spur64src
|– spursistasrc
|– spursrc
|– spurstack64src
|– spurstacksrc
|– src
`– stacksrc

 

Read Full Post »

Building SqueakSSL compiles just fine, but fails at the libtool stage when compiled as an internal plugin.

My hunch is that when compiled as an external plugin, the linking is deferred until the module is loaded by the VM. If that is the case, then it explains the primitive fail.

My approach was to compile it as an internal plugin as (by just giving it a try) I found what I thought was an #include error. It took me a while (too long really–I have a bad habit of not closely reading things) find the problem, but it happens after a successful compilation when a thing called “libtool” is run.

Here is the output of the error at that stage:

/bin/sh
[......]/debugCogSqueakSSL/unixbuild/bld/libtool --mode=link gcc -m32 -g -Og -msse2 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -DNDEBUG -DITIMER_HEARTBEAT=1 -DCOGMTVM=0 -DDEBUGVM=0 -DLSB_FIRST=1 -Wl,-z,now -export-dynamic -o squeak vm/vm.a AsynchFilePlugin/AsynchFilePlugin.a B2DPlugin/B2DPlugin.a BitBltPlugin/BitBltPlugin.a FilePlugin/FilePlugin.a SocketPlugin/SocketPlugin.a SqueakSSL/SqueakSSL.a MiscPrimitivePlugin/MiscPrimitivePlugin.a disabledPlugins.o version.o -lutil -ldl -lpthread -lm -lnsl -lpthread vm/vm.a

gcc -m32 -g -Og -msse2 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -DNDEBUG -DITIMER_HEARTBEAT=1 -DCOGMTVM=0 -DDEBUGVM=0 -DLSB_FIRST=1 -Wl,-z -Wl,now -o squeak disabledPlugins.o version.o -Wl,--export-dynamic vm/vm.a AsynchFilePlugin/AsynchFilePlugin.a B2DPlugin/B2DPlugin.a BitBltPlugin/BitBltPlugin.a FilePlugin/FilePlugin.a SocketPlugin/SocketPlugin.a SqueakSSL/SqueakSSL.a MiscPrimitivePlugin/MiscPrimitivePlugin.a -lutil -ldl -lpthread -lm -lnsl -lpthread vm/vm.a

SqueakSSL/SqueakSSL.a(sqUnixOpenSSL.o): In function `sqCopyBioSSL':
[......]/debugCogSqueakSSL/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c:37: undefined reference to `BIO_ctrl_pending'

(more errors omitted for brevity. all of them are unresolved references to stuff in /usr/include/openssl/ssl.h . these errors do not happen at compile time, only linking stage )

Since discovering this, I have tried two things

1. compile on my pure 64 bit partition…this failed –we don’t have 64 bit Cog yet (: but hey…a guy can hope!

2. I installed openssl compat32 libs alongside the 64 bit versions…as shown below.
2.a I made some changes that I kinda-sorta-hoped would work in some strings in the script that had the substring “/lib64 ” but that did not work.

bash-4.2$ ls lib/*ssl*
lib/libssl.so.0 lib/libssl.so.0.9.8 lib/libssl.so.1 lib/libssl.so.1.0.0
bash-4.2$ ls lib64/*ssl*
lib64/libssl.so.0 lib64/libssl.so.0.9.8 lib64/libssl.so.1 lib64/libssl.so.1.0.0

I posted the above to the vm-dev mailing list and will see if anybody picks up on it. I will hit this again tomorrow!

Read Full Post »

Well, look what we have here from platforms/unix/vm/sqPlatformSpecific.h for the CogVM source tree.


#if defined(__GNUC__)
# if !defined(VM_LABEL)
# define VM_LABEL(foo) asm("\n.globl L" #foo "\nL" #foo ":")
# endif
#else
# if HAVE_ALLOCA_H
# include
# else
# ifdef _AIX
# pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca();
# endif
# endif
# endif
#endif

indented #defines and #includes…I will have to research this a bit more, but if it is true, then putting these puppies and debugging them just got a whole lot easier.

Read Full Post »

There are 3 exercises I went through.

Build 64 bit native VM that runs a 32 bit image
Build a 64 bit native VM compiled to support a 64 bit image downloaded from the Jenkins build server
Generate my own 64 bit image and run that on the VM built in 2 above.

This post is the quick-n-dirty of exercise 3 of the 3.

Please read the previous 2 posts in this series at:

https://timmydosmalltalk.wordpress.com/2014/03/13/howto-build-a-64-native-standardvm-running-32-bit-image-on-slackware-linux-14-1-with-32-bit-compat-libs/

and:

https://timmydosmalltalk.wordpress.com/2014/03/13/howto-build-a-64-native-standard-vm-running-64-bit-image-from-jenkins-build-server/

This exercise assumes you have completed the “64 native Standard VM running 64 bit image from Jenkins build server” exercise
and have an Interpreter VM capable of running a 64 bit image. If you don’t then this will not work.

What we are going to do here is use the SystemTracer on the All-In-One app to generate the 64 bit .image and .changes file
instead of downloading it from Jenkins. I am using my all-in-one install from the above “64 native StandardVM running 32 bit image on Slackware Linux 14.1 with 32 bit compat libs” exercise

#LAUNCH ALL-IN-ONE, INSTALL SystemTracer,
cd ~/usr/src/smalltalk/buildStandardVM32/Squeak-4.5-All-in-One.app
./squeak.sh

Toolbar menu->Tools->Monticello Browser
+Repository->HTTP
MCHttpRepository
location: ‘http://www.squeaksource.com/SystemTracing’
user: ‘squeak’
password: ‘squeak’

Open->SystemTracing-dtl.25.mcz (or latest)->Load

Open a Browser and look at class comment for SystemTracer64 (cut-n-paste below)
traceTo64Script
“This is a script that can be filed in to a 32-bit image to trace that image to 64-bit
format. The SystemTracing package is loaded from a local file, and is removed
from the image when tracing is complete. Save the script to a file, then start the
image to be traced, providing the script as a parameter on the command line.

Create the script file by evaluating this:

| fs |
fs := FileStream newFileNamed: ‘TraceTo64.st’.
fs nextPutAll: (SystemTracer64 traceTo64Script).
fs close.

Get a copy of the a Monticello source file for SystemTracer from the repository
at http://www.squeaksource.com/SystemTracing and place it in your working directory.

Then on the command line:
$ squeak myImageToBeTraced TraceTo64.st”

#GENERATE IMAGE AND CHANGES FILE WITH THE SCRIPT, DO INITIAL LAUNCH IN ORIGINAL DIRECTORY
cd Contents/Resources/
pwd /home/tty/usr/src/smalltalk/buildStandardVM32/Squeak-4.5-All-in-One.app/Contents/Resources
cp package-cache/SystemTracing-dtl.25.mcz ./
ls ls *.st
TraceTo64.st
ls *.mcz
SystemTracing-dtl.25.mcz
../Linux-i686/bin/squeak Squeak4.5-13680.image TraceTo64.st (This will launch squeak and generate the .image and .changes)
ls *.image
Squeak4.5-13680-64.image Squeak4.5-13680.image
ls Squeak4.5-13680-64*
Squeak4.5-13680-64.changes Squeak4.5-13680-64.image (ok, we have the new image and changes. It is important to first launch them in the current directory or else it gets confused)

export LD_LIBRARY_PATH=~/usr/local/standardVM64/lib
/home/tty/usr/local/standardVM64/lib/squeak/4.12.13-_64bit/squeakvm64 -vm-sound-ALSA -vm-display-X11 -xshm Squeak4.5-13680-64.image &

(at this point I get a blank desktop)

#CONFIGURE RUN ENVIRONMENT AND LAUNCH

cd /home/tty/usr/src/smalltalk/
mkdir runStandardVM64Traced
cd runStandardVM64Traced
(NOTE: we need .image, .changes and .sources files. we use the .sources …)
cp ../runStandardVM32/SqueakV41.sources ./
mv ../buildStandardVM32/Squeak-4.5-All-in-One.app/Contents/Resources/Squeak*64.* ./
ls
SqueakV41.sources Squeak4.5-13680-64.changes Squeak4.5-13680-64.image

#make a bash script startStandardVM64Traced.sh with the following contents (we are re-using the vm we created in the previous exercise)
#!/bin/bash
export LD_LIBRARY_PATH=~/usr/local/standardVM64/lib
/home/tty/usr/local/standardVM64/lib/squeak/4.12.13-_64bit/squeakvm64 -vm-sound-ALSA -vm-display-X11 -xshm Squeak4.5-13680-64.image

chmod 0755 startStandardVM64Traced.sh
./startStandardVM64Traced.sh

Toolbar menu->Help->About This System. (not working)

Read Full Post »

I just found an interesting tool in Squeak. It is in SystemTools->MessageTally.
From the class comment:

My instances observe and report the amount of time spent in methods.

NOTE: a higher-level user interface (combining the MessageTally result tree with a method browser) is available from TimeProfileBrowser.

MessageTally provides two different strategies available for profiling:

* spyOn: and friends use a high-priority Process to interrupt the block or process being spied on at periodic intervals. The interrupted call stack is then examined for caller information.

* tallySends: and friends use the interpreter simulator to run the block, recording every method call.

The two give you different results:

* spyOn: gives you a view of where the time is being spent in your program, at least on a rough statistical level (assuming you’ve run the block for long enough and have a high enough poll rate). If you’re trying to optimize your code, start here and optimize the methods where most of the time is being spent first.

* tallySends: gives you accurate counts of how many times methods get called, and by exactly which route. If you’re debugging, or trying to figure out if a given method is getting called too many times, this is your tool.

You can change the printing format (that is, the whitespace and string compression) by using these instance methods:
maxClassNameSize:
maxClassPlusSelectorSize:
maxTabs:

You can change the default polling period (initially set to 1) by calling
MessageTally defaultPollPeriod: numberOfMilliseconds

Q: How do you interpret MessageTally>>tallySends
A: The methods #tallySends and #spyOn: measure two very different quantities, but broken down in the same who-called-who format. #spyOn: is approximate, but more indicative of real time spent, whereas #tallySends is exact and a precise record of how many times each method got executed.

It is not quite what I am looking for for system tracing, but it is interesting nonetheless.

Read Full Post »

Eliot Miranda at Cog:Blog offers three examples of BlockContexts as a preliminary to introducing BlockClosures.

This post focuses on what happens in Eliot’s second example where
he presents an intermediate step towards solving the reentrancy problem by using copy to create a new BlockContext.

From Eliot’s post, his example reads:

OK, let’s deal with the reentrancy problem. Simply evaluating a copy of the block instead of the original produces a fresh activation record for each activation of the block. This is what Allen Wirfs-Brock’s team did in the Tektronix implementation on the 4404 back in the ’80′s. They modified the BlockContext>>value[:value:…] primitives to activate a copy of the receiver. Let’s try modifying the example with explicit copies:

| factorial |
factorial := [:n| n = 1 ifTrue: [1] ifFalse: [(factorial copy value: n – 1) * n]].
(1 to: 10) collect: factorial copy #(1 1 1 1 1 1 1 1 1 1)

which answers… #(1 1 1 1 1 1 1 1 1 1) ?!?!

Being a newbie to this, what happens above was not obvious to me. This “tutorial” shows my line of thinking.

I present this in 2 stages.
Stage 1 starts with tracing the output of a modified version of Eliot’s code. This trace is followed by a discussion of what I see in the trace.
A screenshot of Stage 1 is provided for cross-reference as well.

Stage 2 looks at the problem of the sender of the first MethodContext when the code is run. This point will be made clear to the reader by the end
of Stage 1.

Let’s start with stage 1.

I “newbie-fied” Eliot’s code like this:

| factorial fc |
“Transcript clear.”
factorial := [:n |
n = 1
ifTrue:[
Transcript show: ‘ n=’, (n asString),’ ‘, (thisContext class name), ‘(‘, (thisContext identityHash asString),’)’ .
Transcript show: ‘–sender–>’, (thisContext sender) class name, ‘(‘, (thisContext sender) identityHash asString,’)’.
Transcript show: ‘–home–>’, (thisContext home) class name, ‘(‘, (thisContext home) identityHash asString,’)’; cr.
Transcript show: ‘++++++++++++++++++++++++++++++++++++++++’;cr.
“thisContext explore. ”
1
]
ifFalse:[ Transcript show: ‘———————————————–‘;cr.
Transcript show: ‘ n=’, (n asString),’ ‘, (thisContext class name), ‘(‘, (thisContext identityHash asString),’)’ .
Transcript show: ‘–sender–>’, (thisContext sender) class name, ‘(‘, (thisContext sender) identityHash asString,’)’.
Transcript show: ‘–home–>’, (thisContext home) class name, ‘(‘, (thisContext home) identityHash asString,’)’; cr.
(factorial copy value: n-1) * n
]].
Transcript show: ‘*************************************************’;cr.
Transcript show:’ thisContext = ‘ , (thisContext class name),'(‘,thisContext identityHash asString,’)’.
Transcript show: ‘–sender–>’, (thisContext sender) class name, ‘(‘, (thisContext sender) identityHash asString,’)’.
Transcript show: ‘–home–>’, (thisContext home) class name, ‘(‘, (thisContext home) identityHash asString,’)’; cr.
Transcript show: ‘*************************************************’;cr;cr.

Transcript show:’ factorial = ‘ , (factorial class name),'(‘,factorial identityHash asString,’)’.
Transcript show: ‘–sender–>’, (factorial sender) class name, ‘(‘, (factorial sender) identityHash asString,’)’.
Transcript show: ‘–home–>’, (factorial home) class name, ‘(‘, (factorial home) identityHash asString,’)’; cr.
Transcript show: ‘^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^’;cr;cr.
fc := factorial copy .

Transcript show:’ fc = ‘ , (fc class name),'(‘,fc identityHash asString,’)’.
Transcript show: ‘–sender–>’, (fc sender) class name, ‘(‘, (fc sender) identityHash asString,’)’.
Transcript show: ‘–home–>’, (fc home) class name, ‘(‘, (fc home) identityHash asString,’)’; cr.
Transcript show: ‘^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^’;cr;cr.
thisContext inspect.
thisContext sender explore.
factorial inspect.
fc inspect.
(1 to: 3) collect: fc.

The output in the transcript after DoIt is:

*************************************************
thisContext = MethodContext(2154)–sender–>MethodContext(376)–home–>MethodContext(2154)
*************************************************

factorial = BlockContext(2468)–sender–>UndefinedObject(3840)–home–>MethodContext(2154)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

fc = BlockContext(3452)–sender–>UndefinedObject(3840)–home–>MethodContext(2154)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

n=1 BlockContext(3452)–sender–>MethodContext(337)–home–>MethodContext(2154)
++++++++++++++++++++++++++++++++++++++++
———————————————–
n=2 BlockContext(3452)–sender–>MethodContext(337)–home–>MethodContext(2154)
n=1 BlockContext(1676)–sender–>BlockContext(3452)–home–>MethodContext(2154)
++++++++++++++++++++++++++++++++++++++++
———————————————–
n=3 BlockContext(3452)–sender–>MethodContext(337)–home–>MethodContext(2154)
———————————————–
n=2 BlockContext(1496)–sender–>BlockContext(3452)–home–>MethodContext(2154)
n=1 BlockContext(752)–sender–>BlockContext(1496)–home–>MethodContext(2154)
++++++++++++++++++++++++++++++++++++++++

In my running commentary to myself as I studied the output above, I ran self identityHash on the various inspectors that opened
while running the above code. I then modified the title bar of each inspector and added this identityHash to the title bar. In the following screenshot you can see those inspectors and correlate them to the trace above.

BlockContextReentrantAttemptWithCopy

Here is my running commentary to myself for Stage 1:

1 We see our initial context at the line:
thisContext = MethodContext(2154)–sender–>MethodContext(376)–home–>MethodContext(2154)

MethodContext(2154)’s method is CompiledMethod(3991). This is the code that initially runs.

1. At bytecode 127 of CompiledMethod(3991) the “send: blockCopy” tells the Interpreter to create and activate the initial BlockContext(2468) and it becomes the active record.. Its home is the now the suspended MethodContext(2154). Per the BlueBook, the BlockContext(2154) shares much if its state with the active context that creates it. The receiver, arguments, temporary variables, CompiledMethod and sender are all the same.

You can see this in the line that begins with “factorial=” on the Transcript at the left.

2. sending copy to “factorial” creates BlockContext(3452).

3 at n = 1 The sender of BlockContext(3452) is MethodContext(337). MethodContext(337) was created by sending the message ‘collect’ to the Interval (1 to: 3). Remember, from the BlueBook, a A MethodContext … Represents the execution of a CompiledMethod in response to a message. Notice that this MethodContext(337). Note that it is the first sender at n=2 and n=3 as well.

4. Looking at n=3 will tell us everthing we need to know about n=2 so let’s move to the line that starts with
n=3.

5 At n=3 collect sends the value:3 to BlockContext(3452) activating MethodContext(337)
As the recursion call progresses to n=1, we can see chain of senders. The active BlockContext is at the far right of the following chain.

MethodContext(337) <<<–sender-BlockContext3452()<<<-sender-BlockContext(1496)<<>allocateOrRecycleContext:

7. That’s the chain of our code, but look again at the line near the top that reads:
thisContext = MethodContext(2154)–sender–>MethodContext(376)–home–>MethodContext(2154)

Where did its sender come from?

We are now at Stage2 and need to answer the question, where did that initial sender MethodContext(376) come from?

Here is screenshot and my running commentary notes from that investigation:

BlockContextReentrantAttemptWithCopyDoItTracingIncluded

7. That’s the chain of our code, but look again at the line that reads:
thisContext = MethodContext(2154)–sender–>MethodContext(376)–home–>MethodContext(2154)

Where did its sender MethodContext(376) come from?

To see this, I added tracer code in the following methods:

ParagraphEditor>>doIt
ParagraphEditory>>evaluateSelection
Compiler>>evaluate: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag

I have scrolled the Transcript to include the output from that tracing. Lets follow it.

1. When we DoIt on the example, The message doIt is sent to #ParagraphEditor. We see that tracing
at the lines
This Class->TextMorphEditor
thisContext = MethodContext(3259)–sender–>BlockContext(3126)–home–>MethodContext(3259)
I believe that (but do not know) that since the ParagraphEditor is embeded in a TextMorphEditor, that that is why the class shows as TextMorphEditor.

2. This invokes ParagraphEditor >>evaluateSelection

3 ParagraphEditor >>evaluateSelection does some error checking and marshalling and then invokes
Compiler >> evaluate: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock logged: logFlag

4 The Compiler then compiles the workspace code into the CompiledMethod(3991) and “invokes it”. Where we see it as Compiler(376)>>evaluate:in:to:notifyi…etc…
It is this initial MethodContext(376) that the Compiler creates that serves as the sender to our MethodContext(2154)

5. At this point our code runs as described above.

And that’s it. I will be working Eliot’s third example next, before returning to his first example.

Read Full Post »

Older Posts »