473,545 Members | 1,744 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

are all subclasses virtual (use vtables?)

Are ALL methods in subclasses implemented in C# with vtables and virtual
functions?

I know I could test this myself, but I'm still using Express edition of 2.0,
so I cannot view the optimized disassembly.

I know that you must use vtables for all virtual functions (and interfaces),
but if there are non-virtual functions, does the compiler use a vtable for
everything anyway?

For example, if I have a base class like this:

class baseClass
{ protected variables list......
public void A(){}
public void B(){}
public abstract void C(){}
}
class sub1 : baseClass
{ public override void C(){}
public void D(){}
}

class sub2 : baseClass
{ public override void C(){}
public void E(){}
}

Will the compiler create a full vtable for all of sub2's methods (including
inherited ones)? Or, will it compile in direct addresses (and allow inline
compile for short methods) for functions A(), B(), E() ? (and it could
possibly do C() also). IMO, the only real vtable required would be if you
access sub2 through a variable of type baseClass.

I'm just trying to fully understand this compiler - any insight is
appreciated.

Mar 9 '06 #1
7 1451
ZenRhapsody wrote:
Are ALL methods in subclasses implemented in C# with vtables and virtual
functions?
Methods are not virtual by default in C#, so my guess would be no.
I know I could test this myself, but I'm still using Express edition of 2.0,
so I cannot view the optimized disassembly.
I was under the impression that the express edition of the compiler is
exactly the same as the non-express one.
I'm just trying to fully understand this compiler - any insight is
appreciated.


May I ask why this is of such intense interest to you? if you are
thinking about performance you will probably be much better off using a
profiler.

Don't draw too many conclusions based on the compiler output, the JIT
can change the playing field and your hard work analyzing will, at best,
be wasted and at worst misguiding.

--
Helge Jensen
mailto:he****** ****@slog.dk
sip:he********* *@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Mar 9 '06 #2
Have you considered learning this detail through the Rotor's source code?

Ab.
"ZenRhapsod y" <no****@hotmail .com> wrote in message
news:Oc******** ******@TK2MSFTN GP09.phx.gbl...
Are ALL methods in subclasses implemented in C# with vtables and virtual
functions?

I know I could test this myself, but I'm still using Express edition of 2.0, so I cannot view the optimized disassembly.

I know that you must use vtables for all virtual functions (and interfaces), but if there are non-virtual functions, does the compiler use a vtable for
everything anyway?

For example, if I have a base class like this:

class baseClass
{ protected variables list......
public void A(){}
public void B(){}
public abstract void C(){}
}
class sub1 : baseClass
{ public override void C(){}
public void D(){}
}

class sub2 : baseClass
{ public override void C(){}
public void E(){}
}

Will the compiler create a full vtable for all of sub2's methods (including inherited ones)? Or, will it compile in direct addresses (and allow inline compile for short methods) for functions A(), B(), E() ? (and it could
possibly do C() also). IMO, the only real vtable required would be if you
access sub2 through a variable of type baseClass.

I'm just trying to fully understand this compiler - any insight is
appreciated.

Mar 9 '06 #3
Thx for the response.

Since I have the Express edition, I cannot view the disassembly in debug
mode. In 1.0 Prefessional (only have that at work, and not a lot of time to
experiment with this issue), I can view the actually assembly code after it
has been JIT'd by attaching the debugger to a running EXE. This has been
educational, for example, for seeing how the JIT compiler inline compiles
functions, how it optimizes long switch statements, and how it optimizes
local variables into register variables.

My interest now is purely academic. I am always interested in performance,
but realize that the additional indirect address call of a virtual function
is usally trivial compared to the function's actual calculation time.
However, with short functions that could be in-lined by the compiler, it
would make a difference (assuming, of course, the function is called enough
times to be significant).
"Helge Jensen" <he**********@s log.dk> wrote in message
news:%2******** ********@TK2MSF TNGP12.phx.gbl. ..
ZenRhapsody wrote:
Are ALL methods in subclasses implemented in C# with vtables and virtual
functions?


Methods are not virtual by default in C#, so my guess would be no.
I know I could test this myself, but I'm still using Express edition of
2.0,
so I cannot view the optimized disassembly.


I was under the impression that the express edition of the compiler is
exactly the same as the non-express one.
I'm just trying to fully understand this compiler - any insight is
appreciated.


May I ask why this is of such intense interest to you? if you are
thinking about performance you will probably be much better off using a
profiler.

Don't draw too many conclusions based on the compiler output, the JIT
can change the playing field and your hard work analyzing will, at best,
be wasted and at worst misguiding.

--
Helge Jensen
mailto:he****** ****@slog.dk
sip:he********* *@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-

Mar 10 '06 #4
ZenRhapsody wrote:
Since I have the Express edition, I cannot view the disassembly in debug
mode. In 1.0 Prefessional (only have that at work, and not a lot of time to
experiment with this issue), I can view the actually assembly code after it
has been JIT'd by attaching the debugger to a running EXE. This has been
educational, for example, for seeing how the JIT compiler inline compiles
functions, how it optimizes long switch statements, and how it optimizes
local variables into register variables.

My interest now is purely academic. I am always interested in performance,
but realize that the additional indirect address call of a virtual function
is usally trivial compared to the function's actual calculation time.
However, with short functions that could be in-lined by the compiler, it
would make a difference (assuming, of course, the function is called enough
times to be significant).


Do you have cordbg installed? You can use that to debug through the
optimised code to find out what's going on. However, you should be
aware that inlining is done by the JIT, not the compiler.

Jon

Mar 10 '06 #5
The only way to debug at that level without interfering with the JIT (which
will turn of inlining whenever a managed debugger is attached) is by using
an unmanaged debugger like cdb or windbg. These debuggers are freely
downloadable from
http://www.microsoft.com/whdc/devtoo...nstallx86.mspx

Willy.

"ZenRhapsod y" <no****@hotmail .com> wrote in message
news:%2******** ********@tk2msf tngp13.phx.gbl. ..
| Thx for the response.
|
| Since I have the Express edition, I cannot view the disassembly in debug
| mode. In 1.0 Prefessional (only have that at work, and not a lot of time
to
| experiment with this issue), I can view the actually assembly code after
it
| has been JIT'd by attaching the debugger to a running EXE. This has been
| educational, for example, for seeing how the JIT compiler inline compiles
| functions, how it optimizes long switch statements, and how it optimizes
| local variables into register variables.
|
| My interest now is purely academic. I am always interested in
performance,
| but realize that the additional indirect address call of a virtual
function
| is usally trivial compared to the function's actual calculation time.
| However, with short functions that could be in-lined by the compiler, it
| would make a difference (assuming, of course, the function is called
enough
| times to be significant).
|
|
| "Helge Jensen" <he**********@s log.dk> wrote in message
| news:%2******** ********@TK2MSF TNGP12.phx.gbl. ..
| > ZenRhapsody wrote:
| >
| >> Are ALL methods in subclasses implemented in C# with vtables and
virtual
| >> functions?
| >
| > Methods are not virtual by default in C#, so my guess would be no.
| >
| >> I know I could test this myself, but I'm still using Express edition of
| >> 2.0,
| >> so I cannot view the optimized disassembly.
| >
| > I was under the impression that the express edition of the compiler is
| > exactly the same as the non-express one.
| >
| >> I'm just trying to fully understand this compiler - any insight is
| >> appreciated.
| >
| > May I ask why this is of such intense interest to you? if you are
| > thinking about performance you will probably be much better off using a
| > profiler.
| >
| > Don't draw too many conclusions based on the compiler output, the JIT
| > can change the playing field and your hard work analyzing will, at best,
| > be wasted and at worst misguiding.
| >
| > --
| > Helge Jensen
| > mailto:he****** ****@slog.dk
| > sip:he********* *@slog.dk
| > -=> Sebastian cover-music: http://ungdomshus.nu <=-
|
|
Mar 10 '06 #6
Willy Denoyette [MVP] <wi************ *@telenet.be> wrote:
The only way to debug at that level without interfering with the JIT (which
will turn of inlining whenever a managed debugger is attached) is by using
an unmanaged debugger like cdb or windbg. These debuggers are freely
downloadable from
http://www.microsoft.com/whdc/devtoo...nstallx86.mspx


cordbg allows you to keep JIT optimizations, including inlining - type
m JitOptimization s 1
to set this.

For example, here's some sample C# code:
using System;

class Program
{
static void Main()
{
for (int i=0; i < 10; i++)
{
Console.WriteLi ne (Square(i));
}
}

static int Square (int x)
{
return x*x;
}
}
Here's the disassembly of Main with optimization off:
[0000] push ebp
[0001] mov ebp,esp
[0003] push eax
[0004] push edi
[0005] push esi
[0006] xor esi,esi
*[0008] xor esi,esi
[000a] nop
[000b] jmp 00000015
[000d] mov ecx,esi
[000f] call dword ptr ds:[00A150E4h]
[0015] mov edi,eax
[0017] mov ecx,edi
[0019] call dword ptr ds:[79C56664h]
[001f] inc esi
[0020] cmp esi,0Ah
[0023] jl FFFFFFEA
[0025] nop
[0026] pop esi
[0027] pop edi
[0028] mov esp,ebp
[002a] pop ebp
[002b] ret
And here it is with optimization on:

(cordbg) dis 20
[0000] push esi
*[0001] xor esi,esi
[0003] mov eax,esi
[0005] imul eax,esi
[0008] mov edx,eax
[000a] mov ecx,dword ptr ds:[01C42030h]
[0010] mov eax,dword ptr [ecx]
[0012] call dword ptr [eax+000000BCh]
[0018] inc esi
[0019] cmp esi,0Ah
[001c] jl FFFFFFE7
[001e] pop esi
[001f] ret

Note the inlining of the multiplication in the second version.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 10 '06 #7


"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
| Willy Denoyette [MVP] <wi************ *@telenet.be> wrote:
| > The only way to debug at that level without interfering with the JIT
(which
| > will turn of inlining whenever a managed debugger is attached) is by
using
| > an unmanaged debugger like cdb or windbg. These debuggers are freely
| > downloadable from
| > http://www.microsoft.com/whdc/devtoo...nstallx86.mspx
|
| cordbg allows you to keep JIT optimizations, including inlining - type
| m JitOptimization s 1
| to set this.
|
| For example, here's some sample C# code:
| using System;
|
| class Program
| {
| static void Main()
| {
| for (int i=0; i < 10; i++)
| {
| Console.WriteLi ne (Square(i));
| }
| }
|
| static int Square (int x)
| {
| return x*x;
| }
| }
|
|
| Here's the disassembly of Main with optimization off:
| [0000] push ebp
| [0001] mov ebp,esp
| [0003] push eax
| [0004] push edi
| [0005] push esi
| [0006] xor esi,esi
| *[0008] xor esi,esi
| [000a] nop
| [000b] jmp 00000015
| [000d] mov ecx,esi
| [000f] call dword ptr ds:[00A150E4h]
| [0015] mov edi,eax
| [0017] mov ecx,edi
| [0019] call dword ptr ds:[79C56664h]
| [001f] inc esi
| [0020] cmp esi,0Ah
| [0023] jl FFFFFFEA
| [0025] nop
| [0026] pop esi
| [0027] pop edi
| [0028] mov esp,ebp
| [002a] pop ebp
| [002b] ret
|
|
| And here it is with optimization on:
|
| (cordbg) dis 20
| [0000] push esi
| *[0001] xor esi,esi
| [0003] mov eax,esi
| [0005] imul eax,esi
| [0008] mov edx,eax
| [000a] mov ecx,dword ptr ds:[01C42030h]
| [0010] mov eax,dword ptr [ecx]
| [0012] call dword ptr [eax+000000BCh]
| [0018] inc esi
| [0019] cmp esi,0Ah
| [001c] jl FFFFFFE7
| [001e] pop esi
| [001f] ret
|
| Note the inlining of the multiplication in the second version.
|

You are right that the call to Square is inlined, but that's normal, the CLR
tests the "IsDebugger " atached flag at the first hit of a (managed)
breakpoint in your code, that is after Main is JIT compiled, so, after the
inlining has been done (in optimized build).
subsequent JIT compiles are not guaranteed to be optimized, unless you have
set the "JitOptimizatio ns" mode flag, but the result is not pretty, it's
quite hard to debug with this flag set and the disassembly output cannot be
trusted.

Here is the VS debugger output, which includes the actual address and code
bytes, note that you ran this on V1.1, so I've included the V2. code here
[1] so you can watch the differences between v1 and V2, which may be quite
interesting.

02D1005F 33 F6 xor esi,esi
02D10061 8B D6 mov edx,esi
02D10063 0F AF D6 imul edx,esi
02D10066 8B 0D 30 20 B4 01 mov ecx,dword ptr ds:[1B42030h]
02D1006C 8B 01 mov eax,dword ptr [ecx]
02D1006E FF 90 BC 00 00 00 call dword ptr [eax+0BCh]
02D10074 46 inc esi
02D10075 83 FE 0A cmp esi,0Ah
02D10078 7C E7 jl 02D10061
02D1007A 5E pop esi
02D1007B C3 ret

Here is the same but running under V2.

00CB0077 33 F6 xor esi,esi
00CB0079 EB 2D jmp 00CB00A8
00CB007B 8B C6 mov eax,esi
00CB007D 0F AF C6 imul eax,esi
00CB0080 8B F8 mov edi,eax
00CB0082 83 3D 84 10 27 02 00 cmp dword ptr ds:[2271084h],0
00CB0089 75 0A jne 00CB0095
00CB008B B9 01 00 00 00 mov ecx,1
00CB0090 E8 77 D7 69 78 call 7934D80C
00CB0095 8B 0D 84 10 27 02 mov ecx,dword ptr ds:[2271084h]
00CB009B 8B D7 mov edx,edi
00CB009D 8B 01 mov eax,dword ptr [ecx]
00CB009F FF 90 BC 00 00 00 call dword ptr [eax+0BCh]
00CB00A5 83 C6 01 add esi,1
00CB00A8 83 FE 0A cmp esi,0Ah
00CB00AB 0F 9C C0 setl al
00CB00AE 0F B6 C0 movzx eax,al
00CB00B1 85 C0 test eax,eax
00CB00B3 75 C6 jne 00CB007B
00CB00B5 5E pop esi
00CB00B6 5F pop edi
00CB00B7 C3 ret

Noticed the main differences?

Willy.
Mar 11 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
8020
by: Kapil Khosla | last post by:
Dear all, I am trying to underlying implementation of virtual functions in C++. The way I understand polymorphism is class Base { public: virtual int func(); };
4
4416
by: vijay | last post by:
I have a doubt with size of classed with virtual functions I have declared A,A1,A2 ,B , C, D some classes with no varaibles but a vitual function each, The size of A is as expected 4 bytes with one vtbl ptr BUt when I derive the class B from class A (both have 1 virtual function each ) the size remains still as 4 bytes . class A ...
23
4442
by: Giancarlo Niccolai | last post by:
Hello all. I have peeked through the FAQ and all relevant links, and also through Stroustrup book, but I have not been able to find an answer, so I have to post here as a last resort. It makes sense that if you have virtual destructors, they are eventually used in the explicit destructor call when using the placement new semantic: ...
9
13027
by: kish_nand | last post by:
Could someone please explain me the concept behind virtual functions and vtables. I am little confused about this. Please refer to the following code and tell me how many virtual tables would be created and what they would contain: class base { virtual void display() { cout<<"base display"<<endl;
13
3873
by: Just D | last post by:
All, What are advantages and disadvantages of these two different approaches? 1 . I create a base class with a few virtual methods, then I derive my classes from this class, override these methods and use this class. 2. I work with interfaces. What is faster in .NET? I supposed that deriving from the base classes.
3
3583
by: Anunay | last post by:
Hello all, I have a doubt regarding the concept of virtual functions. When does the virtual function table get created? At compile time or at runtime? Please provide any good references where concepts of Virtual table are explained. Thanks,
11
3401
by: ypjofficial | last post by:
Hello All, So far I have been reading that in case of a polymorphic class ( having at least one virtual function in it), the virtual function call get resolved at run time and during that the vtable pointer is made use of.. eg. class one {
3
2161
by: Chameleon | last post by:
I read "thinking in C++" but I don't understand how the pointers stored in vtable of SeekableInputOutputStream. Can you explain me the order please? Thanks a lot! --------------------------------------- class InputStream { public: virtual int read(void *base, int size) = 0;
10
3619
by: Ole Nielsby | last post by:
James Kanze <james.kanze@gmail.comwrote: COM does rely on vtable layout. COM interfaces are declared as pure virtual classes, all methods using stdcall convention, and this works because most (if not all) C++ compilers for the MSW use a very similar vtable layout. In COM, this is handled by proxies provided by system dlls,
0
7464
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7656
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7805
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
5968
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
4943
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3440
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1874
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1012
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
700
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.