Class checks in the vm

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Class checks in the vm

Guillermo Polito
 
Hi!

I'm playing to bootstrap a Pharo image, trying to get a new environment running into my 'host' image, and after that, dump those new objects into a new image file.

Now, to do that, I'm creating new classes for String, Character...  Which are well known by the vm specialObjectsArray.  And trying to initialize my new image classes, which creates new character objects, and new string objects which is causing me some troubles :P.

Now, my question is about this check in vmmaker (and some others that look similar):

Interpreter>>#asciiOfCharacter: characterObj  "Returns an integer object"
    <inline: false>
    self assertClassOf: characterObj is: (self splObj: ClassCharacter).
    successFlag
        ifTrue: [^ self fetchPointer: CharacterValueIndex ofObject: characterObj]
        ifFalse: [^ ConstZero]  "in case some code needs an int"


- Can't we put a more intelligent assersion like checking if the object responds true to #isCharacter?
- And removing the static check from the vm and adding the dynamic and nice #isCharacter check into the image?

Thanks!
Guille

Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Eliot Miranda-2
 
Hi Guillermo,

On Tue, Apr 17, 2012 at 8:33 AM, Guillermo Polito <[hidden email]> wrote:
 
Hi!

I'm playing to bootstrap a Pharo image, trying to get a new environment running into my 'host' image, and after that, dump those new objects into a new image file.

Now, to do that, I'm creating new classes for String, Character...  Which are well known by the vm specialObjectsArray.  And trying to initialize my new image classes, which creates new character objects, and new string objects which is causing me some troubles :P.

Now, my question is about this check in vmmaker (and some others that look similar):

Interpreter>>#asciiOfCharacter: characterObj  "Returns an integer object"
    <inline: false>
    self assertClassOf: characterObj is: (self splObj: ClassCharacter).
    successFlag
        ifTrue: [^ self fetchPointer: CharacterValueIndex ofObject: characterObj]
        ifFalse: [^ ConstZero]  "in case some code needs an int"


- Can't we put a more intelligent assersion like checking if the object responds true to #isCharacter?

The issue is performance.  One wants as quick a test here as possible, so testing the class of the receiver is faster than doing a probe on the method lookup cache and much faster than possibly having to do a full class lookup.  So realistically the answer is "no, we shouldn't".
 
- And removing the static check from the vm and adding the dynamic and nice #isCharacter check into the image?

 This doesn't make a lot of sense.  asciiOfCharacter: is being used in the VM by various primitives (e.g. at:put: on strings) and its use is to fail if one attempts to store other than a character in a string.  So moving the test to the image means the primitive is not safe.  Keep on moving in this direction and you end up with a system that will crash when one makes an error instead of raising an error message.  Smalltalk is a safe language; it is extremely important that the system not crash and instead provide walkbacks that afford diagnosis of errors.


The real issue here is that you want more flexibility in the VM while bootstrapping than one wants or needs in normal use.  Instead of making the VM slow and more general than it need be the right approach is to create a variant of the VM for your bootstrapping use.  You can do this by creating a subclass of Interpreter which reimplements asciiOfCharacter: (and others you may need) and testing it in the simulator.  You can then use your flexible VM for the bootstrap and once complete use the normal VM.


Thanks!
Guille





--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Stefan Marr-3

Hi Eliot:

On 17 Apr 2012, at 18:13, Eliot Miranda wrote:

> Smalltalk is a safe language; it is extremely important that the system not crash and instead provide walkbacks that afford diagnosis of errors.

Since when is that? Didn't you tell me that if I do something stupid with a primitive, I have to expect that it crashes?

And the last time I checked, the store bytecode didn't do any length checks either, so it is easily possible to forge a method that writes into random memory, no?

Best regards
Stefan


--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525

Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Eliot Miranda-2
 


On Tue, Apr 17, 2012 at 9:20 AM, Stefan Marr <[hidden email]> wrote:

Hi Eliot:

On 17 Apr 2012, at 18:13, Eliot Miranda wrote:

> Smalltalk is a safe language; it is extremely important that the system not crash and instead provide walkbacks that afford diagnosis of errors.

Since when is that? Didn't you tell me that if I do something stupid with a primitive, I have to expect that it crashes?

Most of the time the system is safe.  One has to think a little to get it to crash (thisContext swapSender: 1@2).  But in normal use it doesn't crash ('abc' at: 1 put: 1@2).


And the last time I checked, the store bytecode didn't do any length checks either, so it is easily possible to forge a method that writes into random memory, no?

Yes, there are many ways to crash the VM.  But its not so bad right now (there are lots of safe primitives and the system is much safer than e.g. C), and it's getting better (e.g. I just plugged a gap in objectAt:put:), but it is a tricky balance between performance and safety.  For me, its some judgement call on common usage.  But its certainly up for debate.

 

Best regards
Stefan


--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: <a href="tel:%2B32%202%20629%202974" value="+3226292974">+32 2 629 2974
Fax:   <a href="tel:%2B32%202%20629%203525" value="+3226293525">+32 2 629 3525




--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Igor Stasenko
In reply to this post by Stefan Marr-3
 
Performance, yes...

But i wonder, how much performance we will lose by having more
flexible implementation for ByteString..

So, here what i did:

ByteString>>bat: index put: aCharacter

        ^ aCharacter putIntoByteString: self at: index

Character>>putIntoByteString: string at: index

        ^ value < 256
                ifTrue: [ string basicAt: index put: value ]
                ifFalse: [  string at: index put: self ]


Now benchmark:

| s chars |

s := ByteString new: 1000.
chars := (1 to: 255) collect: [:i | Character value: i ].

[
1 to: 1000 do: [:i |
        chars do: [:char| s at: i put: char ]
        ].
] bench

 '105 per second.'

| s chars |

s := ByteString new: 1000.
chars := (1 to: 255) collect: [:i | Character value: i ].

[
1 to: 1000 do: [:i |
        chars do: [:char| s bat: i put: char ]
        ].
] bench


 '91.9 per second.'

~10%...

Such kind of difference is IMO laughable, taking into account the
a) more flexibility
b) less VM complexity


Another benchmark:

| s |

s := ByteString new: 1000.
[
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
        s at: 1 put: $A.
] bench
 '1,530,000 per second.'

| s |

s := ByteString new: 1000.
[
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
        s bat: 1 put: $A.
] bench
 '1,310,000 per second.'


Frankly, i expected much , much more difference. So, i think in this
case we can safely discard the performance argument(s).

--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Eliot Miranda-2
 


On Tue, Apr 17, 2012 at 9:54 AM, Igor Stasenko <[hidden email]> wrote:

Performance, yes...

But i wonder, how much performance we will lose by having more
flexible implementation for ByteString..

So, here what i did:

ByteString>>bat: index put: aCharacter

       ^ aCharacter putIntoByteString: self at: index

Character>>putIntoByteString: string at: index

       ^ value < 256
               ifTrue: [ string basicAt: index put: value ]
               ifFalse: [  string at: index put: self ]


Now benchmark:

| s chars |

s := ByteString new: 1000.
chars := (1 to: 255) collect: [:i | Character value: i ].

[
1 to: 1000 do: [:i |
       chars do: [:char| s at: i put: char ]
       ].
] bench

 '105 per second.'

| s chars |

s := ByteString new: 1000.
chars := (1 to: 255) collect: [:i | Character value: i ].

[
1 to: 1000 do: [:i |
       chars do: [:char| s bat: i put: char ]
       ].
] bench


 '91.9 per second.'

~10%...

Such kind of difference is IMO laughable,

I disagree.  10% is a significant loss of performance.  It can take huge effort to gain 10% in a VM implementation.  It is not at all laughable.  Cog is significantly faster than the Interpreter (by factors of 3 or 5).  And that performance difference is worth-while.  The straw man below isn't a convincing argument either.  I don't see what is wrong with using a slower more flexible VM for bootstrapping (or indeed a simulation, or ...).  But do we really have to spend time arguing this point?  If you think you can do better, then  do so.  Build a more flexible VM.  Then we can compare the two.


 
taking into account the
a) more flexibility
b) less VM complexity


Another benchmark:

| s |

s := ByteString new: 1000.
[
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
       s at: 1 put: $A.
] bench
 '1,530,000 per second.'

| s |

s := ByteString new: 1000.
[
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
       s bat: 1 put: $A.
] bench
 '1,310,000 per second.'


Frankly, i expected much , much more difference. So, i think in this
case we can safely discard the performance argument(s).

--
Best regards,
Igor Stasenko.



--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Igor Stasenko

On 17 April 2012 19:14, Eliot Miranda <[hidden email]> wrote:

>
>
>
> On Tue, Apr 17, 2012 at 9:54 AM, Igor Stasenko <[hidden email]> wrote:
>>
>>
>> Performance, yes...
>>
>> But i wonder, how much performance we will lose by having more
>> flexible implementation for ByteString..
>>
>> So, here what i did:
>>
>> ByteString>>bat: index put: aCharacter
>>
>>        ^ aCharacter putIntoByteString: self at: index
>>
>> Character>>putIntoByteString: string at: index
>>
>>        ^ value < 256
>>                ifTrue: [ string basicAt: index put: value ]
>>                ifFalse: [  string at: index put: self ]
>>
>>
>> Now benchmark:
>>
>> | s chars |
>>
>> s := ByteString new: 1000.
>> chars := (1 to: 255) collect: [:i | Character value: i ].
>>
>> [
>> 1 to: 1000 do: [:i |
>>        chars do: [:char| s at: i put: char ]
>>        ].
>> ] bench
>>
>>  '105 per second.'
>>
>> | s chars |
>>
>> s := ByteString new: 1000.
>> chars := (1 to: 255) collect: [:i | Character value: i ].
>>
>> [
>> 1 to: 1000 do: [:i |
>>        chars do: [:char| s bat: i put: char ]
>>        ].
>> ] bench
>>
>>
>>  '91.9 per second.'
>>
>> ~10%...
>>
>> Such kind of difference is IMO laughable,
>
>
> I disagree.  10% is a significant loss of performance.  It can take huge effort to gain 10% in a VM implementation.  It is not at all laughable.  Cog is significantly faster than the Interpreter (by factors of 3 or 5).  And that performance difference is worth-while.  The straw man below isn't a convincing argument either.  I don't see what is wrong with using a slower more flexible VM for bootstrapping (or indeed a simulation, or ...).  But do we really have to spend time arguing this point?  If you think you can do better, then  do so.  Build a more flexible VM.  Then we can compare the two.

Calm down, Eliot. I am not challenging and don't want to be
challenged. Yes, we can squeeze 1 or 2 % here and there, but at costs
of having additional constraints/contracts like compact classes,
ifTrue/ifFalse inlining etc.. which , if we follow that path all the
way, we end up with strongly typed system like C or Java and little
room for smalltalk powers.

The good question is where to put optimizations to not constrain the
system more than necessary and do not sacrifice flexibility in favor
of speed.

--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Eliot Miranda-2
 


On Tue, Apr 17, 2012 at 10:33 AM, Igor Stasenko <[hidden email]> wrote:

On 17 April 2012 19:14, Eliot Miranda <[hidden email]> wrote:
>
>
>
> On Tue, Apr 17, 2012 at 9:54 AM, Igor Stasenko <[hidden email]> wrote:
>>
>>
>> Performance, yes...
>>
>> But i wonder, how much performance we will lose by having more
>> flexible implementation for ByteString..
>>
>> So, here what i did:
>>
>> ByteString>>bat: index put: aCharacter
>>
>>        ^ aCharacter putIntoByteString: self at: index
>>
>> Character>>putIntoByteString: string at: index
>>
>>        ^ value < 256
>>                ifTrue: [ string basicAt: index put: value ]
>>                ifFalse: [  string at: index put: self ]
>>
>>
>> Now benchmark:
>>
>> | s chars |
>>
>> s := ByteString new: 1000.
>> chars := (1 to: 255) collect: [:i | Character value: i ].
>>
>> [
>> 1 to: 1000 do: [:i |
>>        chars do: [:char| s at: i put: char ]
>>        ].
>> ] bench
>>
>>  '105 per second.'
>>
>> | s chars |
>>
>> s := ByteString new: 1000.
>> chars := (1 to: 255) collect: [:i | Character value: i ].
>>
>> [
>> 1 to: 1000 do: [:i |
>>        chars do: [:char| s bat: i put: char ]
>>        ].
>> ] bench
>>
>>
>>  '91.9 per second.'
>>
>> ~10%...
>>
>> Such kind of difference is IMO laughable,
>
>
> I disagree.  10% is a significant loss of performance.  It can take huge effort to gain 10% in a VM implementation.  It is not at all laughable.  Cog is significantly faster than the Interpreter (by factors of 3 or 5).  And that performance difference is worth-while.  The straw man below isn't a convincing argument either.  I don't see what is wrong with using a slower more flexible VM for bootstrapping (or indeed a simulation, or ...).  But do we really have to spend time arguing this point?  If you think you can do better, then  do so.  Build a more flexible VM.  Then we can compare the two.

Calm down, Eliot. I am not challenging and don't want to be
challenged. Yes, we can squeeze 1 or 2 % here and there, but at costs
of having additional constraints/contracts like compact classes,
ifTrue/ifFalse inlining etc.. which , if we follow that path all the
way, we end up with strongly typed system like C or Java and little
room for smalltalk powers.

I'm not uncalm :)  I just get frustrated with these performance arguments, having a coherent vision for better performance and having failed to make satisfactory progress.  The better object representation followed by more machine-code primitives step will get another factor of 2 and result in a simpler VM (immediate characters for example).  Speculative inlining/adaiptive optimizing in Smalltalk will get another factor of 3.  But I'm not paid to work on these things.  And I find having discussions about small points like this adds to my frustration because they're not getting us very far and I feel I'm wasting my breath.  Sorry...

 

The good question is where to put optimizations to not constrain the
system more than necessary and do not sacrifice flexibility in favor
of speed.

Right.  Better object representation, followed by speculative inlining.
 

--
Best regards,
Igor Stasenko.



--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Guillermo Polito
In reply to this post by Eliot Miranda-2
 


On Tue, Apr 17, 2012 at 6:13 PM, Eliot Miranda <[hidden email]> wrote:
 
Hi Guillermo,

On Tue, Apr 17, 2012 at 8:33 AM, Guillermo Polito <[hidden email]> wrote:
 
Hi!

I'm playing to bootstrap a Pharo image, trying to get a new environment running into my 'host' image, and after that, dump those new objects into a new image file.

Now, to do that, I'm creating new classes for String, Character...  Which are well known by the vm specialObjectsArray.  And trying to initialize my new image classes, which creates new character objects, and new string objects which is causing me some troubles :P.

Now, my question is about this check in vmmaker (and some others that look similar):

Interpreter>>#asciiOfCharacter: characterObj  "Returns an integer object"
    <inline: false>
    self assertClassOf: characterObj is: (self splObj: ClassCharacter).
    successFlag
        ifTrue: [^ self fetchPointer: CharacterValueIndex ofObject: characterObj]
        ifFalse: [^ ConstZero]  "in case some code needs an int"


- Can't we put a more intelligent assersion like checking if the object responds true to #isCharacter?

The issue is performance.  One wants as quick a test here as possible, so testing the class of the receiver is faster than doing a probe on the method lookup cache and much faster than possibly having to do a full class lookup.  So realistically the answer is "no, we shouldn't".
 
- And removing the static check from the vm and adding the dynamic and nice #isCharacter check into the image?

 This doesn't make a lot of sense.  asciiOfCharacter: is being used in the VM by various primitives (e.g. at:put: on strings) and its use is to fail if one attempts to store other than a character in a string.  So moving the test to the image means the primitive is not safe.  Keep on moving in this direction and you end up with a system that will crash when one makes an error instead of raising an error message.  Smalltalk is a safe language; it is extremely important that the system not crash and instead provide walkbacks that afford diagnosis of errors.


The real issue here is that you want more flexibility in the VM while bootstrapping than one wants or needs in normal use.  Instead of making the VM slow and more general than it need be the right approach is to create a variant of the VM for your bootstrapping use.  You can do this by creating a subclass of Interpreter which reimplements asciiOfCharacter: (and others you may need) and testing it in the simulator.  You can then use your flexible VM for the bootstrap and once complete use the normal VM.

I was not totally aware of the performance issues (I knew there were going to be some tradeoffs, but not so critical :) ).  Now, for the bootstrap, I'll talk with my mentors to see which should be a nice approach to reach where we want to be.

BTW, you were talking about better object representation and inmediate characters, can you give me a pointer of what you mean? (just curious)

Thank you!!
Guille
 


Thanks!
Guille





--
best,
Eliot



Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Nicolas Cellier

Le 18 avril 2012 12:34, Guillermo Polito <[hidden email]> a écrit :

>
>
>
> On Tue, Apr 17, 2012 at 6:13 PM, Eliot Miranda <[hidden email]> wrote:
>>
>>
>> Hi Guillermo,
>>
>> On Tue, Apr 17, 2012 at 8:33 AM, Guillermo Polito <[hidden email]> wrote:
>>>
>>>
>>> Hi!
>>>
>>> I'm playing to bootstrap a Pharo image, trying to get a new environment running into my 'host' image, and after that, dump those new objects into a new image file.
>>>
>>> Now, to do that, I'm creating new classes for String, Character...  Which are well known by the vm specialObjectsArray.  And trying to initialize my new image classes, which creates new character objects, and new string objects which is causing me some troubles :P.
>>>
>>> Now, my question is about this check in vmmaker (and some others that look similar):
>>>
>>> Interpreter>>#asciiOfCharacter: characterObj  "Returns an integer object"
>>>     <inline: false>
>>>     self assertClassOf: characterObj is: (self splObj: ClassCharacter).
>>>     successFlag
>>>         ifTrue: [^ self fetchPointer: CharacterValueIndex ofObject: characterObj]
>>>         ifFalse: [^ ConstZero]  "in case some code needs an int"
>>>
>>>
>>> - Can't we put a more intelligent assersion like checking if the object responds true to #isCharacter?
>>
>>
>> The issue is performance.  One wants as quick a test here as possible, so testing the class of the receiver is faster than doing a probe on the method lookup cache and much faster than possibly having to do a full class lookup.  So realistically the answer is "no, we shouldn't".
>>
>>>
>>> - And removing the static check from the vm and adding the dynamic and nice #isCharacter check into the image?
>>
>>
>>  This doesn't make a lot of sense.  asciiOfCharacter: is being used in the VM by various primitives (e.g. at:put: on strings) and its use is to fail if one attempts to store other than a character in a string.  So moving the test to the image means the primitive is not safe.  Keep on moving in this direction and you end up with a system that will crash when one makes an error instead of raising an error message.  Smalltalk is a safe language; it is extremely important that the system not crash and instead provide walkbacks that afford diagnosis of errors.
>>
>>
>> The real issue here is that you want more flexibility in the VM while bootstrapping than one wants or needs in normal use.  Instead of making the VM slow and more general than it need be the right approach is to create a variant of the VM for your bootstrapping use.  You can do this by creating a subclass of Interpreter which reimplements asciiOfCharacter: (and others you may need) and testing it in the simulator.  You can then use your flexible VM for the bootstrap and once complete use the normal VM.
>
>
> I was not totally aware of the performance issues (I knew there were going to be some tradeoffs, but not so critical :) ).  Now, for the bootstrap, I'll talk with my mentors to see which should be a nice approach to reach where we want to be.
>
> BTW, you were talking about better object representation and inmediate characters, can you give me a pointer of what you mean? (just curious)
>

Character would be encoded directly in the object pointer like
SmallInteger already are.

Nicolas

> Thank you!!
> Guille
>
>>
>>
>>>
>>> Thanks!
>>> Guille
>>>
>>>
>>
>>
>>
>> --
>> best,
>> Eliot
>>
>>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Eliot Miranda-2
In reply to this post by Guillermo Polito
 


On Wed, Apr 18, 2012 at 3:34 AM, Guillermo Polito <[hidden email]> wrote:
 


On Tue, Apr 17, 2012 at 6:13 PM, Eliot Miranda <[hidden email]> wrote:
 
Hi Guillermo,

On Tue, Apr 17, 2012 at 8:33 AM, Guillermo Polito <[hidden email]> wrote:
 
Hi!

I'm playing to bootstrap a Pharo image, trying to get a new environment running into my 'host' image, and after that, dump those new objects into a new image file.

Now, to do that, I'm creating new classes for String, Character...  Which are well known by the vm specialObjectsArray.  And trying to initialize my new image classes, which creates new character objects, and new string objects which is causing me some troubles :P.

Now, my question is about this check in vmmaker (and some others that look similar):

Interpreter>>#asciiOfCharacter: characterObj  "Returns an integer object"
    <inline: false>
    self assertClassOf: characterObj is: (self splObj: ClassCharacter).
    successFlag
        ifTrue: [^ self fetchPointer: CharacterValueIndex ofObject: characterObj]
        ifFalse: [^ ConstZero]  "in case some code needs an int"


- Can't we put a more intelligent assersion like checking if the object responds true to #isCharacter?

The issue is performance.  One wants as quick a test here as possible, so testing the class of the receiver is faster than doing a probe on the method lookup cache and much faster than possibly having to do a full class lookup.  So realistically the answer is "no, we shouldn't".
 
- And removing the static check from the vm and adding the dynamic and nice #isCharacter check into the image?

 This doesn't make a lot of sense.  asciiOfCharacter: is being used in the VM by various primitives (e.g. at:put: on strings) and its use is to fail if one attempts to store other than a character in a string.  So moving the test to the image means the primitive is not safe.  Keep on moving in this direction and you end up with a system that will crash when one makes an error instead of raising an error message.  Smalltalk is a safe language; it is extremely important that the system not crash and instead provide walkbacks that afford diagnosis of errors.


The real issue here is that you want more flexibility in the VM while bootstrapping than one wants or needs in normal use.  Instead of making the VM slow and more general than it need be the right approach is to create a variant of the VM for your bootstrapping use.  You can do this by creating a subclass of Interpreter which reimplements asciiOfCharacter: (and others you may need) and testing it in the simulator.  You can then use your flexible VM for the bootstrap and once complete use the normal VM.

I was not totally aware of the performance issues (I knew there were going to be some tradeoffs, but not so critical :) ).  Now, for the bootstrap, I'll talk with my mentors to see which should be a nice approach to reach where we want to be.

BTW, you were talking about better object representation and inmediate characters, can you give me a pointer of what you mean? (just curious)

Read the class comment of CogMemoryManager in a Cog VMMaker, e.g. VMMaker-oscog-EstebanLorenzano.156 or VMMaker.oscog-eem.157

HTH
 

Thank you!!
Guille
 


Thanks!
Guille





--
best,
Eliot







--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

stephane ducasse-2
In reply to this post by Eliot Miranda-2

>
> I'm playing to bootstrap a Pharo image, trying to get a new environment running into my 'host' image, and after that, dump those new objects into a new image file.
>
> Now, to do that, I'm creating new classes for String, Character...  Which are well known by the vm specialObjectsArray.  And trying to initialize my new image classes, which creates new character objects, and new string objects which is causing me some troubles :P.
>
> Now, my question is about this check in vmmaker (and some others that look similar):
>
> Interpreter>>#asciiOfCharacter: characterObj  "Returns an integer object"
>     <inline: false>
>     self assertClassOf: characterObj is: (self splObj: ClassCharacter).
>     successFlag
>         ifTrue: [^ self fetchPointer: CharacterValueIndex ofObject: characterObj]
>         ifFalse: [^ ConstZero]  "in case some code needs an int"


Guillermo when you change the specialObjectsArray it does not solve your problem?
I imagine that check a class pointer is way faster than looking in the method dict.
Now why when you change the specialObjectArray it does not solve your problem?
Do you need two?

Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

stephane ducasse-2
In reply to this post by Eliot Miranda-2

>
>
> I'm not uncalm :)  I just get frustrated with these performance arguments, having a coherent vision for better performance and having failed to make satisfactory progress.  The better object representation followed by more machine-code primitives step will get another factor of 2 and result in a simpler VM (immediate characters for example).  Speculative inlining/adaiptive optimizing in Smalltalk will get another factor of 3.  But I'm not paid to work on these things.  And I find having discussions about small points like this adds to my frustration because they're not getting us very far and I feel I'm wasting my breath.  Sorry...

I imagine that quite well.
Now the only thing that we can do are:
        - get pharo hyper sexy
        - build a powerful community (some people still did not get what we want to do: blossoming business)
        - get smart guys payed for what they are good at.

What guillermo and ben are doing around the bootstrap is part of step 1 :).

So any step in making the VM code cleaner is also important (unrelated to the question of guillermo)
because it will help making point 1 and 2.

Stef

PS: I applied another time to get a cool grant but I will probably miss it again this year.
Reply | Threaded
Open this post in threaded view
|

Re: Class checks in the vm

Guillermo Polito
In reply to this post by stephane ducasse-2
 


On Sat, Apr 21, 2012 at 9:50 PM, stephane ducasse <[hidden email]> wrote:

>
> I'm playing to bootstrap a Pharo image, trying to get a new environment running into my 'host' image, and after that, dump those new objects into a new image file.
>
> Now, to do that, I'm creating new classes for String, Character...  Which are well known by the vm specialObjectsArray.  And trying to initialize my new image classes, which creates new character objects, and new string objects which is causing me some troubles :P.
>
> Now, my question is about this check in vmmaker (and some others that look similar):
>
> Interpreter>>#asciiOfCharacter: characterObj  "Returns an integer object"
>     <inline: false>
>     self assertClassOf: characterObj is: (self splObj: ClassCharacter).
>     successFlag
>         ifTrue: [^ self fetchPointer: CharacterValueIndex ofObject: characterObj]
>         ifFalse: [^ ConstZero]  "in case some code needs an int"


Guillermo when you change the specialObjectsArray it does not solve your problem?
I imagine that check a class pointer is way faster than looking in the method dict.
Now why when you change the specialObjectArray it does not solve your problem?
Do you need two?

yes, or more :). (or none in the ideal case :( )