how to avoid inlining?

L

Lloyd Dupont

I have some code which looks like that:

[DefaultValue(CornerStyle.Rounded)]
public CornerStyle RectCornerMode
{
get { return this["RectCornerMode"].GetValue<CornerStyle>(); }
set { this["RectCornerMode"].SetValue<CornerStyle>(value); }
}


in this[string] I get the attribute decorating the calling method, and used
it to compute a default value.
now it seems that sometimes (when build in release mode) the property is by
passed and the calling method call this[string] and GetValue directly, thus
ignoring the decorating attribute....

is there a way to avoid this inlining?
any suggestion?
 
L

Lebesgue

Make it virtual. JIT can't inline virtual calls (not quite sure if this is
"better solution" for you)

Lloyd Dupont said:
found it: MethodImplAttribute.
Anyway I thought of a better solution...

--
Regards,
Lloyd Dupont
NovaMind Software
Mind Mapping at its best
www.nova-mind.com
Lloyd Dupont said:
I have some code which looks like that:

[DefaultValue(CornerStyle.Rounded)]
public CornerStyle RectCornerMode
{
get { return this["RectCornerMode"].GetValue<CornerStyle>(); }
set { this["RectCornerMode"].SetValue<CornerStyle>(value); }
}


in this[string] I get the attribute decorating the calling method, and
used it to compute a default value.
now it seems that sometimes (when build in release mode) the property is
by passed and the calling method call this[string] and GetValue directly,
thus ignoring the decorating attribute....

is there a way to avoid this inlining?
any suggestion?
 
M

Mattias Sjögren

Make it virtual. JIT can't inline virtual calls (not quite sure if this is
"better solution" for you)

Sounds like a horrible solution to me. Making a member virtual just to
achieve this side effect just seems wrong. You should only make a
member virtual when it makes sense to do so and you're prepared to
handle the fact that your code may be overridden and perhaps never
run.

Plus your code would break if a future version of the CLR (or some
other runtime implementation) actually supported inlining virtual
methods.


Mattias
 
L

Lebesgue

Mattias,
That's exactly what I meant by stating "not quite sure if this is "better
solution" for you". It's in fact a very bad "solution". Posted just to
present another alternative to using the MethodImpl attribute which is the
best solution to avoid inlining.
 
K

KKS

Your class could inherit from MarshalByRefObject. This would also achive non
inlining and is the purpose of the class altogether.

Regards
Kjetil Kristoffer Solberg
 
A

Andy

Your class could inherit from MarshalByRefObject. This would also achive non
inlining and is the purpose of the class altogether.

No, that's not the purpose of that class at all. The purpose of that
class is to create a COM server object, which is anchored to the
machine on which its running (that is, using the object from other
computers will perform RPC calls to the server).

Actually I'm not sure that inheriting that class will prevent inlining
at all. The only good solution is the attribute mentioned above.
 
J

Jon Skeet [C# MVP]

Andy said:
No, that's not the purpose of that class at all. The purpose of that
class is to create a COM server object, which is anchored to the
machine on which its running (that is, using the object from other
computers will perform RPC calls to the server).

I think that definition is too narrow as well. COM doesn't need to be
involved anywhere. It just means (IMO) that when an instance needs to
be marshalled across an AppDomain boundary - for whatever reason - the
reference will be used, rather than creating a value copy of the
object.
Actually I'm not sure that inheriting that class will prevent inlining
at all.

I believe that it currently prevents inlining, but I haven't seen
anything to actually specify that, or say that it will always be the
case.
The only good solution is the attribute mentioned above.

Agreed.
 
A

Andy

I think that definition is too narrow as well. COM doesn't need to be
involved anywhere. It just means (IMO) that when an instance needs to
be marshalled across an AppDomain boundary - for whatever reason - the
reference will be used, rather than creating a value copy of the
object.

Yes, you are right.
I believe that it currently prevents inlining, but I haven't seen
anything to actually specify that, or say that it will always be the
case.

Inlining is a compiler trick, isn't it? I didn't see anything on the
MBR class that would affect inlining, unless I'm missing it somewhere..
 
J

Jon Skeet [C# MVP]

Inlining is a compiler trick, isn't it? I didn't see anything on the
MBR class that would affect inlining, unless I'm missing it somewhere..

It's done by the JIT, not by the C# -> IL compiler. I don't know the
details about why inlining doesn't take place, but I'm sure I've seen
it in the past in other questions.
 
K

Kjetil

You are mistaken.

The MarshalByRefObject has a bad name. It's primary purpose is to supress
inlining by the JIT compiler so that the transparent proxy can do it's job.
The JIT compiler checks to see if a class inherits from MarshalByRef object
and don't inline if it does.


Regards
Kjetil Kristoffer Solberg
 
P

Peter Duniho

You are mistaken.

The MarshalByRefObject has a bad name. It's primary purpose is to
supress inlining by the JIT compiler so that the transparent proxy can
do it's job.

From the MSDN documentation for MarshalByRefObject:

Enables access to objects across application domain
boundaries in applications that support remoting.

There's nothing in there about inlining at all. In fact, on that page
(http://msdn2.microsoft.com/en-us/library/system.marshalbyrefobject.aspx)
there is no reference to inlining at all.

You'd think that if the "primary purpose is to suppress inlining by the
JIT compiler", some mention of inlining would show up *somewhere* in the
documentation.

I don't find the claim that MarshalByRefObject has as its primary purpose
suppression of inlining is in any way credible.
The JIT compiler checks to see if a class inherits from MarshalByRef
object and don't inline if it does.

It may well be that the compiler special-cases the class inheritance and
that inlining doesn't happen for particular classes, like
MarshalByRefObject. But that doesn't mean that's the purpose of
inheriting from MarshalByRefObject.

Pete
 
K

Kjetil

You need to look at the broader picture. Where does MarshalByRefObject get
used? In scenarios like cross appdomain/process/machine method calls, you
need a mechanism for transforming your stack based method call into some
transportable format, transport the call, then transforming it back into
stack based method calls in or on the target appdomain/process/machine, and
the same back again. This is where the transparent proxy, real proxy and
MarshalByRefObject objects come into the picture. In order for the
transparent proxy to intercept all calls there needs to made sure that no
inlining takes place. How could the transparent proxy transform a method
call and send it to the real proxy if the JIT compiler inlined the method?
It is here that MarshalByRefObject comes to the rescue. To ensure that all
method calls are intercepted by the transparent proxy you inherit from
MarshalByRefObject. Hope this makes things clearer.


Regards
Kjetil Kristoffer Solberg
 
P

Peter Duniho

You need to look at the broader picture.

You need to read the documentation.

A class derived from MarshalByRefObject inherits a LOT more than just
suppression of inlining, and it's farcical to suggest that the primary
purpose of deriving from that class is to suppress inlining, or even that
deriving from that class is an appropriate way to suppress inlining in the
general case, especially when there's a perfectly good attribute that can
be applied to the function where inlining needs to be suppressed.

Pete
 
J

Jon Skeet [C# MVP]

Kjetil said:
You need to look at the broader picture. Where does MarshalByRefObject get
used? In scenarios like cross appdomain/process/machine method calls, you
need a mechanism for transforming your stack based method call into some
transportable format, transport the call, then transforming it back into
stack based method calls in or on the target appdomain/process/machine, and
the same back again. This is where the transparent proxy, real proxy and
MarshalByRefObject objects come into the picture. In order for the
transparent proxy to intercept all calls there needs to made sure that no
inlining takes place. How could the transparent proxy transform a method
call and send it to the real proxy if the JIT compiler inlined the method?
It is here that MarshalByRefObject comes to the rescue. To ensure that all
method calls are intercepted by the transparent proxy you inherit from
MarshalByRefObject. Hope this makes things clearer.

That says that preventing inlining is (currently) required in order to
meet the primary purpose of MarshalByRefObject. That's *very* different
from justifying your claim that the primary purpose of
MarshalByRefObject *is* to prevent inlining.

To make a comparison, imagine we were talking about ref parameters -
it's necessary for the types to match exactly (instead of being able to
pass a string for an object parameter, for example) - but it would be
laugable to state that the primary purpose of ref parameters was to
force people to use an argument of the *exact* type.


Put it this way - consider someone who has decided to derive from
MarshalByRefObject. When you ask them why they did so, do you think
it's likely that they'll reply "To prevent inlining" or "To enable
remoting/cross-app-domain calls (etc)"?
 
A

Andy

You are mistaken.

The MarshalByRefObject has a bad name. It's primary purpose is to supress
inlining by the JIT compiler so that the transparent proxy can do it's job.
The JIT compiler checks to see if a class inherits from MarshalByRef object
and don't inline if it does.

Interesting how nowhere in the MarshalByRefObject MSDN pages does it
state this. In fact, it directly supports what Jon says.
 
K

Kjetil

Peter Duniho said:
You need to read the documentation.

A class derived from MarshalByRefObject inherits a LOT more than just
suppression of inlining, and it's farcical to suggest that the primary
purpose of deriving from that class is to suppress inlining, or even that
deriving from that class is an appropriate way to suppress inlining in the
general case, especially when there's a perfectly good attribute that can
be applied to the function where inlining needs to be suppressed.

Pete

You have to look at context. Whats the context of MarshalByRefObject? All
the members the object inherhits has to do with lifetime maintenace of the
object in the context I describe, meaning that the argument that
MarshalByRefObject's primary purpose is to supress inlining stands. The fact
that it does not say so in MSDN is irrelevant. Again MarshalByRefObject is
poorly named.

Regards
Kjetil Kristoffer Solberg
 
K

Kjetil

Jon Skeet said:
That says that preventing inlining is (currently) required in order to
meet the primary purpose of MarshalByRefObject. That's *very* different
from justifying your claim that the primary purpose of
MarshalByRefObject *is* to prevent inlining.

To make a comparison, imagine we were talking about ref parameters -
it's necessary for the types to match exactly (instead of being able to
pass a string for an object parameter, for example) - but it would be
laugable to state that the primary purpose of ref parameters was to
force people to use an argument of the *exact* type.


Put it this way - consider someone who has decided to derive from
MarshalByRefObject. When you ask them why they did so, do you think
it's likely that they'll reply "To prevent inlining" or "To enable
remoting/cross-app-domain calls (etc)"?
I do not see the comparison here at all. You have to look at this object
from the context in which it is to be used. You need an object that can
supress inlining for the communications model to work. This is what
MarshalByRefObject is all about. The lifetime services is secondary.

Regards
Kjetil Kristoffer Solberg
 
J

Jon Skeet [C# MVP]

I do not see the comparison here at all. You have to look at this object
from the context in which it is to be used. You need an object that can
supress inlining for the communications model to work. This is what
MarshalByRefObject is all about. The lifetime services is secondary.

Yes, you need to suppress inlining - but more importantly, you need the
reference to be marshalled rather than the value. Surely *that* is the
primary purpose of the type.
 
P

Peter Duniho

You have to look at context. Whats the context of MarshalByRefObject?

The context is "enabling access to objects across application domain
boundaries in applications that support remoting". It has everything to
do with addressing issues that come up in moving data between
applications. The suppression of inlining is simply a side-effect, and
absolutely not the primary purpose of the class.

Frankly, I'm finding your claims to be extremely troll-like, and I think
I've been suckered enough. One hopes that anyone with a rational view
will be able to extract the truth from this thread. I don't feel a need
to belabor the point any more than I already have.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top