Read-only oldspace

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

Read-only oldspace

MrGwen
Hi,

If you read the squeak vm mailing they talk about read only objects.
But wait, we've read only why should we change it?? In GST it's done by
testing at "each" access if the object is RO or not. But we can do it
lazily by using the hardware and operating system. Objects can be putted
in a separate space with read-only access, thus we get a page fault when
you try to change an object.

I've implemented the first step a separate space for the *old* read-only
objects. I've first fixed a bug with the oldspace_nomemory each space
should have its own function. Thus there are for each space a
*space_nomemory, gst_init_mem_default initialize the new ro_oldspace.
The macro MAKE_OOP_READONLY calls the _gst_make_oop_readonly function:

* first I check if the oop ro state is the same as the new state; if
yes I leave.

* If the object is fixed or young I only change the state BUT if the
object is old it is moved inside a ro_oldspace if it  becomes RO or it's
moved from the ro_oldspace to the oldspace it is writeable

* gst_make_oop_fixed check if is old and remove the object from the
right space (oldspace or ro_old_space)

* the oldspace_nomemory, fixedspace_nomemory, ro_oldspace_nomemory returns
the correct heap ;-)

* _gst_compact: i'll compact the memory of both oldspace and
ro_oldspace, I don't use the new heap size to grow the ro_oldspace heap
size.
* _gst_sweep_oop is changed to free the memory from the right space ;-)
* the image loading is updated to take care of the ro_oldspace

I think it's all ;-)

Right now the ro mapping is not done but as Paolo said on IRC the patch
will give less false positive on grey page scanning.

Cheers,
Gwen

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

ro-space.patch (13K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Read-only oldspace

Holger Freyther
On 05/12/2011 05:16 PM, Gwenael Casaccio wrote:

> Hi,
>
> If you read the squeak vm mailing they talk about read only objects.
> But wait, we've read only why should we change it?? In GST it's done by
> testing at "each" access if the object is RO or not. But we can do it lazily
> by using the hardware and operating system. Objects can be putted in a
> separate space with read-only access, thus we get a page fault when you try to
> change an object.
>
>

How many read-only objects do we have in a bootstrapped image? In a typical
iliad application? Does it make sense to optimize for it? or will RO handling
just become more easy and this is a cleanup?

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

Re: Read-only oldspace

Paolo Bonzini-2
On 05/12/2011 05:24 PM, Holger Hans Peter Freyther wrote:
> How many read-only objects do we have in a bootstrapped image? In a typical
> iliad application? Does it make sense to optimize for it? or will RO handling
> just become more easy and this is a cleanup?

I think the point is to optimize _non_ read-only objects at the cost of
making tenuring read-only objects a bit more expensive (you will have to
unprotect the page, allocate, copy, protect the page).  We also win
read-only access to fixed instance variables, which GNU Smalltalk
doesn't have (only indexed instance variables are protected).

BTW, for the same reason I think that moving objects to read-only space
directly when you make them read-only (like you did for fixedspace) is a
good idea.  Anyway, read-only objects are mostly literals so they are
long-living.  Gwen, can you reorganize the patch along these lines?

The patch making readonly space, well, readonly should be a separate
one.  For unprotection/protection around allocation you can add hooks to
alloc.c heaps, like we have after_allocating: that would be
before_freeing, after_freeing, before_allocating.

Paolo

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

Re: Read-only oldspace

MrGwen
On 05/13/2011 08:46 AM, Paolo Bonzini wrote:

> On 05/12/2011 05:24 PM, Holger Hans Peter Freyther wrote:
>> How many read-only objects do we have in a bootstrapped image? In a
>> typical
>> iliad application? Does it make sense to optimize for it? or will RO
>> handling
>> just become more easy and this is a cleanup?
>
> I think the point is to optimize _non_ read-only objects at the cost of
> making tenuring read-only objects a bit more expensive (you will have to
> unprotect the page, allocate, copy, protect the page). We also win
> read-only access to fixed instance variables, which GNU Smalltalk
> doesn't have (only indexed instance variables are protected).
>
> BTW, for the same reason I think that moving objects to read-only space
> directly when you make them read-only (like you did for fixedspace) is a
> good idea. Anyway, read-only objects are mostly literals so they are
> long-living. Gwen, can you reorganize the patch along these lines?
>
> The patch making readonly space, well, readonly should be a separate
> one. For unprotection/protection around allocation you can add hooks to
> alloc.c heaps, like we have after_allocating: that would be
> before_freeing, after_freeing, before_allocating.
>
> Paolo
I've made the new patch, the ro_old space is like fixed. I've fixed
two bugs one in the symbol allocation and another when the ro_old heap
should grow.

Gwen

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

ro-space-for-paolo.patch (16K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Read-only oldspace

MrGwen
On 05/13/2011 04:32 PM, Gwenael Casaccio wrote:

> On 05/13/2011 08:46 AM, Paolo Bonzini wrote:
>> On 05/12/2011 05:24 PM, Holger Hans Peter Freyther wrote:
>>> How many read-only objects do we have in a bootstrapped image? In a
>>> typical
>>> iliad application? Does it make sense to optimize for it? or will RO
>>> handling
>>> just become more easy and this is a cleanup?
>>
>> I think the point is to optimize _non_ read-only objects at the cost of
>> making tenuring read-only objects a bit more expensive (you will have to
>> unprotect the page, allocate, copy, protect the page). We also win
>> read-only access to fixed instance variables, which GNU Smalltalk
>> doesn't have (only indexed instance variables are protected).
>>
>> BTW, for the same reason I think that moving objects to read-only space
>> directly when you make them read-only (like you did for fixedspace) is a
>> good idea. Anyway, read-only objects are mostly literals so they are
>> long-living. Gwen, can you reorganize the patch along these lines?
>>
>> The patch making readonly space, well, readonly should be a separate
>> one. For unprotection/protection around allocation you can add hooks to
>> alloc.c heaps, like we have after_allocating: that would be
>> before_freeing, after_freeing, before_allocating.
>>
>> Paolo
>
> I've made the new patch, the ro_old space is like fixed. I've fixed
> two bugs one in the symbol allocation and another when the ro_old heap
> should grow.
>
> Gwen
Hi,

Paolo can you check the patch, here I've changed a bit the behavior of
make_ro; I preserve F_FIXED, F_OLD, or young information thus when
making an object writable I can restore it in the good space.
It seems to be the definitive version

Gwen

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

ro-space-for-paolo.patch (18K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Read-only oldspace

Paolo Bonzini-2
> Paolo can you check the patch, here I've changed a bit the behavior of
> make_ro; I preserve F_FIXED, F_OLD, or young information thus when
> making an object writable I can restore it in the good space.
> It seems to be the definitive version

Just a few comments...

> +      /* become writeable */
> +      if ((oop->flags & F_LOADED) == 0)
> +        {
> +          if (oop->flags & F_FIXED)
> +            newObj = (gst_object) _gst_mem_alloc (_gst_mem.fixed, size);
> +          else if (oop->flags & F_OLD)
> +            newObj = (gst_object) _gst_mem_alloc (_gst_mem.old, size);
> +          else
> +            newObj = (gst_object) _gst_alloc_new_obj (size);

This can use _gst_alloc_obj.

> +  if (oop->flags & F_READONLY)
> +    {
> +      oop->flags |= F_FIXED;

Add a comment somewhere that rospace is never compacted.  As a
consequence...

>  gst_object
> +_gst_alloc_ro_obj (size_t size,
> +                    OOP *p_oop)
> +{
> +  gst_object p_instance;
> +
> +  size = ROUNDED_BYTES (size);
> +
> +  /* If the object is big enough, we put it directly in oldspace.  */
> +  p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size);
> +  if COMMON (p_instance)
> +    goto ok;
> +
> +  _gst_global_gc (size);
> +  p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size);
> +  if COMMON (p_instance)
> +    goto ok;
> +
> +  _gst_compact (0);
> +  p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size);

... the compaction step here is not necessary.

> @@ -889,25 +1054,43 @@ oldspace_before_freeing (heap_data *h, heap_block *blk, size_t sz)
>  }
>
>  heap_data *
> -oldspace_nomemory (heap_data *h, size_t sz)
> +grow_nomemory (heap_data *h, size_t sz)
>  {
>    if (!_gst_gc_running)
>      _gst_global_gc (sz);
>    else
>      {
>        /* Already garbage collecting, emergency growth just to satisfy
> - tenuring necessities.  */
> -      int grow_amount_to_satisfy_rate = _gst_mem.old->heap_limit
> +         tenuring necessities.  */
> +      int grow_amount_to_satisfy_rate = h->heap_limit
>             * (100.0 + _gst_mem.space_grow_rate) / 100;
> -      int grow_amount_to_satisfy_threshold =
> -   (sz + _gst_mem.old->heap_total)
> -   * 100.0 /_gst_mem.grow_threshold_percent;
> +      int grow_amount_to_satisfy_threshold =
> +           (sz + h->heap_total)
> +           * 100.0 /_gst_mem.grow_threshold_percent;
>
> -      _gst_mem.old->heap_limit = MAX (grow_amount_to_satisfy_rate,
> -      grow_amount_to_satisfy_threshold);
> +      h->heap_limit = MAX (grow_amount_to_satisfy_rate,
> +                           grow_amount_to_satisfy_threshold);
>      }
>
> -  return _gst_mem.old;
> +  return h;

This change to the "return" is wrong -- yes, it's tricky, I also
misremembered it the other day and probably didn't explain it well
enough on IRC.  _gst_mem.old could have changed due to the GC.  So just
make this function void...

> +}
> +
> +heap_data *
> +ro_oldspace_nomemory (heap_data *h, size_t sz)
> +{
> +  return grow_nomemory (_gst_mem.ro_old, sz);

... and return the appropriate space from these functions
(_gst_mem.ro_old here and likewise elsewhere).

> +          if (flags & F_READONLY)
> +            object = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size);
> +  else if (flags & F_FIXED)

This is bad unfortunately.  There are a _lot_ of readonly objects, and
allocating them will cause a measurable slowdown of image load.  I'm not
sure how you can fix that, perhaps by first storing readonly objects,
then page aligning the file, and then storing other objects.  Remember
that any slowdown incurred by image save is acceptable.

Otherwise looks good!  Have you measured a practical performance
difference with it?

Paolo

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

Re: Read-only oldspace

MrGwen
On 05/17/2011 02:33 PM, Paolo Bonzini wrote:

>> Paolo can you check the patch, here I've changed a bit the behavior of
>> make_ro; I preserve F_FIXED, F_OLD, or young information thus when
>> making an object writable I can restore it in the good space.
>> It seems to be the definitive version
>
> Just a few comments...
>
>> + /* become writeable */
>> + if ((oop->flags & F_LOADED) == 0)
>> + {
>> + if (oop->flags & F_FIXED)
>> + newObj = (gst_object) _gst_mem_alloc (_gst_mem.fixed, size);
>> + else if (oop->flags & F_OLD)
>> + newObj = (gst_object) _gst_mem_alloc (_gst_mem.old, size);
>> + else
>> + newObj = (gst_object) _gst_alloc_new_obj (size);
>
> This can use _gst_alloc_obj.
>
>> + if (oop->flags & F_READONLY)
>> + {
>> + oop->flags |= F_FIXED;
>
> Add a comment somewhere that rospace is never compacted. As a
> consequence...
>
>> gst_object
>> +_gst_alloc_ro_obj (size_t size,
>> + OOP *p_oop)
>> +{
>> + gst_object p_instance;
>> +
>> + size = ROUNDED_BYTES (size);
>> +
>> + /* If the object is big enough, we put it directly in oldspace. */
>> + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size);
>> + if COMMON (p_instance)
>> + goto ok;
>> +
>> + _gst_global_gc (size);
>> + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size);
>> + if COMMON (p_instance)
>> + goto ok;
>> +
>> + _gst_compact (0);
>> + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size);
>
> ... the compaction step here is not necessary.
>
>> @@ -889,25 +1054,43 @@ oldspace_before_freeing (heap_data *h,
>> heap_block *blk, size_t sz)
>> }
>>
>> heap_data *
>> -oldspace_nomemory (heap_data *h, size_t sz)
>> +grow_nomemory (heap_data *h, size_t sz)
>> {
>> if (!_gst_gc_running)
>> _gst_global_gc (sz);
>> else
>> {
>> /* Already garbage collecting, emergency growth just to satisfy
>> - tenuring necessities. */
>> - int grow_amount_to_satisfy_rate = _gst_mem.old->heap_limit
>> + tenuring necessities. */
>> + int grow_amount_to_satisfy_rate = h->heap_limit
>> * (100.0 + _gst_mem.space_grow_rate) / 100;
>> - int grow_amount_to_satisfy_threshold =
>> - (sz + _gst_mem.old->heap_total)
>> - * 100.0 /_gst_mem.grow_threshold_percent;
>> + int grow_amount_to_satisfy_threshold =
>> + (sz + h->heap_total)
>> + * 100.0 /_gst_mem.grow_threshold_percent;
>>
>> - _gst_mem.old->heap_limit = MAX (grow_amount_to_satisfy_rate,
>> - grow_amount_to_satisfy_threshold);
>> + h->heap_limit = MAX (grow_amount_to_satisfy_rate,
>> + grow_amount_to_satisfy_threshold);
>> }
>>
>> - return _gst_mem.old;
>> + return h;
>
> This change to the "return" is wrong -- yes, it's tricky, I also
> misremembered it the other day and probably didn't explain it well
> enough on IRC. _gst_mem.old could have changed due to the GC. So just
> make this function void...
>
>> +}
>> +
>> +heap_data *
>> +ro_oldspace_nomemory (heap_data *h, size_t sz)
>> +{
>> + return grow_nomemory (_gst_mem.ro_old, sz);
>
> ... and return the appropriate space from these functions
> (_gst_mem.ro_old here and likewise elsewhere).
>
>> + if (flags & F_READONLY)
>> + object = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size);
>> + else if (flags & F_FIXED)
>
> This is bad unfortunately. There are a _lot_ of readonly objects, and
> allocating them will cause a measurable slowdown of image load. I'm not
> sure how you can fix that, perhaps by first storing readonly objects,
> then page aligning the file, and then storing other objects. Remember
> that any slowdown incurred by image save is acceptable.
>
> Otherwise looks good! Have you measured a practical performance
> difference with it?
>
> Paolo


Paolo could I postpone the save issue to a third patch ?
Also I am thinking to float objects they shouldn't be by default
read only, but only when they are used as literals (ie in compiled method).

Gwen

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

Re: Read-only oldspace

Paolo Bonzini-2
On 05/17/2011 10:39 PM, Gwenael Casaccio wrote:
>>>
>>
>> This is bad unfortunately. There are a _lot_ of readonly objects, and
>> allocating them will cause a measurable slowdown of image load. I'm not
>> sure how you can fix that, perhaps by first storing readonly objects,
>> then page aligning the file, and then storing other objects. Remember
>> that any slowdown incurred by image save is acceptable.
>
> Paolo could I postpone the save issue to a third patch ?

You can commit this patch to your repo and start working on it. :)

Paolo

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

Re: Read-only oldspace

MrGwen
On 05/18/2011 09:37 AM, Paolo Bonzini wrote:

> On 05/17/2011 10:39 PM, Gwenael Casaccio wrote:
>>>>
>>>
>>> This is bad unfortunately. There are a _lot_ of readonly objects, and
>>> allocating them will cause a measurable slowdown of image load. I'm not
>>> sure how you can fix that, perhaps by first storing readonly objects,
>>> then page aligning the file, and then storing other objects. Remember
>>> that any slowdown incurred by image save is acceptable.
>>
>> Paolo could I postpone the save issue to a third patch ?
>
> You can commit this patch to your repo and start working on it. :)
>
> Paolo

Is it what you want for the image saving ?

https://github.com/MrGwen/GNU-Smalltalk/commit/0372cfe08977da6d1d5cb8cecf2d7796f5375593

Gwen

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

Re: Read-only oldspace

Paolo Bonzini-2
On 05/25/2011 11:31 AM, Gwenael Casaccio wrote:
>
> Is it what you want for the image saving ?
>
> https://github.com/MrGwen/GNU-Smalltalk/commit/0372cfe08977da6d1d5cb8cecf2d7796f5375593

Yes!  Just:

1) no cut-and-paste :)

2) if "use_copy_on_write" is true, you should mmap the read-only data to
a separate memory region, so that you can make it read-only too.
Perhaps you need to invoke mmap separately instead of doing it just once
at the beginning of the loading.

Paolo

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

Re: Read-only oldspace

MrGwen
On 05/25/2011 06:13 PM, Paolo Bonzini wrote:

> On 05/25/2011 11:31 AM, Gwenael Casaccio wrote:
>>
>> Is it what you want for the image saving ?
>>
>> https://github.com/MrGwen/GNU-Smalltalk/commit/0372cfe08977da6d1d5cb8cecf2d7796f5375593
>>
>
> Yes! Just:
>
> 1) no cut-and-paste :)
>
> 2) if "use_copy_on_write" is true, you should mmap the read-only data to
> a separate memory region, so that you can make it read-only too. Perhaps
> you need to invoke mmap separately instead of doing it just once at the
> beginning of the loading.
>
> Paolo


Hi,

I use a separate memory region for the ro space when loading and
refactor a bit :)

https://github.com/MrGwen/GNU-Smalltalk/commit/a6c6aa267b12bf59169ef5c67f6fd1a016e32e7b

Gwen

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

Re: Read-only oldspace

MrGwen
Here is the complete ro patch Paolo

Gwen

On Fri, May 27, 2011 at 1:01 PM, Gwenael Casaccio <[hidden email]> wrote:

> On 05/25/2011 06:13 PM, Paolo Bonzini wrote:
>>
>> On 05/25/2011 11:31 AM, Gwenael Casaccio wrote:
>>>
>>> Is it what you want for the image saving ?
>>>
>>>
>>> https://github.com/MrGwen/GNU-Smalltalk/commit/0372cfe08977da6d1d5cb8cecf2d7796f5375593
>>>
>>
>> Yes! Just:
>>
>> 1) no cut-and-paste :)
>>
>> 2) if "use_copy_on_write" is true, you should mmap the read-only data to
>> a separate memory region, so that you can make it read-only too. Perhaps
>> you need to invoke mmap separately instead of doing it just once at the
>> beginning of the loading.
>>
>> Paolo
>
>
> Hi,
>
> I use a separate memory region for the ro space when loading and refactor a
> bit :)
>
> https://github.com/MrGwen/GNU-Smalltalk/commit/a6c6aa267b12bf59169ef5c67f6fd1a016e32e7b
>
> Gwen
>

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

ro_space_for_paolo.patch (133K) Download Attachment