Design and Implementation of Generics for the 'NET CLR - PowerPoint PPT Presentation

1 / 25
About This Presentation
Title:

Design and Implementation of Generics for the 'NET CLR

Description:

This paper describes the design and implementation of support for parametric ... Reduced code bloat (typed collections) More readable code ... – PowerPoint PPT presentation

Number of Views:30
Avg rating:3.0/5.0
Slides: 26
Provided by: ayw8
Category:

less

Transcript and Presenter's Notes

Title: Design and Implementation of Generics for the 'NET CLR


1
Design and Implementation of Generics for the
.NET CLR
  • Andrew Kennedy and Don Syme

Presented by Arthur Wong
27th November, 2002
2
Introduction
  • This paper describes the design and
    implementation of support for parametric
    polymorphism in the .NET Common Language Runtime.

3
What are Generics?
  • Generics is another name of parametric
    polymorphism and templates
  • Generics allows classes, structs, interfaces,
    methods to be parameterized by other types, e.g.
    Stackltintgt, Stackltlonggt,Stackltstringgt,etc.
  • Attempts to support C, Oberon, Java, VB .NET,
    Haskell, Ada, Modula-3, C, Eiffel, etc.
  • Achieves high level of code reuse, increase type
    safety, better performance, etc.
  • Differs slightly in syntax and greatly in
    implementation from templates as found in C and
    generics as proposed for the Java language

4
Object-based code in C - Today
  • class Stack private Object items
    private int nitems Stack() nitems 0
    items new Object50 Object Pop()
    if (nitems 0) throw new EmptyException()
    return items--nitems
  • void Push(Object item) ... return
    itemsnitems

5
Object-based code in C - Today
  • Stack s new Stack()
  • s.Push(1)
  • s.Push(2) //boxing
  • int n (int)(s.Pop()) (int)(s.Pop())
    //unboxing
  • Inexpressive. Type system doesnt document what
    should be in a particular stack.
  • Unsafe. Type errors (s.Push(2) ) lead to
    runtime exceptions instead of being caught by
    compiler.
  • Ugly. Casts everywhere,
  • Slow. Casts are slow, and converting base types
    (e.g. ints) to Objects involves expensive boxing
    and unboxing.

6
Generic code in C - Future
  • class StackltTgt private T items private
    int nitems Stack() nitems 0 items
    new T50 T Pop() if (nitems 0)
    throw new EmptyException() return
    items--nitems
  • void Push(T item) if (items.Length
    nitems) T temp items items
    new Tnitems2 Array.CopyltTgt(temp,
    items, nitems) itemsnitems
    item

7
Generic code in C - Future
Stackltintgt s new Stackltintgt() s.Push(1) s.Push
(2) int n s.Pop() s.Pop()
  • Expressive. Type system documents what should be
    in a particular stack.
  • Safe. Type errors (s.Push(2) ) lead to compile
    time error which is caught by compiler.
  • Clear. No Casts
  • Fast. Eliminating boxing and unboxing.

8
IL for Object-based and Generic
Object-based Stack
Generic Stack
  • .class Stack
  • .field private class System.Object store
  • .field private int32 size
  • .method public void .ctor()
  • ldarg.0
  • call void System.Object.ctor()
  • ldarg.0
  • ldc.i4 10
  • newarr System.Object
  • stfld class System.Object Stackstore
  • ldarg.0
  • ldc.i4 0
  • stfld int32 Stacksize
  • ret
  • .method public void Push(class System.Object x)
  • ret
  • .method public class System.Object Pop()
  • .class StackltTgt
  • .field private !0 store
  • .field private int32 size
  • .method public void .ctor()
  • ldarg.0
  • call void System.Object.ctor()
  • ldarg.0
  • ldc.i4 10
  • newarr !0
  • stfld !0 Stacklt!0gtstore
  • ldarg.0
  • ldc.i4 0
  • stfld int32 Stacklt!0gtsize
  • ret
  • .method public void Push(!0 x)
  • ret
  • .method public !0 Pop()

9
IL for Object-based and Generic
Object-based Stack cont
Generic Stack cont
  • .
  • .
  • .
  • .method public static void Main()
  • .entrypoint
  • .maxstack 3
  • .locals (class Stack)
  • newobj void Stack.ctor()
  • stloc.0
  • ldloc.0
  • ldc.i4 17
  • box System.Int32
  • call instance void StackPush(class
    System.Object)
  • ldloc.0
  • call instance class System.Object StackPop()
  • unbox System.Int32
  • ldind.i4
  • ldc.i4 17
  • ceq
  • .
  • .
  • .
  • .method public static void Main()
  • .entrypoint
  • .maxstack 3
  • .locals (class Stackltint32gt)
  • newobj void Stackltint32gt.ctor()
  • stloc.0
  • ldloc.0
  • ldc.i4 17
  • call instance void Stackltint32gtPush(!0)
  • ldloc.0
  • call instance !0 Stackltint32gtPop()
  • ldc.i4 17
  • ceq

10
Design of Generics
11
Implementation of Generics
  • Two traditional implementation routes of
    parametric polymorphism
  • Representation and code specialization
  • Relatively easy implementation
  • Code explosion, especially in polymorphism
    recursion ? very simple class may create hundred
    or thousand times of code in compile time.
  • E.g. C
  • Representation and code sharing
  • Decrease code size
  • Introduce box/unboxing (ex. object based Stack)
  • E.g. Todays C

12
Implementation of Generics
  • Introduction of Generics Implementation
  • Generics take advantage of dynamic loading
    Just-in-Time compilation of CLR
  • Code generation at runtime on demand
  • CLR can choose mix-and-match specialization and
    sharing
  • The current challenge is to implement
  • Support exact runtime types
  • Code sharing as much as possible

13
Implementation of Generics
  • 1. Dynamic code expansion and sharing
  • Instantiating generic classes and methods is
    handled by the CLR.
  • Generate code on demand using Just-in-Time
    compiler
  • Sharing code for compatible instantiations
  • Avoid wasting time and space in generating
    specialized code that never gets executed
  • Primitive (Value) types are mutually
    incompatible
  • All reference types are compatible with each
    other

14
Implementation of Generics
  • 2. Implementation of runtime types for objects
  • Objects carry runtime type information
  • Objects are represented by a vtable pointer
    followed by the objects contents
  • Contents such as fields or array elements
  • vtables main role is virtual method dispatcher
  • It contains a code pointer for each methods

15
Implementation of Generics
  • If polymorphic objects are many, they extra word
    (type info) is very expansive (1 and 2 OUT!)
  • of instantiations ltlt of objects (3 and 4
    still OK)
  • Virtual method calls (vtable visits) are
    extremely frequent in OO code (3 OUT)

Inline
Share the original vtable via an indirection
  • For compatible instances, they share same class
    code.
  • But we need to keep the exact run time type for
    different instances
  • There is a conflict for code sharing and type
    specialization
  • There are four ways to implement the runtime
    types for objects

3
1
4
2
Example (DictltT,Ugt class) Dictltint,objectgt and
Dictltbool,stringgt
Via an direction to a hash-consed instantiation
Duplicate it per instantiation
16
Implementation of Generics
  • No boxing and unboxing
  • Due to type specialization the implementation
    never needs to box values of primitive type
  • Provides simplicity and performance
  • Optimized use of runtime type information
  • Efficient in the presence of code sharing and
    with minimal overhead (allocate memory for
    instance and indirection method call thru vtable)
    for programs that make no use of them

17
How does it work?
1a. Look for Stackltintgt1b. Nothing exists yet,
so create structures for Stackltintgt
Stackltintgt intStack1 new Stackltintgt()Stackltin
tgt intStack2 new Stackltintgt()Stackltstringgt
stringStack new Stackltstringgt()Stackltobjectgt
objStack new StackltCustomergt()intStack1.Push(
15)stringStack.Push(xxx)customerStack.Push
(anyCustomer)
2a. Look for Stackltintgt2b. Type already loaded!
3a. Look for Stackltstringgt3b. ltstringgt not
compatible with ltintgt, and it is reference type,
so create structures for Stackltstringgt
4a. Look for StackltCustomergt4b. Reference type
is unlike with value types, another specialized
version of Stack class is not created for the
Customer type. Instead, an instance of the
specialized version of Stack is created and the
Customer type is allocated memory and a pointer
is set to reference it.
18
How does it work?
Stackltintgt intStack1 new Stackltintgt()Stackltin
tgt intStack2 new Stackltintgt()Stackltstringgt
stringStack new Stackltstringgt()Stackltobjectgt
objStack new StackltCustomergt()intStack1.Push(
15)stringStack.Push(xxx)customerStack.Push
(anyCustomer)
Compile code for Stackltintgt.Push
Compile code for Stackltstringgt.Push
Re-use code from Stackltstringgt.Push
19
Performance of Generics
  • Performance test
  • Stack with repeated push and pops of 0...10000
    elements
  • Test code
  • S new stack
  • c constant
  • for m 1 ... 10000 do
  • Spush(c) m times
  • Spop() m times
  • Test cases
  • (a) Object-based (Todays C) Stack
  • (b) Generics (Future C) Stackltintgt
  • (c) Specialized (Mono) Stack_int
  • 5X speedup Generics vs. Object-based
  • A bit speedup (in string and int cases) Generics
    vs. Specialized

20
Performance of Generics
  • Runtime type computations
  • Generic allocation (vtable and other structures
    setup) 10 to 20 slower (overhead) in generic
    code, which consider acceptable

21
Performance of Generics
  • Costing runtime type creation
  • Runtime type computations
  • Generic allocation (vtable and other structures
    setup) 10 to 20 slower (overhead) in generic
    code, which consider acceptable

22
Design Comparison of Generics
23
Comparison with C templates
  • What C gets wrong
  • Efficiency
  • nearly all implementations code-expand
  • Safety
  • not checked at declaration use, but at link
    time
  • Simplicity
  • very complicated (usages)

24
Comparison with C templates
  • What .NET Generics get right
  • Efficiency
  • code expansion managed by the CLR
  • Safety
  • check at declaration use
  • Simplicity
  • there are some corners, but the mechanism is
    simple to explain use

25
Summary
  • .NET generics is a world first cross-language
    generics in a high-level virtual machine design.
  • Implementation
  • The runtime level is the right place to implement
    generics for .NET CLR
  • Reduced code bloat (typed collections)
  • More readable code
  • Good performance ? no boxing, no downcasts

At OOPSLA in November 2002, it is announced that
Generics will be in next major release .NET CLR
26
  • The End Thank You!
Write a Comment
User Comments (0)
About PowerShow.com