need help from the experts

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

need help from the experts

Chris Muller-3
With Eliot's latest Cog things are really rocking!  But I am still
having one issue which seems to be related to a Cog code-generation /
timing issue.

It relates to a hack that dynamically creates a subclass of a domain
class to generate overrides of all of its methods that potentially
change the state of the object (e.g., a write-barrier).

In addition to the overriding methods, it also must generate one
accessor method which is used to refer to a Session object, so that
the overriding methods can notify it if, in fact, an inst-var changed.

When I generate the subclass, I _cannot_ add any new inst-vars to hold
the Session (because primChangeClassTo: requires the same physical
shape).  So, to make the hack work at all, first I compile the
following method to establish slots for a couple of literals:

   myDomainSubclass
        compileSilently:
                 'writeBarrier
                       ^ Object first'
        classified: 'accessing'.

Then slap in the Session object I want into the second slot:

   (myDomainSubclass methodDictionary at: #writeBarrier)
       literalAt: 2
       put: #Object -> (WeakArray with: theSession)

Voila!  theSession has now been hacked into the CM at literal 2.
"Object" in the code now refers to the WeakArray holding my Session
rather than the Object class.

I wouldn't do this at all if it wasn't for the 3X improvement in
commit performance.  However, about once or twice a day, I encounter a
debugger which indicates, by the accessing attempt, it thinks that
literal 2 is an Integer or a Character.  Most of the time simply
printing "self writeBarrier" right there in the debugger produces the
correct answer (the Session object) -- as if Cog suddenly "caught up"
with it.

Any suggestions are greatly appreciated, thank you!

Reply | Threaded
Open this post in threaded view
|

Re: need help from the experts

Bob Arning-2
What if, instead of substituting a new literal in the CM, you tried modifying the literal itself? Maybe COG would not object to that.
   myDomainSubclass
        compileSilently:
                 'writeBarrier
                       ^ #(foo) first first'
        classified: 'accessing'.

   ((myDomainSubclass methodDictionary at: #writeBarrier)
       literalAt: 2) at: 1
       put: (WeakArray with: theSession)


On 12/26/12 12:09 PM, Chris Muller wrote:
With Eliot's latest Cog things are really rocking!  But I am still
having one issue which seems to be related to a Cog code-generation /
timing issue.

It relates to a hack that dynamically creates a subclass of a domain
class to generate overrides of all of its methods that potentially
change the state of the object (e.g., a write-barrier).

In addition to the overriding methods, it also must generate one
accessor method which is used to refer to a Session object, so that
the overriding methods can notify it if, in fact, an inst-var changed.

When I generate the subclass, I _cannot_ add any new inst-vars to hold
the Session (because primChangeClassTo: requires the same physical
shape).  So, to make the hack work at all, first I compile the
following method to establish slots for a couple of literals:

   myDomainSubclass
        compileSilently:
                 'writeBarrier
                       ^ Object first'
        classified: 'accessing'.

Then slap in the Session object I want into the second slot:

   (myDomainSubclass methodDictionary at: #writeBarrier)
       literalAt: 2
       put: #Object -> (WeakArray with: theSession)

Voila!  theSession has now been hacked into the CM at literal 2.
"Object" in the code now refers to the WeakArray holding my Session
rather than the Object class.

I wouldn't do this at all if it wasn't for the 3X improvement in
commit performance.  However, about once or twice a day, I encounter a
debugger which indicates, by the accessing attempt, it thinks that
literal 2 is an Integer or a Character.  Most of the time simply
printing "self writeBarrier" right there in the debugger produces the
correct answer (the Session object) -- as if Cog suddenly "caught up"
with it.

Any suggestions are greatly appreciated, thank you!





Reply | Threaded
Open this post in threaded view
|

Re: need help from the experts

Chris Muller-3
That's a great suggestion.  I did it and, so far, the issue has not
occurred.  It might be fixed, thank you!

On Wed, Dec 26, 2012 at 11:47 AM, Bob Arning <[hidden email]> wrote:

> What if, instead of substituting a new literal in the CM, you tried
> modifying the literal itself? Maybe COG would not object to that.
>
>    myDomainSubclass
>         compileSilently:
>                  'writeBarrier
>                        ^ #(foo) first first'
>         classified: 'accessing'.
>
>    ((myDomainSubclass methodDictionary at: #writeBarrier)
>        literalAt: 2) at: 1
>        put: (WeakArray with: theSession)
>
>
> On 12/26/12 12:09 PM, Chris Muller wrote:
>
> With Eliot's latest Cog things are really rocking!  But I am still
> having one issue which seems to be related to a Cog code-generation /
> timing issue.
>
> It relates to a hack that dynamically creates a subclass of a domain
> class to generate overrides of all of its methods that potentially
> change the state of the object (e.g., a write-barrier).
>
> In addition to the overriding methods, it also must generate one
> accessor method which is used to refer to a Session object, so that
> the overriding methods can notify it if, in fact, an inst-var changed.
>
> When I generate the subclass, I _cannot_ add any new inst-vars to hold
> the Session (because primChangeClassTo: requires the same physical
> shape).  So, to make the hack work at all, first I compile the
> following method to establish slots for a couple of literals:
>
>    myDomainSubclass
>         compileSilently:
>                  'writeBarrier
>                        ^ Object first'
>         classified: 'accessing'.
>
> Then slap in the Session object I want into the second slot:
>
>    (myDomainSubclass methodDictionary at: #writeBarrier)
>        literalAt: 2
>        put: #Object -> (WeakArray with: theSession)
>
> Voila!  theSession has now been hacked into the CM at literal 2.
> "Object" in the code now refers to the WeakArray holding my Session
> rather than the Object class.
>
> I wouldn't do this at all if it wasn't for the 3X improvement in
> commit performance.  However, about once or twice a day, I encounter a
> debugger which indicates, by the accessing attempt, it thinks that
> literal 2 is an Integer or a Character.  Most of the time simply
> printing "self writeBarrier" right there in the debugger produces the
> correct answer (the Session object) -- as if Cog suddenly "caught up"
> with it.
>
> Any suggestions are greatly appreciated, thank you!
>
>
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: need help from the experts

Bob Arning-2
I'm not sure all the reasons that led you to the tricky solution, but less tricky alternatives could use some sort of shared dictionary. This would need cleaning from time to time, but that wouldn't be hard.
---------------------
Using a class variable

foo2: theSession
"
SomeClass new foo2: 'thisIsMySession',Time now asString; writeBarrier
"
   
    SomeClassDictionary ifNil: [SomeClassDictionary _ Dictionary new].
    SomeClassCounter ifNil: [SomeClassCounter _ 0].
    SomeClassCounter _ SomeClassCounter + 1.
    SomeClassDictionary at: SomeClassCounter put: (WeakArray with: theSession).
    self class compileSilently:
                 'writeBarrier
                       ^ (SomeClassDictionary at: ',SomeClassCounter,') first'
        classified: 'accessing'.

generates something like this:

writeBarrier
    ^ (SomeClassDictionary at: 7) first

---------------
Using a pool dictionary

foo1: theSession
"
SomeClass new foo1: 'thisIsMySession',Time now asString; writeBarrier
"
    | id |
   
    SomeClassCounter ifNil: [SomeClassCounter _ 0].
    SomeClassCounter _ SomeClassCounter + 1.
    id _ ('MyPoolID',SomeClassCounter asString) asSymbol.
    SomeClassPool at: id put: (WeakArray with: theSession).
    self class compileSilently:
                 'writeBarrier
                       ^ ',id,' first'
        classified: 'accessing'.

generates something like this:

writeBarrier
    ^ MyPoolID8 first
------------------

Either might be a bit less fragile.

Cheers,
Bob

On 12/27/12 10:20 AM, Chris Muller wrote:
That's a great suggestion.  I did it and, so far, the issue has not
occurred.  It might be fixed, thank you!

On Wed, Dec 26, 2012 at 11:47 AM, Bob Arning [hidden email] wrote:
What if, instead of substituting a new literal in the CM, you tried
modifying the literal itself? Maybe COG would not object to that.

   myDomainSubclass
        compileSilently:
                 'writeBarrier
                       ^ #(foo) first first'
        classified: 'accessing'.

   ((myDomainSubclass methodDictionary at: #writeBarrier)
       literalAt: 2) at: 1
       put: (WeakArray with: theSession)


On 12/26/12 12:09 PM, Chris Muller wrote:

With Eliot's latest Cog things are really rocking!  But I am still
having one issue which seems to be related to a Cog code-generation /
timing issue.

It relates to a hack that dynamically creates a subclass of a domain
class to generate overrides of all of its methods that potentially
change the state of the object (e.g., a write-barrier).

In addition to the overriding methods, it also must generate one
accessor method which is used to refer to a Session object, so that
the overriding methods can notify it if, in fact, an inst-var changed.

When I generate the subclass, I _cannot_ add any new inst-vars to hold
the Session (because primChangeClassTo: requires the same physical
shape).  So, to make the hack work at all, first I compile the
following method to establish slots for a couple of literals:

   myDomainSubclass
        compileSilently:
                 'writeBarrier
                       ^ Object first'
        classified: 'accessing'.

Then slap in the Session object I want into the second slot:

   (myDomainSubclass methodDictionary at: #writeBarrier)
       literalAt: 2
       put: #Object -> (WeakArray with: theSession)

Voila!  theSession has now been hacked into the CM at literal 2.
"Object" in the code now refers to the WeakArray holding my Session
rather than the Object class.

I wouldn't do this at all if it wasn't for the 3X improvement in
commit performance.  However, about once or twice a day, I encounter a
debugger which indicates, by the accessing attempt, it thinks that
literal 2 is an Integer or a Character.  Most of the time simply
printing "self writeBarrier" right there in the debugger produces the
correct answer (the Session object) -- as if Cog suddenly "caught up"
with it.

Any suggestions are greatly appreciated, thank you!