More finalization enhancements

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

More finalization enhancements

Levente Uzonyi-2
Hi,

I have two other ideas to enhance finalization:
1. If WeakKeyDictionary's finalizer is nil, then #finalizeValues can
return immediately, because if finalizer is nil, we just have to throw
away the associations which key became nil. The suggested change postpones
the removal of elements from the dictionary until rehash, grow or a
(lucky) removal happens. It can save a lot of time if there are large
WeakKeyDictionaries around (which can easily happen if you load Monticello
packages).
2. There should be a way to add multiple finalizers for a
single object. Currently if you send #toFinalizeSend:to:with: to an
object, it creates an ObjectFinalizer and adds it to the current
finalization registry. If you send it one more time to the same
object, the first finalizer will be lost. I see two possible solutions:
  (a) change WeakRegistry to store multiple finalizers per object
  (b) same as (a), but in a subclass of WeakRegistry and Object >>
#finalizationRegistry returns and instance of this subclass

Ideas? Opinions?


Cheers,
Levente

Reply | Threaded
Open this post in threaded view
|

Re: More finalization enhancements

Levente Uzonyi-2
I came to the decision that 1. is a bad idea, because currently there
is no WeakKeyDictionary which has a finalizer, because it's a new
feature. This means that every WeakKeyDictionary would keep references to
the finalizers until a rehash, grow or a (lucky) removal happens and that
may means "almost forever". So the real solution to the slowdown described
in 1. is to remove the cache of MCMethodDefinition from WeakArray's
weakDependents which is safe to do IMHO.

I uploaded an example implementation of 2b to the Inbox, you can try it
from an updated trunk image if you execute this:

(Installer squeakfoundation project: 'inbox')
  install: 'System-ul.263.mcz';
  install: 'Collections-ul.318.mcz';
  install: 'CollectionsTests-ul.148.mcz'


I think we can't get much better finalization performance/features without
VM support if 2. gets into the Trunk in some form, so I'm going to focus
on Streams again.

My short term plan is to rewrite all methods which send #*FileNamed: and
#close to FileStream (or a subclass) to use the #*FileNamed:do: method.
This is better since it ensures that the file is always closed and it's
closed at the right time. This will cause changes in a lot of packages.
If that's done, I'll try to refactor the #*FileNamed:do: methods to open
and close the file without registering it to the finalization registry.
This way opening and closing files will cost less if they are used in a
limited scope.
If that's done too, I'll try to speed up file opening/closing even more.
This involves changes of TextConverter and String too.
If that's all done, we may use readonly copies of the source files
instead of shared globals without much slowdown.

In the meantime I'm still working on the method trailer refactorings so
accessing source files will be even faster.


Levente

On Mon, 22 Feb 2010, Levente Uzonyi wrote:

> Hi,
>
> I have two other ideas to enhance finalization:
> 1. If WeakKeyDictionary's finalizer is nil, then #finalizeValues can return
> immediately, because if finalizer is nil, we just have to throw away the
> associations which key became nil. The suggested change postpones the removal
> of elements from the dictionary until rehash, grow or a (lucky) removal
> happens. It can save a lot of time if there are large WeakKeyDictionaries
> around (which can easily happen if you load Monticello packages).
> 2. There should be a way to add multiple finalizers for a single object.
> Currently if you send #toFinalizeSend:to:with: to an object, it creates an
> ObjectFinalizer and adds it to the current finalization registry. If you send
> it one more time to the same object, the first finalizer will be lost. I see
> two possible solutions:
> (a) change WeakRegistry to store multiple finalizers per object
> (b) same as (a), but in a subclass of WeakRegistry and Object >>
> #finalizationRegistry returns and instance of this subclass
>
> Ideas? Opinions?
>
>
> Cheers,
> Levente
>
>

Reply | Threaded
Open this post in threaded view
|

Re: More finalization enhancements

Levente Uzonyi-2
As you probably noticed, I pushed the changes which implement 2a to the
Trunk. For 1. I uploaded two packages to the Inbox. To try them evaluate
this:

(Installer squeakfoundation project: 'inbox')
  install: 'Monticello-ul.372.mcz';
  install: 'Monticello-ul.373.mcz'


Levente

On Wed, 24 Feb 2010, Levente Uzonyi wrote:

> I came to the decision that 1. is a bad idea, because currently there is no
> WeakKeyDictionary which has a finalizer, because it's a new feature. This
> means that every WeakKeyDictionary would keep references to the finalizers
> until a rehash, grow or a (lucky) removal happens and that may means "almost
> forever". So the real solution to the slowdown described in 1. is to remove
> the cache of MCMethodDefinition from WeakArray's weakDependents which is safe
> to do IMHO.
>
> I uploaded an example implementation of 2b to the Inbox, you can try it from
> an updated trunk image if you execute this:
>
> (Installer squeakfoundation project: 'inbox')
> install: 'System-ul.263.mcz';
> install: 'Collections-ul.318.mcz';
> install: 'CollectionsTests-ul.148.mcz'
>
>
> I think we can't get much better finalization performance/features without VM
> support if 2. gets into the Trunk in some form, so I'm going to focus on
> Streams again.
>
> My short term plan is to rewrite all methods which send #*FileNamed: and
> #close to FileStream (or a subclass) to use the #*FileNamed:do: method. This
> is better since it ensures that the file is always closed and it's closed at
> the right time. This will cause changes in a lot of packages.
> If that's done, I'll try to refactor the #*FileNamed:do: methods to open and
> close the file without registering it to the finalization registry. This way
> opening and closing files will cost less if they are used in a limited scope.
> If that's done too, I'll try to speed up file opening/closing even more. This
> involves changes of TextConverter and String too.
> If that's all done, we may use readonly copies of the source files instead of
> shared globals without much slowdown.
>
> In the meantime I'm still working on the method trailer refactorings so
> accessing source files will be even faster.
>
>
> Levente
>
> On Mon, 22 Feb 2010, Levente Uzonyi wrote:
>
>> Hi,
>>
>> I have two other ideas to enhance finalization:
>> 1. If WeakKeyDictionary's finalizer is nil, then #finalizeValues can return
>> immediately, because if finalizer is nil, we just have to throw away the
>> associations which key became nil. The suggested change postpones the
>> removal of elements from the dictionary until rehash, grow or a (lucky)
>> removal happens. It can save a lot of time if there are large
>> WeakKeyDictionaries around (which can easily happen if you load Monticello
>> packages).
>> 2. There should be a way to add multiple finalizers for a single object.
>> Currently if you send #toFinalizeSend:to:with: to an object, it creates an
>> ObjectFinalizer and adds it to the current finalization registry. If you
>> send it one more time to the same object, the first finalizer will be lost.
>> I see two possible solutions:
>> (a) change WeakRegistry to store multiple finalizers per object
>> (b) same as (a), but in a subclass of WeakRegistry and Object >>
>> #finalizationRegistry returns and instance of this subclass
>>
>> Ideas? Opinions?
>>
>>
>> Cheers,
>> Levente
>>
>>
>
>