#at:, #basicAt:, #at:put: and method stubs

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

#at:, #basicAt:, #at:put: and method stubs

Artur Zaroda
Hello,

"Array at: 1 put: 1" walkbacks with invalid access to memory
location. "Array at: 2" doesn't, but the result is not what
one would expect either.

MethodProtocol>>compileStub:into: and Debugger>>generateStubFor:inClass:
assume, that stubs they generate are correct, so there is no check
for nil on result of #compile:. Unfortunately that assumption is not
always correct. For example stub that MethodProtocol>>compileStub:into:
is generating may have argument name that clashes with instance variable
name (Debugger>>generateStubFor:inClass: does have a check for that).
Another problem is when selector of stub is illegal. It may happen
in MethodProtocol>>compileStub:into: because with ProtocolBrowser you
can put anything (for example a number) as "selector" in protocol.
You are going to receive message on Transcript saying that new method
was created, which is not true. Debugger>>generateStubFor:inClass: can
be fooled into generating incorrect stub as well, for example by
executing "1 perform: #'+a' with: 1" and asking from debugger to implement
that in SmallInteger. Doing the same with "1 perform: #'' with: 1"
or "1 perform: #'' with: 1 with: 2" will walkback (in two different
places).

Some time ago, in a slightly off-topic thread, I wrote about relative speed
of Object>>at: and Object>>basicAt:. The latter appears to be about 15%
slower. Same is the case with Object>>at:put: and Object>>basicAt:put:.
It may be just my machine that shows this effect, but if it's not, then
it looks like there is a possibility for optimization.

Artur Zaroda
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: #at:, #basicAt:, #at:put: and method stubs

Blair McGlashan
Artur

Thanks for your bug reports.

You wrote in message
news:[hidden email]...
>
> "Array at: 1 put: 1" walkbacks with invalid access to memory
> location. "Array at: 2" doesn't, but the result is not what
> one would expect either.

I suspect this is might be related to bug fix 39 in the 4.01 release notes:
"GP
fault if attempt to store characters into a ByteArray using #at:put: rather
than "cannot hold" error". I'm guessing that the handling of the error
case(s) may be wrong in the primitive, just as it was for byte objects under
certain circumstances. I'll make a new VM available as soon as it is fixed.

>...MethodProtocol>>compileStub:into: and Debugger>>generateStubFor:inClass:
> assume, that stubs they generate are correct, so there is no check
> for nil on result of #compile:. Unfortunately that assumption is not
> always correct. For example stub that MethodProtocol>>compileStub:into:
> is generating may have argument name that clashes with instance variable
> name (Debugger>>generateStubFor:inClass: does have a check for that).
> Another problem is when selector of stub is illegal. It may happen
> in MethodProtocol>>compileStub:into: because with ProtocolBrowser you
> can put anything (for example a number) as "selector" in protocol.
> You are going to receive message on Transcript saying that new method
> was created, which is not true. Debugger>>generateStubFor:inClass: can
> be fooled into generating incorrect stub as well, for example by
> executing "1 perform: #'+a' with: 1" and asking from debugger to implement
> that in SmallInteger. Doing the same with "1 perform: #'' with: 1"
> or "1 perform: #'' with: 1 with: 2" will walkback (in two different
> places).

True, although I think that with the exception of the potential instance
variable clash in MethodProtocol>>compileStub:into:, the real bugs are that
the UI allows one to get into that position. Debugger>>queryCommand: should
not enable the "Implement In" menu if the selector is invalid (not a
position one would normally get into one has to say), and obviously the
protocol browser should not permit the entry of invalid selectors. We'll
sort this out in the next patch level.

>
> Some time ago, in a slightly off-topic thread, I wrote about relative
speed
> of Object>>at: and Object>>basicAt:. The latter appears to be about 15%
> slower. Same is the case with Object>>at:put: and Object>>basicAt:put:.
> It may be just my machine that shows this effect, but if it's not, then
> it looks like there is a possibility for optimization.

The apparent better performance of the #at: variants is due to a caching
optimisation in 4.0. The main benefit of this is that it can remove the need
to perform any kind of message lookup for #at:[put:], but the cache also
reduces the cost of the bounds check. In consequence of the latter #at: will
have marginally better performance in typical micro-benchmarks, however I
doubt it would be at all significant in practice, and probably not enough to
justify maintaining a further cache.

Regards

Blair