ReadOnly

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

ReadOnly

Gwenaël Casaccio
Hi,

   The current implementation of the read-only support is not finished
a read-only object can change the value of an instance variable.
So I've made two implementations of the read-only the first with
a write barrier using sigsegv and the other checking the read-only
bit.

   The write barrier implementation uses the fixed space as a
read-only space after the allocation and the copy of the object
to the space the pages are marked read only and registered to
a read_ony_space_handler. Before the STORE_RECEIVER_ operation in vm.def
the interpreter state is exported. Once a write is done
oldspace_sigsegv_handler
is called and a check is done to see it's a read-only page or not (using
sigsegv library)
the read-only space handler is called and does a long jump in the
interpreter. I send
a message to _gst_self.

   The other implementation uses the bit check, nothing really special
here :) I've made
a simple "benchmark" and the difference between both approaches is not
really noticeable.
Frankly speaking I don't know what is the best approach to use (using
write barrier or not).
I think it could be nice to use an other heap for the read only objects:
there are less wrong
positive with grey pages.

   I see at least two issues the first with C programs and the write
barrier that uses
libgst and write an object directly the handler is not correct in that
case.
Second issue - in both cases - with the bytecode set for instance if
it's the bc 80
and I send an tryToWriteAt::put: message and if the code simply returns
it's
going to crash.

Gwen


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: ReadOnly

Paolo Bonzini-2
Il 06/11/2013 10:25, Gwenaël Casaccio ha scritto:
> The other implementation uses the bit check, nothing really special
> here :) I've made
> a simple "benchmark" and the difference between both approaches is not
> really noticeable.
> Frankly speaking I don't know what is the best approach to use (using
> write barrier or not).
> I think it could be nice to use an other heap for the read only objects:
> there are less wrong
> positive with grey pages.

I think most read-only objects are old (and mmap-ed directly from the
image) anyway, so it shouldn't be a big change.

>   I see at least two issues the first with C programs and the write
> barrier that uses
> libgst and write an object directly the handler is not correct in that
> case.

Yes, C programs might expect to be able to write to read-only objects.

> Second issue - in both cases - with the bytecode set for instance if
> it's the bc 80
> and I send an tryToWriteAt::put: message and if the code simply returns
> it's
> going to crash.

I think whatever #tryToWriteAt:put: returns should be left on the stack.
 So this:


    Object subclass: A [
         | a |
         tryToWriteAt: index put: object [ ^42 ]
         test [ (a := 123) printNl. a printNl ]
    ]

    Eval [
        A new
            makeReadOnly: true;
            test
    ]

should print

    42           "result of #tryToWriteAt:put:"
    nil          "nothing was stored actually"

Paolo

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: ReadOnly

Gwenaël Casaccio
On 06/11/2013 13:05, Paolo Bonzini wrote:

> Il 06/11/2013 10:25, Gwenaël Casaccio ha scritto:
>> The other implementation uses the bit check, nothing really special
>> here :) I've made
>> a simple "benchmark" and the difference between both approaches is not
>> really noticeable.
>> Frankly speaking I don't know what is the best approach to use (using
>> write barrier or not).
>> I think it could be nice to use an other heap for the read only objects:
>> there are less wrong
>> positive with grey pages.
> I think most read-only objects are old (and mmap-ed directly from the
> image) anyway, so it shouldn't be a big change.
You've right

>>    I see at least two issues the first with C programs and the write
>> barrier that uses
>> libgst and write an object directly the handler is not correct in that
>> case.
> Yes, C programs might expect to be able to write to read-only objects.
>
>> Second issue - in both cases - with the bytecode set for instance if
>> it's the bc 80
>> and I send an tryToWriteAt::put: message and if the code simply returns
>> it's
>> going to crash.
> I think whatever #tryToWriteAt:put: returns should be left on the stack.
>   So this:
>
>
>      Object subclass: A [
>           | a |
>           tryToWriteAt: index put: object [ ^42 ]
>           test [ (a := 123) printNl. a printNl ]
>      ]
>
>      Eval [
>          A new
>              makeReadOnly: true;
>              test
>      ]
>
> should print
>
>      42           "result of #tryToWriteAt:put:"
>      nil          "nothing was stored actually"
>
> Paolo

Yes I agree for the stack, I'm thinking about the bytecode combination
if in the bc 80
I send a message when it leave the message the ip is the next ip and it
will go to the next
instruction and for the bc 80 it's bad because it's the last
instruction, if I'm  right.

Gwen


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: ReadOnly

Gwenaël Casaccio
On 06/11/2013 20:56, Gwenaël Casaccio wrote:

> On 06/11/2013 13:05, Paolo Bonzini wrote:
>> Il 06/11/2013 10:25, Gwenaël Casaccio ha scritto:
>>> The other implementation uses the bit check, nothing really special
>>> here :) I've made
>>> a simple "benchmark" and the difference between both approaches is not
>>> really noticeable.
>>> Frankly speaking I don't know what is the best approach to use (using
>>> write barrier or not).
>>> I think it could be nice to use an other heap for the read only
>>> objects:
>>> there are less wrong
>>> positive with grey pages.
>> I think most read-only objects are old (and mmap-ed directly from the
>> image) anyway, so it shouldn't be a big change.
> You've right
>>>    I see at least two issues the first with C programs and the write
>>> barrier that uses
>>> libgst and write an object directly the handler is not correct in that
>>> case.
>> Yes, C programs might expect to be able to write to read-only objects.
>>
>>> Second issue - in both cases - with the bytecode set for instance if
>>> it's the bc 80
>>> and I send an tryToWriteAt::put: message and if the code simply returns
>>> it's
>>> going to crash.
>> I think whatever #tryToWriteAt:put: returns should be left on the stack.
>>   So this:
>>
>>
>>      Object subclass: A [
>>           | a |
>>           tryToWriteAt: index put: object [ ^42 ]
>>           test [ (a := 123) printNl. a printNl ]
>>      ]
>>
>>      Eval [
>>          A new
>>              makeReadOnly: true;
>>              test
>>      ]
>>
>> should print
>>
>>      42           "result of #tryToWriteAt:put:"
>>      nil          "nothing was stored actually"
>>
>> Paolo
>
> Yes I agree for the stack, I'm thinking about the bytecode combination
> if in the bc 80
> I send a message when it leave the message the ip is the next ip and
> it will go to the next
> instruction and for the bc 80 it's bad because it's the last
> instruction, if I'm  right.
>
> Gwen
>
Here is a first attempt to add RO supports what do you think ?

Gwen


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

0001-Read-only-objects.patch (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: ReadOnly

Paolo Bonzini-2
In reply to this post by Gwenaël Casaccio
Il 06/11/2013 20:56, Gwenaël Casaccio ha scritto:
>
> Yes I agree for the stack, I'm thinking about the bytecode combination
> if in the bc 80
> I send a message when it leave the message the ip is the next ip and it
> will go to the next
> instruction and for the bc 80 it's bad because it's the last
> instruction, if I'm  right.

Ah, I see now.

In general if a (basic) bytecode can send, it can only be the
last message of a compound bytecode.  See this part of superops.cc

    " allSuperoperatorBreaks ["
    "     | breaks |"
    "     breaks := SortedCollection new."
    "     self allByteCodeIndicesDo: [ :i :b :op |"
    ///////// "Split where jumps land"
    "         (b >= 40 and: [ b <= 43 ])"
    "            ifTrue: [ breaks add: (self jumpDestinationAt: i forward: b > 40) ]."

    ///////// "Split after returns"
    "         (b >= 50 and: [ b <= 51 ])"
    "            ifTrue: [ breaks add: (self nextBytecodeIndex: i) ]."

    ///////// "Split after jumps"
    "         (b >= 40 and: [ b <= 43 ])"
    "            ifTrue: [ breaks add: (self nextBytecodeIndex: i) ]."

    ///////// "Split after push/store literal variable"
    "         (b = 34 or: [ b = 38 ])"
    "            ifTrue: [ breaks add: (self nextBytecodeIndex: i) ]."

    ///////// "Split after sends"
    "         (b < 32 and: [ (b + 12 bitAnd: 250) ~= 32 ])"
    "            ifTrue: [ breaks add: (self nextBytecodeIndex: i) ]"
    "     ]."
    "     ^breaks ]"

It splits after push/store literal variable because it sends #value and
#value: respectively.  You would have to split after store instance variable
too, and regenerate the superoperators.

Paolo

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk