Todd, Rotor's code generator is heavily biased toward portability, which means keeping as much code as possible in C. If a helper is embedded, it needs to be re-implemented for each architecture. However, a helper written in C needs to be simply recompiled.
The best way to see what is going on in the JIT compiler for a particular function is to set environment variable COMPlus_JitBreak=<class name>::<function name> and run the program under the debugger. The program will break before the function is JIT compiled so you can set break points on the instructions which are of interest to you and walk through that code. If you have a copy of Shared Source CLI Essentials, you can look at page 156 for the explanation of the x86 JIT calling convention. Here is a short summary of what happens. You have 5 five dword sized arguments plus a this pointer, which in this case is a pointer to local stack. First two parameters - this pointer and the first dword argument are pulled out into ecx and edx. Extra space is allocated for the value on the local stack. So when the call happens at 02D42DF6 the stack looks like the following: Return buffer dword1 Return buffer dword2 Return buffer dword3 Return buffer dword4 Arg 2 Arg 3 Arg 4 Arg 5 Arg 1 Pointer to return buffer <--- sp After the call, six dwords are removed from the stack, so the stack looks like. Return buffer dword1 Return buffer dword2 Return buffer dword3 Return buffer dword4 <--- sp Now the valuetype is on the local stack it needs to be copied over to the static's heap. This is accomplished via CopyBytes_helper, because the write barriers need to be used if the valuetype contains object references. Before copying the valuetype JIT_InitClass is called to make sure the class has been initialized: 02D42DFB B8 3C 44 E5 06 mov eax,6E5443Ch 02D42E00 50 push eax 02D42E01 B8 00 52 35 79 mov eax,79355200h 02D42E06 FF D0 call eax 02D42E08 83 C4 04 add esp,4 Then the address where the valuetype should be copied is obtained: 02D42E0B B8 7C 2D E5 06 mov eax,6E52D7Ch 02D42E10 50 push eax 02D42E11 B8 3E 33 35 79 mov eax,7935333Eh 02D42E16 FF D0 call eax 02D42E18 83 C4 04 add esp,4 Then the call to CopyBytes_helper is made: 02D42E1B 50 push eax <-- dest. address 02D42E1C 8D 44 24 04 lea eax,[esp+4] <-- source address 02D42E20 50 push eax 02D42E21 B8 10 00 00 00 mov eax,10h <-- size 02D42E26 50 push eax Here the GC map of the value is encoded in the instruction stream. The call pushes the return address on the stack and the return address serves as an argument to CopyBytes helper. This instruction sequence confuses the debugger. In this case the GC map has length of 1 bytes and is located at 02D42E2C 00 So the code should be decoded as: 02D42E27 E8 01 00 00 00 call 02D42E2D 02D42E2C 00 <-- GC map 02D42E2D 59 pop ecx 02D42E2E 51 push ecx 02D42E2F B8 98 18 71 79 mov eax,79711898h 02D42E34 FF D0 call eax 02D42E36 83 C4 10 add esp,10h <-- pop of arguments 02D42E39 83 C4 10 add esp,10h <-- pop of the value At this point the local stack is cleared and the value resides in the proper location. Vladimir This posting is provided "AS IS" with no warranties, and confers no rights. -----Original Message----- From: Discussion of the Rotor Shared Source CLI implementation [mailto:[EMAIL PROTECTED] On Behalf Of Anderson, Todd A Sent: Tuesday, October 14, 2003 5:39 PM To: [EMAIL PROTECTED] Subject: [DOTNET-ROTOR] stsfld for a value type Could someone in the know please help me to understand what the assembly corresponding to the following IL is doing? What I'd like to know is, how are value types treated with respect to stsfld? There are 5 calls in the assembly code...to what do they correspond? Moreover, why does Rotor make calls for these functions rather than using embedded code? thanks, Todd IL code from System.Decimal::.cctor ----------------------------------- IL_0000: ldc.i4.0 IL_0001: ldc.i4.0 IL_0002: ldc.i4.0 IL_0003: ldc.i4.0 IL_0004: ldc.i4.0 IL_0005: newobj instance void System.Decimal::.ctor(int32, int32, int32, bool, unsigned int8) IL_000a: stsfld valuetype System.Decimal System.Decimal::Zero FJit assembly generated for the above IL ---------------------------------------- // next 10 lines for the 5 load constant 0's 02D42DB0 33 C0 xor eax,eax 02D42DB2 50 push eax 02D42DB3 33 C0 xor eax,eax 02D42DB5 50 push eax 02D42DB6 33 C0 xor eax,eax 02D42DB8 50 push eax 02D42DB9 33 C0 xor eax,eax 02D42DBB 50 push eax 02D42DBC 33 C0 xor eax,eax 02D42DBE 50 push eax // subtracting 12 from esp? 02D42DBF 81 C4 F4 FF FF FF add esp,0FFFFFFF4h // copying 0 params onto the stack space we just reserved...why? 02D42DC5 8B 44 24 0C mov eax,dword ptr [esp+0Ch] 02D42DC9 89 44 24 00 mov dword ptr [esp],eax 02D42DCD 8B 44 24 10 mov eax,dword ptr [esp+10h] 02D42DD1 89 44 24 04 mov dword ptr [esp+4],eax 02D42DD5 8B 44 24 14 mov eax,dword ptr [esp+14h] 02D42DD9 89 44 24 08 mov dword ptr [esp+8],eax 02D42DDD 8B 44 24 18 mov eax,dword ptr [esp+18h] // didn't this just overwrite the original 5th parameter we pushed? 02D42DE1 89 44 24 0C mov dword ptr [esp+0Ch],eax // general confusion from here on down... 02D42DE5 8B 54 24 1C mov edx,dword ptr [esp+1Ch] 02D42DE9 8D 44 24 10 lea eax,[esp+10h] 02D42DED 8B C8 mov ecx,eax 02D42DEF 52 push edx 02D42DF0 51 push ecx 02D42DF1 B8 68 45 E5 06 mov eax,6E54568h 02D42DF6 FF 10 call dword ptr [eax] 02D42DF8 83 C4 18 add esp,18h 02D42DFB B8 3C 44 E5 06 mov eax,6E5443Ch 02D42E00 50 push eax 02D42E01 B8 00 52 35 79 mov eax,79355200h 02D42E06 FF D0 call eax 02D42E08 83 C4 04 add esp,4 02D42E0B B8 7C 2D E5 06 mov eax,6E52D7Ch 02D42E10 50 push eax 02D42E11 B8 3E 33 35 79 mov eax,7935333Eh 02D42E16 FF D0 call eax 02D42E18 83 C4 04 add esp,4 02D42E1B 50 push eax 02D42E1C 8D 44 24 04 lea eax,[esp+4] 02D42E20 50 push eax 02D42E21 B8 10 00 00 00 mov eax,10h 02D42E26 50 push eax 02D42E27 E8 01 00 00 00 call 02D42E2D 02D42E2C 00 59 51 add byte ptr [ecx+51h],bl 02D42E2F B8 98 18 71 79 mov eax,79711898h 02D42E34 FF D0 call eax 02D42E36 83 C4 10 add esp,10h 02D42E39 83 C4 10 add esp,10h =================================== This list is hosted by DevelopMentor(r) http://www.develop.com NEW! ASP.NET courses you may be interested in: 2 Days of ASP.NET, 29 Sept 2003, in Redmond http://www.develop.com/courses/2daspdotnet Guerrilla ASP.NET, 13 Oct 2003, in Boston http://www.develop.com/courses/gaspdotnet View archives and manage your subscription(s) at http://discuss.develop.com =================================== This list is hosted by DevelopMentorŪ http://www.develop.com NEW! ASP.NET courses you may be interested in: 2 Days of ASP.NET, 29 Sept 2003, in Redmond http://www.develop.com/courses/2daspdotnet Guerrilla ASP.NET, 13 Oct 2003, in Boston http://www.develop.com/courses/gaspdotnet View archives and manage your subscription(s) at http://discuss.develop.com