1 / 57

Introduzione al CLR/MSIL

Introduzione al CLR/MSIL. Alfredo Paolillo e Marco Servetto. Vocabolario. IL: Intermediate Language, Standard ECMA del 1997 MSIL: Microsoft IL, Implementazione Microsoft di IL. Introduzione. Perché .NET Ambiente di esecuzione Common Language Runtime. Perché .NET.

kalani
Download Presentation

Introduzione al CLR/MSIL

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduzione alCLR/MSIL Alfredo Paolillo e Marco Servetto

  2. Vocabolario • IL: • Intermediate Language, Standard ECMA del 1997 • MSIL: • Microsoft IL, Implementazione Microsoft di IL

  3. Introduzione • Perché .NET • Ambiente di esecuzione • Common Language Runtime

  4. Perché .NET • Difficile effettuare sviluppo omogeneo • Molto tempo viene dedicato a far comunicare i vari “strati” • Serve un salto qualitativo per semplificare lo scenario

  5. Codici • Evoluzione • Codice nativo • Codice interpretato • Codice MSIL

  6. Codice nativo Sorgenti Compilatore Codicenativo(.EXE) Output

  7. Codice interpretato Sorgenti Interprete Output

  8. Codice MSIL Sorgenti Compilatore.NET CodiceMSIL (Assembly) .EXE/.DLL Codicenativo Output Compilatore JIT

  9. Codice MSIL Sorgenti Compilatore.NET CodiceMSIL (Assembly) .EXE/.DLL Codice + metadati Codicenativo Output Compilatore JIT

  10. Codice MSIL Ambiente di esecuzione .NET Runtime Sorgenti Compilatore.NET CodiceMSIL (Assembly) .EXE/.DLL Codicenativo Output Compilatore JIT

  11. Motori JIT • Inizialmente previsti 4 motori:

  12. JIT – Just in Time Compiler • In teoria, come con Java, è possibile compilare MSIL ed eseguirlo (interpretato) in qualsiasi ambiente che supporti l’esecuzione • La compilazione di un’applicazione da un tipo di codice assembly quale MSIL verso un codice eseguibile sulla macchina nativa dovrebbe appesantire le prestazioni dell’applicazione • È quello che succede?

  13. JIT – Just in Time Compiler • Il codice non viene caricato tutto in memoria • il compilatore JIT compila solo il codice necessario, quindi memorizza nella cache il codice nativo compilato per riutilizzarlo • L’overhead è una lieve differenza che, nella maggior parte dei casi, non verrà rilevata

  14. JIT – Just in Time Compiler • Quando viene caricata una classe, il caricatore aggiunge uno stub a ogni metodo della classe • La prima volta che viene chiamato il metodo, il codice stub cede il controllo al compilatore JIT, che compila MSIL nel codice nativo. • Lo stub viene quindi modificato per puntare al codice nativo appena creato, affinché le chiamate successive passino direttamente al codice nativo

  15. Indipendenza dalla piattaforma • .NET è un’implementazione di CLI • Common Language Infrastructure • CLI è uno standard ECMA • ECMA-334, ECMA-335 • Esistono già altre implementazioni di CLI: • SSCLI (Microsoft, per Windows, FreeBSD e Macintosh) • Mono (per Linux) • DotGNU • Intel OCL (Open CLI Library) • …

  16. Codice IL Tutto questo assomiglia a qualcosa di già visto? Forse Java? • Ci sono delle differenze • Un compilatore Java crea bytecode, che in fase di esecuzione viene interpretato tramite JVM • .NET crea un codice nativo

  17. Codice IL • Un vantaggio rilevante offerto da .NET Framework rispetto a Java e JVM è la scelta del linguaggio di programmazione • JVM solo Java • .NET Multilinguaggio (VB.net, C#, J# etc…) • Vediamo un esempio di IL

  18. Modulo(file PE) Codice IL Metadati Manifest Assembly Assembly

  19. Metadati • Concetto chiave in .NET • Informazioni sui tipi di un assembly • Generati automaticamente dai compilatori • Estendibili da terze parti • Formato binario rappresentabile con XML: • XML Schema (XSD) • Serializzazione e deserializzazione oggetti a runtime in XML

  20. Metadati • Descrizione di un assembly • Identità: nome, versione, cultura [, pubblic key] • Tipi esportati • Assembly da cui dipende • Descrizione dei tipi • Nome, visibilità, classe base, interfacce implementate • Attributi custom • Definiti dall’utente • Definiti dal compilatore

  21. Codice IL • Proviamo adesso a scrivere e compilare dei semplici programmi in C# e proviamo ad analizzarli

  22. Codice IL • Esempio 1 namespace testUno { public class esempioUno { public esempioUno() { } static void Main(string[] args) { int primaVariabile = 0x1234; int secondaVariabile = 0xabcdef; } } }

  23. Codice IL • Il file eseguibile è costituito da due parti: • la prima è il codice MSIL, utilizzato per generare il codice nativo • la seconda è rappresentata dai metadati • Con un tool in dotazione con l’SDK possiamo Diassemblare il file ottenuto dalla compilazione • Otterremo il seguente output • Tralasceremo comunque alcuni dettagli come il codice del costruttore di classe

  24. Codice IL .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 13 (0xd) .maxstack 1 .locals init (int32 V_0, int32 V_1) IL_0000: ldc.i4 0x1234 IL_0005: stloc.0 IL_0006: ldc.i4 0xabcdef IL_000b: stloc.1 IL_000c: ret } // end of method esempioUno::Main

  25. Codice IL – istruzioni principali • .entrypoint • Specifies that this method is the entry point to the application (only one such method is allowed). • .maxstack • int32 specifies the maximum number of elements on the evaluation stack during the execution of the method • .locals [init] • Defines a set of local variables for this method. • ldc.i4: • Description Push num of type int32 onto the stack as int32. • stloc.0: • Description: Pop value from stack into local variable 0. • ret: • Description: return from method, possibly returning a value

  26. Codice IL – Metainformazioni ScopeName : testUno.exe MVID : {F01C8E38-E942-43D9-9D71-95D37789D357} =========================================================== Global functions ------------------------------------------------------- Global fields ------------------------------------------------------- Global MemberRefs ------------------------------------------------------- TypeDef #1 ------------------------------------------------------- TypDefName: testUno.esempioUno (02000002) Flags : [Public] [AutoLayout] [Class] [AnsiClass] (00100001) Extends : 01000001 [TypeRef] System.Object Method #1 ------------------------------------------------------- MethodName: .ctor (06000001) Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] (00001886) RVA : 0x00002050 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. Method #2 [ENTRYPOINT] ------------------------------------------------------- MethodName: Main (06000002) Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091) RVA : 0x00002064 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] ReturnType: Void 1 Arguments Argument #1: SZArray String 1 Parameters (1) ParamToken : (08000001) Name : args flags: [none] (00000000)

  27. Codice IL – Metainformazioni TypeRef #1 (01000001) ------------------------------------------------------- Token: 0x01000001 ResolutionScope: 0x23000001 TypeRefName: System.Object MemberRef #1 ------------------------------------------------------- Member: (0a000002) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. TypeRef #2 (01000002) ------------------------------------------------------- Token: 0x01000002 ResolutionScope: 0x23000001 TypeRefName: System.Diagnostics.DebuggableAttribute MemberRef #1 ------------------------------------------------------- Member: (0a000001) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 2 Arguments Argument #1: Boolean Argument #2: Boolean

  28. Codice IL – Metainformazioni Signature #1 (0x11000001) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 2 Arguments Argument #1: I4 Argument #2: I4 Assembly ------------------------------------------------------- Token: 0x20000001 Name : testUno Public Key : Hash Algorithm : 0x00008004 Major Version: 0x00000000 Minor Version: 0x00000000 Build Number: 0x00000000 Revision Number: 0x00000000 Locale: <null> Flags : [SideBySideCompatible] (00000000) CustomAttribute #1 (0c000001) ------------------------------------------------------- CustomAttribute Type: 0a000001 CustomAttributeName: System.Diagnostics.DebuggableAttribute :: instance void .ctor(bool,bool) Length: 6 Value : 01 00 00 01 00 00 > < ctor args: ( <can not decode> )

  29. Codice IL – Metainformazioni AssemblyRef #1 ------------------------------------------------------- Token: 0x23000001 Public Key or Token: b7 7a 5c 56 19 34 e0 89 Name: mscorlib Major Version: 0x00000001 Minor Version: 0x00000000 Build Number: 0x00001388 Revision Number: 0x00000000 Locale: <null> HashValue Blob: Flags: [none] (00000000)

  30. Codice IL I metadati vengono organizzati in tabelle, in cui fondamentalmente viene descritto ciò che il codice definisce e a cui fa riferimento Prestiamo attenzione a questa parte di codice: CallCnvntn: [LOCALSIG] 2 Arguments Argument #1: I4 Argument #2: I4

  31. Codice C# • Proviamo adesso a compilare il seguente codice FILE:esempioDueB namespace testDue { public class esempioDueB { static void Main(string[] args) { esempioDueA variabile = new esempioDueA(); variabile.printString(); } } }

  32. Codice C# FILE: esempioDueA using System; namespace testDue { public class esempioDueA { public esempioDueA() { } public void printString() { string s = "Hello!!!!"; Console.Write(s); } } }

  33. Codice IL • Disassembliamo: A differenza di prima dovremo analizzare due codici

  34. Codice IL .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 13 (0xd) .maxstack 1 .locals init (class testDue.esempioDueA V_0) IL_0000: newobj instance void testDue.esempioDueA::.ctor() IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: callvirt instance void testDue.esempioDueA::printString() IL_000c: ret } // end of method esempioDueB::Main

  35. Codice IL .method public hidebysig instance void printString() cil managed { // Code size 13 (0xd) .maxstack 1 .locals init (string V_0) IL_0000: ldstr "Hello!!!!" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: call void [mscorlib]System.Console::Write(string) IL_000c: ret } // end of method esempioDueA::printString

  36. Codice IL Principali differenze rispetto al codice precedente: • Newobj: • Assembli format: newobjctor • Description: allocate an uninitialized object or value type and call ctor • Call: • Assembli format: call method • Description: Call method described by method • Callvirt: • Assembli format: callvirt method • Description: Call a method associated with obj

  37. Codice IL • Andiamo nuovamente a riesaminare le meta-informazioni: Signature #2 (0x11000002) (EsempioDueB) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 1 Arguments Argument #1: Class testDue.esempioDueA Signature #1 (0x11000001) (EsempioDueA) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 1 Arguments Argument #1: String

  38. Codice IL – Metainformazioni Method #2 (definizione del metodo invocato dalla call) ------------------------------------------------------- MethodName: printString (06000002) Flags : [Public] [HideBySig] [ReuseSlot] (00000086) RVA : 0x00002064 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. .................. User Strings (costante) ------------------------------------------------------- 70000001 : ( 9) L"Hello!!!!”

  39. Codice C# • Passaggio di parametri: namespace testTre { public class esempioTreA { static void Main(string[] args) { string s = ("HELLO!!!!!!!!!!!!!!!!!!!!!!!!!!"); esempioTreB variabile = new esempioTreB(); variabile.printString(s); } } }

  40. Esempio C# Using system; public class esempioTreB { public esempioTreB() { } public void printString(string s) { Console.Write(s); } }

  41. Codice IL .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 20 (0x14) .maxstack 2 .locals init (string V_0, class testTre.esempioTreB V_1) IL_0000: ldstr "HELLO!!!!!!!!!!!!!!!!!!!!!!!!!!" IL_0005: stloc.0 IL_0006: newobj instance void testTre.esempioTreB::.ctor() IL_000b: stloc.1 IL_000c: ldloc.1 IL_000d: ldloc.0 IL_000e: callvirt instance void testTre.esempioTreB::printString(string) IL_0013: ret } // end of method esempioTreA::Main

  42. Codice IL .method public hidebysig instance void printString(string s) cil managed { // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.1 IL_0001: call void [mscorlib]System.Console::Write(string) IL_0006: ret } // end of method esempioTreB::printString

  43. Codice IL • ldarg.1 • Assembli format: ldarg.1 • Description: Load argument 1 onto stack Esistono anche delle varianti, ad esempio: • ldarg num • Assembli format: ldarg num • Description: Load argument numbered num onto stack.

  44. Codice IL – Metainformazioni TypeDef #1 ------------------------------------------------------- TypDefName: testTre.esempioTreB (02000002) Flags : [Public] [AutoLayout] [Class] [AnsiClass] (00100001) Extends : 01000001 [TypeRef] System.Object Method #1 ------------------------------------------------------- MethodName: .ctor (06000001) Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] (00001886) RVA : 0x00002050 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. Method #2 ------------------------------------------------------- MethodName: printString (06000002) Flags : [Public] [HideBySig] [ReuseSlot] (00000086) RVA : 0x00002064 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String 1 Parameters (1) ParamToken : (08000001) Name : s flags: [none] (00000000)

  45. Codice IL – Metainformazioni Signature #1 (0x11000001) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 2 Arguments Argument #1: String Argument #2: Class testTre.esempioTreB Assenza di Signature #2 La classe su cui viene invocato il metodo printString non ha dichiarazioni locali

  46. Garbage Collector • Gli oggetti vengono distrutti automaticamente quando non sono più referenziati • Algoritmo Mark-and-Compact

  47. Garbage Collector - fase 1: Mark NextObjPtr Root set Oggetti “vivi” Oggetti non raggiungibili Spazio libero

  48. Garbage Collector - fase 2: Compact Spazio recuperato NextObjPtr Root set Oggetti “vivi” Spazio libero

  49. GC e distruzione deterministica • In alcuni casi serve un comportamento di finalizzazione deterministica: • Riferimenti a oggetti non gestiti • Utilizzo di risorse che devono essere rilasciate appena termina il loro utilizzo • Non si possono usare i finalizzatori, che non sono richiamabili direttamente • Implementare l’interfaccia IDisposable

  50. Common Type System • Tutto è un oggetto • Due categorie di tipi: • Tipi reference (riferimento) • Allocati su heap gestito • Tipi value (valore) • Allocati su stack o in oggetti gestiti (reference) • Tutti i tipi value possono essere visti come tipi reference • Boxing

More Related