2015-10-18 14 views
10

Attualmente sto leggendo il libro intitolato Pro .NET Performance. Uno dei suoi capitoli contiene informazioni dettagliate sulla struttura interna dei tipi di riferimento. La tabella dei metodi è uno dei campi interni della struttura di layout del tipo di riferimento. In questo libro si dice che la tabella dei metodi consiste in informazioni su TUTTI i metodi di una classe. Sto cercando di verificare questa teoria con un piccolo programma.net table structure della struttura clr

class MyClass 
{ 
    public void M() 
    { 
    } 
} 

static void Main(string[] args) 
{ 
    MyClass m = new MyClass(); 
    m.M(); 
    Console.ReadLine(); 
} 

ho avviare questo programma con la sessione di WinDbg mio WinDbg è simile al seguente

!clrstack -a 
ConsoleApp.Program.Main(System.String[]) [c:\visual studio 2012\Projects\Algorithms\ConsoleApp\Program.cs @ 36] 
    PARAMETERS: 
     args (0x00bff274) = 0x02ba2fbc 
    LOCALS: 
     0x00bff270 = 0x02ba2fd8 

0x02ba2fd8 - è l'indirizzo dell'istanza MyClass Cosa devo fare è cercare di eseguire il dump esempio MyClass

!do 0x02ba2fd8 

Name:  ConsoleApp.MyClass 
MethodTable: 00f84d74 
EEClass:  00f81840 
Size:  12(0xc) bytes 
File:  C:\visual studio 2012\Projects\Algorithms\ConsoleApp\bin\Debug\ConsoleApp.exe 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
601a4544 4000001  4   System.Int32 1 instance  10 Z 

passo successivo è quello di eseguire il dump tavolo metodo (il suo indirizzo è 00f84d74)

!dumpmt -md 00f84d74 

EEClass:   00f81840 
Module:   00f83fbc 
Name:   ConsoleApp.MyClass 
mdToken:   02000002 
File:   C:\visual studio 2012\Projects\Algorithms\ConsoleApp\bin\Debug\ConsoleApp.exe 
BaseSize:  0xc 
ComponentSize: 0x0 
Slots in VTable: 6 
Number of IFaces in IFaceMap: 0 
-------------------------------------- 
MethodDesc Table 
    Entry MethodDe JIT Name 
6005a2c8 5fcf8354 PreJIT System.Object.ToString() 
60065600 5fcf835c PreJIT System.Object.Equals(System.Object) 
600319b0 5fcf837c PreJIT System.Object.GetHashCode() 
600316e8 5fcf8390 PreJIT System.Object.Finalize() 
012604c0 00f84d6c JIT ConsoleApp.MyClass..ctor() 
012604f8 00f84d60 JIT ConsoleApp.MyClass.M() 

L'output! Comando dumpmt mostra che tabella metodo contiene entrata per il metodo M(). Ma quando provo ad eseguire il dump di memoria all'indirizzo 00f84d74

dd 00f84d74 

00f84d74 00000200 0000000c 00024188 00000004 
00f84d84 601a299c 00f83fbc 00f84db0 00f81840 
00f84d94 012604c0 00000000 00f84da0 6005a2c8 
00f84da4 60065600 600319b0 600316e8 00000080 
00f84db4 00000000 03ba3500 00000000 03ba3504 
00f84dc4 00000000 00000000 00000000 00000000 
00f84dd4 00000000 00000000 00000000 00000000 
00f84de4 00000000 00000000 00000000 00000000 

Non riesco a trovare alcun riferimento all'indirizzo di M() metodo (012604f8)

Quindi la domanda è se tabella di metodo contiene riferimenti alla non metodi virtuali? Dove sono memorizzati?

+1

012604f8 è l'indirizzo della descrizione dei metadati del metodo. La tabella dei metodi contiene oltre gli indirizzi dei metodi. I 4 metodi virtuali ereditati da Object partono da 00f84da0 (6005a2c8 ecc.), I due metodi della classe non sono ancora jitted. –

+0

Grazie, Hans. Il metodo M() è già compilato con JIT. Ma non c'è una voce nella tabella dei metodi per M(). – dmitryo

risposta

7

enter image description here

grazie a uno dei miei colleghi che po 'di luce alla mia domanda. Risulta che i puntatori del metodo si trovano in offset negativi rispetto al puntatore della tabella dei metodi