The Trunk: Kernel-ul.709.mcz

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

The Trunk: Kernel-ul.709.mcz

commits-2
Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.709.mcz

==================== Summary ====================

Name: Kernel-ul.709
Author: ul
Time: 4 September 2012, 12:42:11.196 am
UUID: 359e6dd2-5981-ae43-a5bd-c687dd1d5614
Ancestors: Kernel-eem.708

Various changes:
- improved Object >> #inboundPointersExcluding:. Better results (less noise) and performance. Uses a marker object instead of 0.
- introduced ProtoObject >> #pointsOnlyWeaklyTo: which returns true if the receiver only has a weak reference to the argument, otherwise false. The reason why it's in ProtoObject is that #pointsTo: is there too. Implementation from Pharo by Igor Stasenko.
- added Process >> #environmentAt:ifAbsentPut: which is useful for direct manipulation of the environment of Processes
- introduced Behavior >> #isCompact and changed two methods which can use this method directly

=============== Diff against Kernel-eem.708 ===============

Item was changed:
  ----- Method: Behavior>>becomeCompact (in category 'private') -----
  becomeCompact
  "Here are the restrictions on compact classes in order for export segments to work:  A compact class index may not be reused.  If a class was compact in a release of Squeak, no other class may use that index.  The class might not be compact later, and there should be nil in its place in the array."
  | cct index |
 
  self isWeak ifTrue:[^ self halt: 'You must not make a weak class compact'].
  cct := Smalltalk compactClassesArray.
+ (self isCompact or: [cct includes: self])
- (self indexIfCompact > 0 or: [cct includes: self])
  ifTrue: [^ self halt: self name , 'is already compact'].
  index := cct indexOf: nil
  ifAbsent: [^ self halt: 'compact class table is full'].
  "Install this class in the compact class table"
  cct at: index put: self.
  "Update instspec so future instances will be compact"
  format := format + (index bitShift: 11).
  "Make up new instances and become old ones into them"
  self updateInstancesFrom: self.
  "Purge any old instances"
  Smalltalk garbageCollect.!

Item was changed:
  ----- Method: Behavior>>becomeCompactSimplyAt: (in category 'private') -----
  becomeCompactSimplyAt: index
  "Make me compact, but don't update the instances.  For importing segments."
  "Here are the restrictions on compact classes in order for export segments to work:  A compact class index may not be reused.  If a class was compact in a release of Squeak, no other class may use that index.  The class might not be compact later, and there should be nil in its place in the array."
  | cct |
 
  self isWeak ifTrue:[^ self halt: 'You must not make a weak class compact'].
  cct := Smalltalk compactClassesArray.
+ (self isCompact or: [cct includes: self])
- (self indexIfCompact > 0 or: [cct includes: self])
  ifTrue: [^ self halt: self name , 'is already compact'].
  (cct at: index) ifNotNil: [^ self halt: 'compact table slot already in use'].
  "Install this class in the compact class table"
  cct at: index put: self.
  "Update instspec so future instances will be compact"
  format := format + (index bitShift: 11).
  "Caller must convert the instances"
  !

Item was added:
+ ----- Method: Behavior>>isCompact (in category 'testing') -----
+ isCompact
+
+ ^self indexIfCompact ~= 0!

Item was changed:
  ----- Method: Object>>inboundPointersExcluding: (in category 'tracing') -----
  inboundPointersExcluding: objectsToExclude
+ "Answer a list of all objects in the system that hold a reference to me, excluding those in the collection of objectsToExclude."
- "Answer a list of all objects in the system that point to me, excluding those in the collection of objectsToExclude. I do my best to avoid creating any temporary objects that point to myself, especially method and block contexts. Adapted from PointerFinder class >> #pointersTo:except:"
 
+ | pointers object objectsToAlwaysExclude |
- | anObj pointers objectsToAlwaysExclude |
  Smalltalk garbageCollect.
+ pointers := OrderedCollection new.
+ "SystemNavigation >> #allObjectsDo: is inlined here with a slight modification: the marker object is pointers. This gives better results, because the value of pointers, it's inner objects and transient method contexts will not be iterated over."
+ object := self someObject.
+ [ object == pointers ] whileFalse: [
+ (object isInMemory and: [ object pointsTo: self ]) ifTrue: [
+ pointers add: object ].
+ object := object nextObject ].
- "big collection shouldn't grow, so it's contents array is always the same"
- pointers := OrderedCollection new: 1000.
-
- "#allObjectsDo: and #pointsTo: are expanded inline to keep spurious
- method and block contexts out of the results"
- anObj := self someObject.
- [0 == anObj] whileFalse: [ "We must use #== here, to avoid leaving the loop when anObj is another number that's equal to 0 (e.g. 0.0)."
- anObj isInMemory
- ifTrue: [((anObj instVarsInclude: self)
- or: [anObj class == self])
- ifTrue: [pointers add: anObj]].
- anObj := anObj nextObject].
-
  objectsToAlwaysExclude := {
- pointers collector.
  thisContext.
  thisContext sender.
  thisContext sender sender.
  objectsToExclude.
  }.
+ ^pointers removeAllSuchThat: [ :ea |
-
- ^ pointers removeAllSuchThat: [:ea |
  (objectsToAlwaysExclude identityIncludes: ea)
+ or: [ objectsToExclude identityIncludes: ea ] ]!
- or: [objectsToExclude identityIncludes: ea]]!

Item was added:
+ ----- Method: Process>>environmentAt:ifAbsentPut: (in category 'process specific') -----
+ environmentAt: key ifAbsentPut: aBlock
+
+ ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut: aBlock.!

Item was added:
+ ----- Method: ProtoObject>>pointsOnlyWeaklyTo: (in category 'tracing') -----
+ pointsOnlyWeaklyTo: anObject
+ "Assume, we already know that receiver points to an object, answer true if receiver points only weakly to it."
+
+ self class isWeak ifFalse: [ ^false ].
+ 1 to: self class instSize do: [ :i |
+ (self instVarAt: i) == anObject ifTrue: [ ^false ] ].
+ ^true!


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Frank Shearar-3
On 4 September 2012 00:06,  <[hidden email]> wrote:

> Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-ul.709.mcz
>
> ==================== Summary ====================
>
> Name: Kernel-ul.709
> Author: ul
> Time: 4 September 2012, 12:42:11.196 am
> UUID: 359e6dd2-5981-ae43-a5bd-c687dd1d5614
> Ancestors: Kernel-eem.708
>
> Various changes:
> - improved Object >> #inboundPointersExcluding:. Better results (less noise) and performance. Uses a marker object instead of 0.
> - introduced ProtoObject >> #pointsOnlyWeaklyTo: which returns true if the receiver only has a weak reference to the argument, otherwise false. The reason why it's in ProtoObject is that #pointsTo: is there too. Implementation from Pharo by Igor Stasenko.
> - added Process >> #environmentAt:ifAbsentPut: which is useful for direct manipulation of the environment of Processes
> - introduced Behavior >> #isCompact and changed two methods which can use this method directly
>
> =============== Diff against Kernel-eem.708 ===============
>
> Item was changed:
>   ----- Method: Behavior>>becomeCompact (in category 'private') -----
>   becomeCompact
>         "Here are the restrictions on compact classes in order for export segments to work:  A compact class index may not be reused.  If a class was compact in a release of Squeak, no other class may use that index.  The class might not be compact later, and there should be nil in its place in the array."
>         | cct index |
>
>         self isWeak ifTrue:[^ self halt: 'You must not make a weak class compact'].
>         cct := Smalltalk compactClassesArray.
> +       (self isCompact or: [cct includes: self])
> -       (self indexIfCompact > 0 or: [cct includes: self])
>                 ifTrue: [^ self halt: self name , 'is already compact'].
>         index := cct indexOf: nil
>                 ifAbsent: [^ self halt: 'compact class table is full'].
>         "Install this class in the compact class table"
>         cct at: index put: self.
>         "Update instspec so future instances will be compact"
>         format := format + (index bitShift: 11).
>         "Make up new instances and become old ones into them"
>         self updateInstancesFrom: self.
>         "Purge any old instances"
>         Smalltalk garbageCollect.!
>
> Item was changed:
>   ----- Method: Behavior>>becomeCompactSimplyAt: (in category 'private') -----
>   becomeCompactSimplyAt: index
>         "Make me compact, but don't update the instances.  For importing segments."
>   "Here are the restrictions on compact classes in order for export segments to work:  A compact class index may not be reused.  If a class was compact in a release of Squeak, no other class may use that index.  The class might not be compact later, and there should be nil in its place in the array."
>         | cct |
>
>         self isWeak ifTrue:[^ self halt: 'You must not make a weak class compact'].
>         cct := Smalltalk compactClassesArray.
> +       (self isCompact or: [cct includes: self])
> -       (self indexIfCompact > 0 or: [cct includes: self])
>                 ifTrue: [^ self halt: self name , 'is already compact'].
>         (cct at: index) ifNotNil: [^ self halt: 'compact table slot already in use'].
>         "Install this class in the compact class table"
>         cct at: index put: self.
>         "Update instspec so future instances will be compact"
>         format := format + (index bitShift: 11).
>         "Caller must convert the instances"
>   !
>
> Item was added:
> + ----- Method: Behavior>>isCompact (in category 'testing') -----
> + isCompact
> +
> +       ^self indexIfCompact ~= 0!
>
> Item was changed:
>   ----- Method: Object>>inboundPointersExcluding: (in category 'tracing') -----
>   inboundPointersExcluding: objectsToExclude
> +       "Answer a list of all objects in the system that hold a reference to me, excluding those in the collection of objectsToExclude."
> - "Answer a list of all objects in the system that point to me, excluding those in the collection of objectsToExclude. I do my best to avoid creating any temporary objects that point to myself, especially method and block contexts. Adapted from PointerFinder class >> #pointersTo:except:"
>
> +       | pointers object objectsToAlwaysExclude |
> -       | anObj pointers objectsToAlwaysExclude |
>         Smalltalk garbageCollect.
> +       pointers := OrderedCollection new.
> +       "SystemNavigation >> #allObjectsDo: is inlined here with a slight modification: the marker object is pointers. This gives better results, because the value of pointers, it's inner objects and transient method contexts will not be iterated over."
> +       object := self someObject.
> +       [ object == pointers ] whileFalse: [
> +               (object isInMemory and: [ object pointsTo: self ]) ifTrue: [
> +                       pointers add: object ].
> +               object := object nextObject ].
> -       "big collection shouldn't grow, so it's contents array is always the same"
> -       pointers := OrderedCollection new: 1000.
> -
> -       "#allObjectsDo: and #pointsTo: are expanded inline to keep spurious
> -        method and block contexts out of the results"
> -       anObj := self someObject.
> -       [0 == anObj] whileFalse: [ "We must use #== here, to avoid leaving the loop when anObj is another number that's equal to 0 (e.g. 0.0)."
> -               anObj isInMemory
> -                       ifTrue: [((anObj instVarsInclude: self)
> -                               or: [anObj class == self])
> -                                       ifTrue: [pointers add: anObj]].
> -               anObj := anObj nextObject].
> -
>         objectsToAlwaysExclude := {
> -               pointers collector.
>                 thisContext.
>                 thisContext sender.
>                 thisContext sender sender.
>                 objectsToExclude.
>         }.
> +       ^pointers removeAllSuchThat: [ :ea |
> -
> -       ^ pointers removeAllSuchThat: [:ea |
>                 (objectsToAlwaysExclude identityIncludes: ea)
> +                       or: [ objectsToExclude identityIncludes: ea ] ]!
> -                       or: [objectsToExclude identityIncludes: ea]]!
>
> Item was added:
> + ----- Method: Process>>environmentAt:ifAbsentPut: (in category 'process specific') -----
> + environmentAt: key ifAbsentPut: aBlock
> +
> +       ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut: aBlock.!

Given that Process >> #environmentAt:put: says "^ (env ifNil: [ env :=
Dictionary new ]) at: key put: value" wouldn't it be better to defer
the dictionary creation to it, or pull the two initialisation places
into one, separate, place?

frank

> Item was added:
> + ----- Method: ProtoObject>>pointsOnlyWeaklyTo: (in category 'tracing') -----
> + pointsOnlyWeaklyTo: anObject
> +       "Assume, we already know that receiver points to an object, answer true if receiver points only weakly to it."
> +
> +       self class isWeak ifFalse: [ ^false ].
> +       1 to: self class instSize do: [ :i |
> +               (self instVarAt: i) == anObject ifTrue: [ ^false ] ].
> +       ^true!
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Levente Uzonyi-2
On Tue, 4 Sep 2012, Frank Shearar wrote:

> On 4 September 2012 00:06,  <[hidden email]> wrote:
>> Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
>> Item was added:
>> + ----- Method: Process>>environmentAt:ifAbsentPut: (in category 'process specific') -----
>> + environmentAt: key ifAbsentPut: aBlock
>> +
>> +       ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut: aBlock.!
>
> Given that Process >> #environmentAt:put: says "^ (env ifNil: [ env :=
> Dictionary new ]) at: key put: value" wouldn't it be better to defer
> the dictionary creation to it, or pull the two initialisation places
> into one, separate, place?

There are three things to consider:
- do we want to expose the dictionary itself?
- performance
- single initialization point

I picked the implementation with better performance and didn't want to
expose the dictionary. We can also have a single initialization point but
the code looks a bit unusual (at least to me):

Process >> #ensureEnvironment

  env ifNil: [ env := Dictionary new ]

Process >> #environmentAt: key put: value

  env ifNil: [ self ensureEnvironment ].
  ^env at: key put: value

Process >> #environmentAt: key ifAbsentPut: aBlock

  env ifNil: [ self ensureEnvironment ].
  ^env at: key ifAbsentPut: aBlock

I can push a new version if you like this implementation more.


Levente

>
> frank
>
>> Item was added:
>> + ----- Method: ProtoObject>>pointsOnlyWeaklyTo: (in category 'tracing') -----
>> + pointsOnlyWeaklyTo: anObject
>> +       "Assume, we already know that receiver points to an object, answer true if receiver points only weakly to it."
>> +
>> +       self class isWeak ifFalse: [ ^false ].
>> +       1 to: self class instSize do: [ :i |
>> +               (self instVarAt: i) == anObject ifTrue: [ ^false ] ].
>> +       ^true!
>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Frank Shearar-3
On 4 September 2012 14:37, Levente Uzonyi <[hidden email]> wrote:

> On Tue, 4 Sep 2012, Frank Shearar wrote:
>
>> On 4 September 2012 00:06,  <[hidden email]> wrote:
>>>
>>> Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
>>> Item was added:
>>> + ----- Method: Process>>environmentAt:ifAbsentPut: (in category 'process
>>> specific') -----
>>> + environmentAt: key ifAbsentPut: aBlock
>>> +
>>> +       ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut:
>>> aBlock.!
>>
>>
>> Given that Process >> #environmentAt:put: says "^ (env ifNil: [ env :=
>> Dictionary new ]) at: key put: value" wouldn't it be better to defer
>> the dictionary creation to it, or pull the two initialisation places
>> into one, separate, place?
>
>
> There are three things to consider:
> - do we want to expose the dictionary itself?
> - performance
> - single initialization point
>
> I picked the implementation with better performance and didn't want to
> expose the dictionary. We can also have a single initialization point but
> the code looks a bit unusual (at least to me):
>
> Process >> #ensureEnvironment
>
>
>         env ifNil: [ env := Dictionary new ]
>
> Process >> #environmentAt: key put: value
>
>         env ifNil: [ self ensureEnvironment ].
>         ^env at: key put: value
>
> Process >> #environmentAt: key ifAbsentPut: aBlock
>
>         env ifNil: [ self ensureEnvironment ].
>         ^env at: key ifAbsentPut: aBlock
>
> I can push a new version if you like this implementation more.

I suppose using a method that does the initialisation's too much of a
hit? Having a #environment that said "^ env ifNil: []" would be too
expensive?

frank

> Levente
>
>
>>
>> frank
>>
>>> Item was added:
>>> + ----- Method: ProtoObject>>pointsOnlyWeaklyTo: (in category 'tracing')
>>> -----
>>> + pointsOnlyWeaklyTo: anObject
>>> +       "Assume, we already know that receiver points to an object,
>>> answer true if receiver points only weakly to it."
>>> +
>>> +       self class isWeak ifFalse: [ ^false ].
>>> +       1 to: self class instSize do: [ :i |
>>> +               (self instVarAt: i) == anObject ifTrue: [ ^false ] ].
>>> +       ^true!
>>>
>>>
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Levente Uzonyi-2
On Tue, 4 Sep 2012, Frank Shearar wrote:

> On 4 September 2012 14:37, Levente Uzonyi <[hidden email]> wrote:
>> On Tue, 4 Sep 2012, Frank Shearar wrote:
>>
>>> On 4 September 2012 00:06,  <[hidden email]> wrote:
>>>>
>>>> Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
>>>> Item was added:
>>>> + ----- Method: Process>>environmentAt:ifAbsentPut: (in category 'process
>>>> specific') -----
>>>> + environmentAt: key ifAbsentPut: aBlock
>>>> +
>>>> +       ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut:
>>>> aBlock.!
>>>
>>>
>>> Given that Process >> #environmentAt:put: says "^ (env ifNil: [ env :=
>>> Dictionary new ]) at: key put: value" wouldn't it be better to defer
>>> the dictionary creation to it, or pull the two initialisation places
>>> into one, separate, place?
>>
>>
>> There are three things to consider:
>> - do we want to expose the dictionary itself?
>> - performance
>> - single initialization point
>>
>> I picked the implementation with better performance and didn't want to
>> expose the dictionary. We can also have a single initialization point but
>> the code looks a bit unusual (at least to me):
>>
>> Process >> #ensureEnvironment
>>
>>
>>         env ifNil: [ env := Dictionary new ]
>>
>> Process >> #environmentAt: key put: value
>>
>>         env ifNil: [ self ensureEnvironment ].
>>         ^env at: key put: value
>>
>> Process >> #environmentAt: key ifAbsentPut: aBlock
>>
>>         env ifNil: [ self ensureEnvironment ].
>>         ^env at: key ifAbsentPut: aBlock
>>
>> I can push a new version if you like this implementation more.
>
> I suppose using a method that does the initialisation's too much of a
> hit? Having a #environment that said "^ env ifNil: []" would be too
> expensive?

No, but it would expose the environment dictionary and would make all
these methods pointless.


Levente

>
> frank
>
>> Levente
>>
>>
>>>
>>> frank
>>>
>>>> Item was added:
>>>> + ----- Method: ProtoObject>>pointsOnlyWeaklyTo: (in category 'tracing')
>>>> -----
>>>> + pointsOnlyWeaklyTo: anObject
>>>> +       "Assume, we already know that receiver points to an object,
>>>> answer true if receiver points only weakly to it."
>>>> +
>>>> +       self class isWeak ifFalse: [ ^false ].
>>>> +       1 to: self class instSize do: [ :i |
>>>> +               (self instVarAt: i) == anObject ifTrue: [ ^false ] ].
>>>> +       ^true!
>>>>
>>>>
>>>
>>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Frank Shearar-3
On 4 September 2012 15:25, Levente Uzonyi <[hidden email]> wrote:

> On Tue, 4 Sep 2012, Frank Shearar wrote:
>
>> On 4 September 2012 14:37, Levente Uzonyi <[hidden email]> wrote:
>>>
>>> On Tue, 4 Sep 2012, Frank Shearar wrote:
>>>
>>>> On 4 September 2012 00:06,  <[hidden email]> wrote:
>>>>>
>>>>>
>>>>> Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
>>>>> Item was added:
>>>>> + ----- Method: Process>>environmentAt:ifAbsentPut: (in category
>>>>> 'process
>>>>> specific') -----
>>>>> + environmentAt: key ifAbsentPut: aBlock
>>>>> +
>>>>> +       ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut:
>>>>> aBlock.!
>>>>
>>>>
>>>>
>>>> Given that Process >> #environmentAt:put: says "^ (env ifNil: [ env :=
>>>> Dictionary new ]) at: key put: value" wouldn't it be better to defer
>>>> the dictionary creation to it, or pull the two initialisation places
>>>> into one, separate, place?
>>>
>>>
>>>
>>> There are three things to consider:
>>> - do we want to expose the dictionary itself?
>>> - performance
>>> - single initialization point
>>>
>>> I picked the implementation with better performance and didn't want to
>>> expose the dictionary. We can also have a single initialization point but
>>> the code looks a bit unusual (at least to me):
>>>
>>> Process >> #ensureEnvironment
>>>
>>>
>>>         env ifNil: [ env := Dictionary new ]
>>>
>>> Process >> #environmentAt: key put: value
>>>
>>>         env ifNil: [ self ensureEnvironment ].
>>>         ^env at: key put: value
>>>
>>> Process >> #environmentAt: key ifAbsentPut: aBlock
>>>
>>>         env ifNil: [ self ensureEnvironment ].
>>>         ^env at: key ifAbsentPut: aBlock
>>>
>>> I can push a new version if you like this implementation more.
>>
>>
>> I suppose using a method that does the initialisation's too much of a
>> hit? Having a #environment that said "^ env ifNil: []" would be too
>> expensive?
>
>
> No, but it would expose the environment dictionary and would make all these
> methods pointless.

Surely noone ever uses methods marked private!

frank

> Levente
>
>
>>
>> frank
>>
>>> Levente
>>>
>>>
>>>>
>>>> frank
>>>>
>>>>> Item was added:
>>>>> + ----- Method: ProtoObject>>pointsOnlyWeaklyTo: (in category
>>>>> 'tracing')
>>>>> -----
>>>>> + pointsOnlyWeaklyTo: anObject
>>>>> +       "Assume, we already know that receiver points to an object,
>>>>> answer true if receiver points only weakly to it."
>>>>> +
>>>>> +       self class isWeak ifFalse: [ ^false ].
>>>>> +       1 to: self class instSize do: [ :i |
>>>>> +               (self instVarAt: i) == anObject ifTrue: [ ^false ] ].
>>>>> +       ^true!
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Frank Shearar-3
On 4 September 2012 18:03, Frank Shearar <[hidden email]> wrote:

> On 4 September 2012 15:25, Levente Uzonyi <[hidden email]> wrote:
>> On Tue, 4 Sep 2012, Frank Shearar wrote:
>>
>>> On 4 September 2012 14:37, Levente Uzonyi <[hidden email]> wrote:
>>>>
>>>> On Tue, 4 Sep 2012, Frank Shearar wrote:
>>>>
>>>>> On 4 September 2012 00:06,  <[hidden email]> wrote:
>>>>>>
>>>>>>
>>>>>> Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
>>>>>> Item was added:
>>>>>> + ----- Method: Process>>environmentAt:ifAbsentPut: (in category
>>>>>> 'process
>>>>>> specific') -----
>>>>>> + environmentAt: key ifAbsentPut: aBlock
>>>>>> +
>>>>>> +       ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut:
>>>>>> aBlock.!
>>>>>
>>>>>
>>>>>
>>>>> Given that Process >> #environmentAt:put: says "^ (env ifNil: [ env :=
>>>>> Dictionary new ]) at: key put: value" wouldn't it be better to defer
>>>>> the dictionary creation to it, or pull the two initialisation places
>>>>> into one, separate, place?
>>>>
>>>>
>>>>
>>>> There are three things to consider:
>>>> - do we want to expose the dictionary itself?
>>>> - performance
>>>> - single initialization point
>>>>
>>>> I picked the implementation with better performance and didn't want to
>>>> expose the dictionary. We can also have a single initialization point but
>>>> the code looks a bit unusual (at least to me):
>>>>
>>>> Process >> #ensureEnvironment
>>>>
>>>>
>>>>         env ifNil: [ env := Dictionary new ]
>>>>
>>>> Process >> #environmentAt: key put: value
>>>>
>>>>         env ifNil: [ self ensureEnvironment ].
>>>>         ^env at: key put: value
>>>>
>>>> Process >> #environmentAt: key ifAbsentPut: aBlock
>>>>
>>>>         env ifNil: [ self ensureEnvironment ].
>>>>         ^env at: key ifAbsentPut: aBlock
>>>>
>>>> I can push a new version if you like this implementation more.
>>>
>>>
>>> I suppose using a method that does the initialisation's too much of a
>>> hit? Having a #environment that said "^ env ifNil: []" would be too
>>> expensive?
>>
>>
>> No, but it would expose the environment dictionary and would make all these
>> methods pointless.
>
> Surely noone ever uses methods marked private!

OK, so how about pushing the env ifNil: [] into ensure? Do you think
this would look a bit less weird?:

Process >> #environmentAt: key ifAbsentPut: aBlock

        self ensureEnvironment.
        ^env at: key ifAbsentPut: aBlock

I dislike the necessity to remember to "self ensureEnvironment" before
any access of env, but I take your point regarding exposing the
dictionary.

frank

>
> frank
>
>> Levente
>>
>>
>>>
>>> frank
>>>
>>>> Levente
>>>>
>>>>
>>>>>
>>>>> frank
>>>>>
>>>>>> Item was added:
>>>>>> + ----- Method: ProtoObject>>pointsOnlyWeaklyTo: (in category
>>>>>> 'tracing')
>>>>>> -----
>>>>>> + pointsOnlyWeaklyTo: anObject
>>>>>> +       "Assume, we already know that receiver points to an object,
>>>>>> answer true if receiver points only weakly to it."
>>>>>> +
>>>>>> +       self class isWeak ifFalse: [ ^false ].
>>>>>> +       1 to: self class instSize do: [ :i |
>>>>>> +               (self instVarAt: i) == anObject ifTrue: [ ^false ] ].
>>>>>> +       ^true!
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Tobias Pape
Am 05.09.2012 um 11:42 schrieb Frank Shearar:

> On 4 September 2012 18:03, Frank Shearar <[hidden email]> wrote:
>> On 4 September 2012 15:25, Levente Uzonyi <[hidden email]> wrote:
>>> On Tue, 4 Sep 2012, Frank Shearar wrote:
>>>
>>>
>>>
>>> No, but it would expose the environment dictionary and would make all these
>>> methods pointless.
>>
>> Surely noone ever uses methods marked private!
>
> OK, so how about pushing the env ifNil: [] into ensure? Do you think
> this would look a bit less weird?:
>
> Process >> #environmentAt: key ifAbsentPut: aBlock
>
>        self ensureEnvironment.
>        ^env at: key ifAbsentPut: aBlock
>
> I dislike the necessity to remember to "self ensureEnvironment" before
> any access of env, but I take your point regarding exposing the
> dictionary.


What about

Process >> #pvtEnvironment

        ^ env ifNil: [env := Dictionary new]

Process >> #environmentAt: key ifAbsentPut: aBlock

        ^ self pvtEnvironment at: key ifAbsentPut: aBlock


(naming subject to bikeshedding,
eg, name it pvtEnvironment, ensureEnvironment, ensuredEnvironment,
theEnvironment ...)

Best
        -Tobias
Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Frank Shearar-3
On 5 September 2012 12:10, Tobias Pape <[hidden email]> wrote:

> Am 05.09.2012 um 11:42 schrieb Frank Shearar:
>
>> On 4 September 2012 18:03, Frank Shearar <[hidden email]> wrote:
>>> On 4 September 2012 15:25, Levente Uzonyi <[hidden email]> wrote:
>>>> On Tue, 4 Sep 2012, Frank Shearar wrote:
>>>>
>>>>
>>>>
>>>> No, but it would expose the environment dictionary and would make all these
>>>> methods pointless.
>>>
>>> Surely noone ever uses methods marked private!
>>
>> OK, so how about pushing the env ifNil: [] into ensure? Do you think
>> this would look a bit less weird?:
>>
>> Process >> #environmentAt: key ifAbsentPut: aBlock
>>
>>        self ensureEnvironment.
>>        ^env at: key ifAbsentPut: aBlock
>>
>> I dislike the necessity to remember to "self ensureEnvironment" before
>> any access of env, but I take your point regarding exposing the
>> dictionary.
>
>
> What about
>
> Process >> #pvtEnvironment
>
>         ^ env ifNil: [env := Dictionary new]
>
> Process >> #environmentAt: key ifAbsentPut: aBlock
>
>         ^ self pvtEnvironment at: key ifAbsentPut: aBlock
>
>
> (naming subject to bikeshedding,
> eg, name it pvtEnvironment, ensureEnvironment, ensuredEnvironment,
> theEnvironment ...)

While #pvtEnvironment is more forceful than categorising #environment
as 'private' in indicating "don't use this", I expect Levente to still
say "yes but that still exposes the dictionary!"

frank

> Best
>         -Tobias

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Tobias Pape
Am 05.09.2012 um 13:27 schrieb Frank Shearar:

> On 5 September 2012 12:10, Tobias Pape <[hidden email]> wrote:
>> Am 05.09.2012 um 11:42 schrieb Frank Shearar:
>>
>>> On 4 September 2012 18:03, Frank Shearar <[hidden email]> wrote:
>>>
>>> OK, so how about pushing the env ifNil: [] into ensure? Do you think
>>> this would look a bit less weird?:
>>>
>>> Process >> #environmentAt: key ifAbsentPut: aBlock
>>>
>>>       self ensureEnvironment.
>>>       ^env at: key ifAbsentPut: aBlock
>>>
>>> I dislike the necessity to remember to "self ensureEnvironment" before
>>> any access of env, but I take your point regarding exposing the
>>> dictionary.
>>
>>
>> What about
>>
>> Process >> #pvtEnvironment
>>
>>        ^ env ifNil: [env := Dictionary new]
>>
>> Process >> #environmentAt: key ifAbsentPut: aBlock
>>
>>        ^ self pvtEnvironment at: key ifAbsentPut: aBlock
>>
>>
>> (naming subject to bikeshedding,
>> eg, name it pvtEnvironment, ensureEnvironment, ensuredEnvironment,
>> theEnvironment ...)
>
> While #pvtEnvironment is more forceful than categorising #environment
> as 'private' in indicating "don't use this", I expect Levente to still
> say "yes but that still exposes the dictionary!"


so does aProcess instVarNamed: 'env' (SCRN)
The point is that the

        self ensureEnvironment.
        env …
relies too much on side-effects, imho.

Two things here:
1) what is the harm of exposing the dictionary?
   If you use it, you are guilty nonetheless
2) What speaks against initalizing the env in an #initialize?
   That would remove these checks alltogether :)

Best
        -Tobias



Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Levente Uzonyi-2
On Wed, 5 Sep 2012, Tobias Pape wrote:

> Am 05.09.2012 um 13:27 schrieb Frank Shearar:
>
>> On 5 September 2012 12:10, Tobias Pape <[hidden email]> wrote:
>>> Am 05.09.2012 um 11:42 schrieb Frank Shearar:
>>>
>>>> On 4 September 2012 18:03, Frank Shearar <[hidden email]> wrote:
>>>>
>>>> OK, so how about pushing the env ifNil: [] into ensure? Do you think
>>>> this would look a bit less weird?:
>>>>
>>>> Process >> #environmentAt: key ifAbsentPut: aBlock
>>>>
>>>>       self ensureEnvironment.
>>>>       ^env at: key ifAbsentPut: aBlock
>>>>
>>>> I dislike the necessity to remember to "self ensureEnvironment" before
>>>> any access of env, but I take your point regarding exposing the
>>>> dictionary.
>>>
>>>
>>> What about
>>>
>>> Process >> #pvtEnvironment
>>>
>>>        ^ env ifNil: [env := Dictionary new]
>>>
>>> Process >> #environmentAt: key ifAbsentPut: aBlock
>>>
>>>        ^ self pvtEnvironment at: key ifAbsentPut: aBlock
>>>
>>>
>>> (naming subject to bikeshedding,
>>> eg, name it pvtEnvironment, ensureEnvironment, ensuredEnvironment,
>>> theEnvironment ...)
>>
>> While #pvtEnvironment is more forceful than categorising #environment
>> as 'private' in indicating "don't use this", I expect Levente to still
>> say "yes but that still exposes the dictionary!"
>
>
> so does aProcess instVarNamed: 'env' (SCRN)
When you use reflection, then you know anything can happen. If it's
exposed via a single message, then you'll probably think it's okay to
access it.

> The point is that the
> …
> self ensureEnvironment.
> env …
> relies too much on side-effects, imho.
>
> Two things here:
> 1) what is the harm of exposing the dictionary?
>   If you use it, you are guilty nonetheless

If the environment dictionary is accessed from another process, then
things can go really bad.

> 2) What speaks against initalizing the env in an #initialize?
>   That would remove these checks alltogether :)

Most processes don't use the environment. We should check how it
would affect mass process creation.


Levente

>
> Best
> -Tobias
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ul.709.mcz

Colin Putney-3
Levente Uzonyi replied to Tobias Pape:

> When you use reflection, then you know anything can happen. If it's exposed
> via a single message, then you'll probably think it's okay to access it.
>
>
>> The point is that the
>> …
>>         self ensureEnvironment.
>>         env …
>> relies too much on side-effects, imho.
>>
>> Two things here:
>> 1) what is the harm of exposing the dictionary?
>>   If you use it, you are guilty nonetheless
>
>
> If the environment dictionary is accessed from another process, then things
> can go really bad.

But isn't this true regardless of whether the dictionary is exposed?
Can a process can damage the environment of another process by sending
it #environmentAt:put:?

Another idea would be to expose some kind of scope object that had a
more specific protocol than Dictionary and could protect against bad
things happening. That would be available through a lazy initializer.
If we did it in 4.5, it would complement the introduction of
Environment, which does something similar for global variables.

Colin