Date post: | 31-Dec-2015 |
Category: |
Documents |
Upload: | letitia-mccormick |
View: | 218 times |
Download: | 1 times |
Page 1 © Imperial College London
Flexible Dynamic Linkingfor .NET
Anders Aaltonen
Alex Buckley
Susan Eisenbach
Acknowledgement: Microsoft Research
Page 2 © Imperial College London
Agenda
• Introduction to dynamic linking
• Flexibility and safety at link-time
• Developer-centric flexibility
• Implementation
• Conclusion
Page 3 © Imperial College London
Dynamic linking
Turns
ldfld MemberDescriptor
generated at compile-time
into
ldfld 0x100405
in the run-time environment
by using assembly and class definitions
Page 4 © Imperial College London
Dynamic linking
• Is taken as given in modern execution environments
• Saves space by sharing code between programs
• Enables configurable binding policies
– User/system-wide upgrades (v1.0 → v2.0)
– Servicing policy (v1.1.9 → v1.2.0)
– Unification policy (use version corresponding to the CLR)
– Local and remote probing (check GAC, then URL)
• Supports bytecode verification on the user’s machine
Page 5 © Imperial College London
call void [mscorlib]System.Console::WriteLine(string)
Assembly metadataimport mscorlib =
MSCorLib, v1.1.1322, PK=9999, Culture=US
Class metadata
export A,B,C,D
IL code namespace System;class Console { void WriteLine(string s){…}}
LinkerCalc
v1.2.3.4
PublicKey=12345
Culture=UK
Assembly metadata
Class metadata
export System.Console
IL code
MSCorLib
v1.1.1322
PublicKey=99999
Culture=US
Page 6 © Imperial College London
Linking is constrained by compiler decisions
call void[mscorlib]System.Console::WriteLine(string)
Console.WriteLine(“Hi”);
call void[monolib]System.Console::WriteLine(string)
Known to the compiler
Available at runtime
Page 7 © Imperial College London
Platform- or vendor-specific assemblies might be available at runtime only
• Generic ODBC v. SQLServer ODBC
• Microsoft FTP v. third-party SecureFTP
• Imperial’s LTSA model-checker can use non-redistributable NASA algorithms
• Avoid compile-time dependencies on NASA code?
• (Separate compilation still checks dependencies)
• Have to use error-prone reflection
Page 8 © Imperial College London
How can I bind to the runtime environment when the compiler forces its choices on me?orInstead of the database library,how can I target a database library?
Source codeCompile-time
classesRun-time classes
new DBLib() DBLib OK SQLSvrLib OK
new DBLib() (None) OKDBLib,
SQLSvrLibOK
Page 9 © Imperial College London
Assembly type variable
call void [X]System.Console::WriteLine(…)
call void [mscorlib]System.Console::WriteLine(…)
Class type variable
call void [mscorlib]Y::WriteLine(…)
call void [mscorlib]System.Console::WriteLine(…)
Initial idea: make bytecode more flexible
Substitute compiler’s X with mscorlib at link-time
Substitute compiler’s Y at link-time
Page 10 © Imperial College London
Flexible bytecode: True late binding
• Extend Fusion servicing policies to re-naming
• Use “generic” classes without naming a specific assembly
– Different versions of an assembly: Development/Testing/Production/Archive
– Develop binary components off-site, using stub assemblies,then execute on-site, using full assemblies
– Simplified command-line compilation (fewer /r: args)
• Use a specific assembly without mentioning a class
– Code to the interface, not the implementation[mscorlib]List l = new [mscorlib]X();
Page 11 © Imperial College London
Flexible bytecode: Orthogonal to generics
• Generics make an interface type-safe, but any given type parameter needs a specific implementation
• Type parameters in a generic class are determined by a particular (dynamic) instantiation List<Person> l = new ArrayList<Person>();
• Type variables in flexible bytecode are determinedby arbitrary agents (VM, programmer, user)with different scopes (global, assembly, class)
Page 12 © Imperial College London
Flexible bytecode: Type-safety
• The substitute for an assembly or class should provide members used by the programmer, e.g.
– Assembly X provides interface List
– Interface List provides ‘void compare(List l);’
– Class Y is a subclass of/implements List
So:
• Collect constraints from bytecode
• Search the GAC for suitable assemblies at run-time
• OK?
Page 13 © Imperial College London
Problems with constraints
• Subtype constraints require data-flow analysis
• Unreachable code may be over-constraining
• Constraints say nothing about behaviour
• Debugging is impractical if truly arbitrary components are chosen at run-time
Page 14 © Imperial College London
Semantic substitutions
• Policy: Programmer must know valid assemblies/classes
• Custom attributes declare possible substitutions
[LinkAssembly(A1, A2)]
[LinkAssembly(A1, A3)]
[LinkClass(C1, C2)]
[LinkClass(C1, C3)]
• Any assembly or class can be independently substituted
→ All types are type variables
• Need member and subtype constraints to avoid resolution errors (but not guide substitutions)
[LinkMember(A1, C1, ‘B m(D)’)]
[LinkSubtype(A1, C1, A2, C2)]
Page 15 © Imperial College London
Attribute scoping
• We do not always want flexible bytecode
• Minimise impact by choosing the right scope [assembly: LinkClass(C,…)]
[LinkClass(C,…)]
class App {
void m() { …C… } // Search class,assembly
[LinkClass(C,…)]
void n() { …C…} // Use method’s [LinkClass] }
• Only the most local scope is used
Page 16 © Imperial College London
Substitution interfaces
• Group substitutions by platform/vendor/maturity:[LinkAssembly(A1,A1_32,”win32”)]
[LinkAssembly(A2,A2_32,”win32”)]
[LinkAssembly(A1,A1_64,”win64”)]
[LinkAssembly(A2,A2_64,”win64”)]
• On a Win32 machine, only the A1→A1_32 and A2→A2_32 substitutions will be possible
• Once A1 or A2 has been substituted, we should stay within the “win32” interface
Page 17 © Imperial College London
Interface policies
[LinkAssembly(A1,A1_32,”win32”,
LOCAL_INTERFACE)]
Demand “win32” [LinkAssembly]+[LinkClass] substitutions
[LinkAssembly(A1,A1_32,”win32”,
LOCAL_INTERFACE_PREFERRED)]
Try “win32” substitutions first, but allow others on failure
[LinkAssembly(A1,A1_32,”win32”,
LOCAL_INTERFACE_EAGER)]
Eagerly check that all “win32” substitutions will succeed
[LinkAssembly(A1,A1_32,”win32”,ANY_INTERFACE)]
No restrictions on later substitutions
Page 18 © Imperial College London
Hello.cs
Preparing bytecode for flexible linking
[assembly: LinkClass]
[LinkClass]
class App {
void m() { … }
[LinkClass] void n() { … } }
Hello.exe
Assembly metadata
IL code
Class metadata
Hello.il
.assembly Hello {
.custom instance LinkClass
.class App extends … {
.custom instance LinkClass
Hello.il
.assembly Hello {
.custom instance LinkClass
.custom instance LinkMember
.class App extends … {
.custom instance LinkClass
.custom instance LinkMember
Compiler
ILDASM
Infer member constraints
Avoid source code: compilers are hard to change, and there are many of them
Metadata is backward - compatible
Must be able to compile in some default environment
ILASM
Page 19 © Imperial College London
Just-In-Time substitution
• CLI-compliant linking is very flexible
• Verification is optional
• Resolution may occur as early as install time, as late as execution time
• CLR/SSCLI is lazy: resolution and verification happen at JIT-compilation
• Extend resolution to handle [Link*()] attributes
• “JIT-substitution”
Page 20 © Imperial College London
Standard resolution
Modifying the SSCLI
Verifier/JIT compiler
FDL resolution
Fusion
Assembly/class loading
Filesystem
Constraint verification
x86 code
Attribute collection
Resolution cacheCEEInfo::findClass/Field/Method
Page 21 © Imperial College London
Attribute collection
• A LinkContext encapsulates a single resolution attempt, e,g, call [A]C::m …
= A fully-qualified member reference needing resolution
+ Nearest [LinkAssembly] and [LinkClass] attributes in scope
+ Set of constraints applying to these attributes
• JIT-compiling a method creates a MasterLinkContext
– Finding custom attributes is easy with Metadata Importers
• LinkContexts in a method share a MasterLinkContext
• Need a LinkContext for caller’s and callee’s scope
Page 22 © Imperial College London
Issue: Static resolution of flexible fields
• C# 1.x compiler resolves fields statically
• Effect is to “hide” members that should be substituted
• Java 1.3 did the same; changed in 1.4
// Compile-time envclass A { String f;}class B : A {}
[LinkClass(B,C)]new B().f;
[LinkClass(B,C)]ldfld […]A::f // Does not match // the LinkClass(B,…)
compiles to
Page 23 © Imperial College London
Conclusion
• .NET is a good home for flexible dynamic linking– Different frameworks have different API implementations
→ more choices for the programmer in [Link*]
– Resolution guided by rich metadata
– Easy to represent substitutions and constraints
– Flexible bytecode is still verifiable (type-safe)
– Tiny amounts of code in the SSCLI are very effective
• Future work– Modify compiler(s) for independent compilation
– Enforce consistent representation for substituted types
– Overcome static resolution problem