1 / 30

Extending Rotor with Structural Reflection to support Reflective Languages

Extending Rotor with Structural Reflection to support Reflective Languages. Introduction. Adaptiveness and Adaptability. The dynamic manipulation (evolution) of system behavior and structure is becoming increasingly important to develop adaptive and adaptable applications

bo-hartman
Download Presentation

Extending Rotor with Structural Reflection to support Reflective Languages

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. Extending Rotor with Structural Reflection to support Reflective Languages

  2. Introduction Adaptiveness and Adaptability • The dynamic manipulation (evolution) of system behavior and structure is becoming increasingly important to develop adaptive and adaptable applications • A system is adaptive if it is able to change its behavior (by itself) according to the changes in its environment, or within itself • A system is adaptable if the user could dynamically produce a new system behavior • There are different approaches to construct adaptable(ive) software • Adaptive (Dynamic) Languages • Python, Dylan, Ruby, Smalltalk, Self or CLOS) • Adaptive Paradigms • Agile and Adaptive Methodologies • A lot of Domain Specific Adaptive Frameworks

  3. Introduction Dynamic Languages • Programming languages that support reasoning about / customizing their own structure, behavior and environment, supporting self-modifying features and dynamic code generation • As a side effect of this dynamism, dynamic programming languages are dynamically typed • For example, it is possible to dynamically • Change the interface of objects and classes • Modify the implementation of specific methods • Adapt the structure of objects • Generate new code • Modify an object’s type • Customize the behavior of a set of classes (meta-classes)

  4. Introduction Pros and Cons • Facilitate the development of adaptive and adaptable software • Design-time and runtime integration • Making new software entities first-class objects (modules, classes, meta-classes, objects, methods, fields and types) increases behavior parameterization (factorization) • Due to these benefits, static languages (Java or C#) are incorporating more and more dynamic features • However, static type-checking has important benefits • The lack of static type-checking may cause a loss of safety • Test-driven development (PyUnit, JUnit or NUnit) could be used in some scenarios • Mixing static and dynamic type-checking could be interesting, when developing adaptable software • Performance caused by inferring types (and checking) at runtime

  5. Introduction ЯRotor • Our Project, Extending Rotor with Structural Reflection to support Reflective Languages has tried to response these questions • Is it possible to improve runtime performance of reflective languages? • Is it possible to make static and dynamic languages interoperate? • Is it possible to combine the best of both worlds (static typing where possible, dynamic typing when needed)? • The main objective is to enhance Rotor with structural reflective primitives offered by dynamic languages, in order to evaluate • feasibility of making the CLI a runtime reflective platform (combining static and dynamic languages) • performance cost (vs. static rotor) and performance benefits (vs. interpreted counterparts)

  6. Contents • Introduction • Reflection • Structural Reflection in Rotor • Implementation • Assessment • Conclusions

  7. Reflection Reflection • Reflection is the capability of a computational system to reason about/act upon itself, adjusting itself to changing conditions • Its computational domain is enhanced by its own representation, offering its semantics and structure as if they were computable data • Runtime reflection offers dynamic adaptation of running systems (dynamic languages) • Regarding to what can be reflected, reflection can be classified into • Introspection: program structure may be consulted, but not modified (e.g. Java and C# reflective capabilities) • Structural Reflection: program structure can be modified and those changes should be reflected (e.g. modifying attributes and methods of Python classes) • Computational Reflection: modifying program behavior (e.g. extending the message passing mechanism to develop a trace log with a MOP)

  8. Reflection Extending Rotor’s Reflection • Runtime adaptiveness has been an important issue in .Net’s design • Introspection services of the System.Reflection namespace • Generative programming with the Reflection.Emit namespace • Dynamic inspection of the declarative information offered by attributes • Structural Reflection is a step forward to adaptiveness, permitting the modification of program’s structure at runtime • There are languages that offer this level of reflection: Python, Ruby, Dylan, Smalltalk or CLOS • Extending Rotor with structural reflection has • Made the CLI a platform to directly support reflective features of dynamic languages • Made the most of itsintrospective, attribute and generative programming features • Improved runtime performance of existing implementations, using its JIT compiler • Offered direct interoperability between X.Net and dynamic languages

  9. Contents • Introduction • Reflection • Structural Reflection in Rotor • Implementation • Assessment • Conclusions

  10. Structural Reflection in Rotor Structural Reflective Facilities • We have extended Rotor with the following summary of structural reflective capabilities • Fields Manipulation. Dynamic addition, deletion and updating of • The structure of classes (static and non-static fields) • The structure of a single object • Methods manipulation. Dynamic addition, deletion and updating of • Methods of classes (static and instance methods) • Methods of a specific object The implementation of new methods can be • obtained as copies of existing ones • dynamically generated by means of the System.Reflection.Emit namespace • The programmer may combine these facilities with .Net introspective features to create adaptive(able) software in an easier way

  11. Structural Reflection in Rotor Python Example # Modify attributes of # a single object point.z=3 printpoint.z# 3 # Modify methods of # a single object def draw3D(self): print"("+str(self.x)+ ","+str(self.y)+ ","+str(self.z)+")" point.draw3D=draw3D point.draw3D()# (1,2,3) # Modify methods of a class def getX(self): returnself.x Point.getX=getX printpoint.getX()# 1 class Point: "Constructor" def __init__(self, x, y): self.x=x self.y=y "Move Method" def move(self, relx, rely): self.x=self.x+relx self.y=self.y+rely "Draw Method" def draw(self): print"("+str(self.x)+ ","+str(self.y)+")" point=Point(1,2) point.draw() # (1,2)

  12. Structural Reflection in Rotor Conceptual Problems • There are conceptual issues to tackle when adding structural reflective capabilities to class-based object-oriented systems • Modifying classes structure  Schema evolution • Default values to new fields • Runtime exceptions to manage obsolete code • Modifying the structure of a single object  Schema versioning (new class for that object) • Class identity (different classes, same type) • Memory consumption • Class structure consistency (future modifications of “first” class should imply modifications of “second” class) … Imply a complex implementation of an incoherent computational model (e.g. MetaXa)

  13. Structural Reflection in Rotor Prototype-Based OO Comp. Model • The prototype-based object-oriented computational model (e.g. Self or Mootstrap) • Does not use classes (only objects) • Shared behavior could be defined in objects called trait objects • Common structure is defined with prototype objects • Object’s instantiation is performed by cloning prototypes Prototype-based model Point Class-based model Trait object Point x,y:Integer draw() move(x,y:Integer) inheritance p:Point x=245 y=-23 pointPrototype p Prototype object Prototype Cloning

  14. Modify attributes of a single object rotate method implementation • Modify methods of a single object • Modify behavior and structure of a class z 3 distance method Structural Reflection in Rotor Overcoming to Schema Evolution • Prototype-based OO model overcomes the schema versioning problem detected with classes • It is possible to modify the structure of a single object in a coherent way Point draw method implementation move method implementation p1 p2 x 0 y 0 x 1 y 2 x 12 y 0 pointPrototype

  15. Structural Reflection in Rotor Structural Reflection in Rotor • But, Rotor uses a class-based object-oriented computational model !!! • It is necessary to maintain classes because of • Existing (class-based) legacy code • Languages and applications interoperability • The programmer will continue using classes, but when using new structural reflective capabilities • Classes will be treated as trait objects (shared behavior and lazy schema evolution for fields) • Objects will be capable of grouping both attributes and methods (slots)  No schema versioning Internally we use a prototype-based reflective model (module object of rotor)

  16. Structural Reflection in Rotor Architecture Statically and Dynamically typed language Supporting both class-based and prototype-based OO models • Manipulation of methods: • Classes: Shared behavior (both models) • Objects: Specific behavior (mainly prototype-based model) • Manipulation of fields: • Classes: Lazy schema evolution (class-based model) • Objects: Specific instance modification (mainly prototype-based model) • “Static typing where possible, dynamic typing when needed” Statically typed language (legacy code) Dynamically typed language C# Reflective C# Python Compilation Interaction Interaction MSIL Execution ЯRotor Operating System

  17. Contents • Introduction • Reflection • Structural Reflection in Rotor • Implementation • Assessment • Conclusions

  18. Implementation BCL Interface • The final implementation consists of • A set of new BCL reflective primitives • The extension of appropriate IL instruction semantics (code generated by the JITter) • The BCL has been extended with a System.Reflection.Structural namespace • A summary of the most significant primitives (static methods of the Structural utility class) • [add,get,remove,alter,exist]Field: Modify (inspect) the field structure of classes and single objects • [add,get,remove,alter,exist]Method: work with both classes (Sytem.Type) and objects using method descriptions (MethodInfo) • Methods could be cloned from existing ones or dynamically generated with System.Reflection.Emit • invoke: executes a class or object method taking into account the prototype-based semantics (and inheritance) • [get,set]Value: statically-typed field access

  19. Implementation Sample Code Fragment (BCL) • A fragment of C# program that only uses the BCL interface of ЯRotor: RuntimeStructuralFieldInfo rsfi=new RuntimeStructuralFieldInfo( "z", typeof(int),3, FieldAttributes.Public); Structural.addField(point,rsfi); // field addition (object) // * Draw3D is the MethodInfo of a new method generated by // means of the System.Reflection.Emit namespace Structural.addMethod(point,draw3D); // method addition (object) Object[] pars={}; // method invocation (object method) Structural.invoke(point,draw3D.ReturnType, "draw3D",pars); // * getX is another MethodInfo Structural.addMethod(typeof(Point),getX); // add class method Console.WriteLine(Structural.invoke( point, getX.ReturnType, "getX", pars ); rsfi = new RuntimeStructuralFieldInfo( "isShowing", typeof(bool), false, FieldAttributes.Public); Structural.addField(typeof(Point), rsfi);// add class field

  20. Implementation Extension of IL Semantics • The new reflective model must be supported by the IL instructions, offering the benefits: • Making existing (legacy) .Net applications reflective • Programmers should make no distinction between static and dynamic (reflective) code • Applications needn’t to be recompiled to be adapted • We generate new native code, modifying the JIT compiler • This IL statements support dynamic type-checking • ldfld, ldsfld, ldflda: Load into the stack the field value (or address) following the prototype-based model • stfld, stsfld: Store a value into a field, deciding its memory location at runtime • call, callvirt: Execute methods following the prototype-based model

  21. Implementation Implementation Details • Inside of Rotor, both classes and objects are instances of the Object class (object.h) • These instances have fixed-size data • we couldn’t make objects variable size • We placed reflective information of each object inside their SyncBlock (syncblk.h) • Two hash tables were added to dynamically collect reflective members (methods and fields) • Reflective primitives manipulate this reflective information • New semantics of IL instructions was added modifying the JITter functions (fjit.cpp): compileCEE_{LDFLD,LDFLDA,STFLD,CALL,CALLVIRT} • The reflective information is manipulated at runtime by the runtime helper functions (fjitdef.h): JIT_{{Set,Get}Field{32,64,Obj},GetFieldAddr,GetStaticFieldAddr,Test{Method,VirtualMethod}} • The rest of the functionality was placed in the BCL

  22. Contents • Introduction • Reflection • Structural Reflection in Rotor • Implementation • Assessment • Conclusions

  23. Assessment Reflective Primitives Assessment • Three performance assessments • Reflective primitives • The cost of adaptiveness (no reflection) • Benefits of JIT compilation (vs. existing implementations) • We have evaluated the performance of the following reflective primitives • [add, delete][method, attribute] • invoke, accessField compared with • CPython 2.4. The most widely used interpreted implementation –developed in C • ActivePython 2.4 from ActiveState (C) • Jython 2.1. Compiles into 100% pure JVM code • IronPython 0.6. Generates CLR IL code • Reflective primitives have been measured using different scenarios (10,000 iterations each)

  24. Assessment Reflective Primitives Assessment • ЯRotor uses 23.18% average time (5.74times faster) to execute reflective primitivesin comparison with CPython • Notice that we do not support the whole Python programming language computational model 1200 40000 1000 20000 Jython 800 0 IronPython 600 ActivePython 1,2 Object attribute addition 3,4 Class attribute addition 5,6 Object attribute deletion 7,8 Class attribute deletion 9,10 Object attribute access 11,12 Class attribute access 13 Object method addition 14 Class method addition 15,16 Object method invocation 17 Class method invocation 18 Object method deletion 19 Class method deletion CPython 400 ЯRotor 200 0 1 3 5 7 9 11 13 15 17 19

  25. Assessment The cost of Adaptiveness • Static (non-reflective) operations should also be measuredagainst original Rotor • The current cost of flexibility has been measured with the Tommti benchmark that measures: {int,double,long} Arithmetic, trigonometric, input/output, array, exception handling, hash table(s), heap sort, vector, matrix, loops and string operations • A performance penalty was only detected in member accesses int arithmetic double arithmetic long arithmetic trigonometric io array exception hashmap hashmaps heapsort vector matrix loops StringBuilder 100% 80% Rotor 60% ЯRotor 40% 20% 0%

  26. Assessment The cost of Adaptiveness (II) • After many optimizations, we have measured (ЯRotor vs. Rotor) • the cost of static (non-reflective) primitives • Instance field access (ldfld): 0.6times slower • Instance method invocation (call): 0.6times slower • the execution of real C# application benchmarks • LCSCBench (LR parser): 0.81 times slower • AHCBench (Compression Algorithm): 2.14 times slower

  27. Assessment Benefits of JIT Compilation • What has been the performance benefit when executing non-reflective code? • We have compared C# Tommti benchmark executed on ЯRotorandCPython • Average runtime performance is 9.01 times faster • We do not support the whole Python computational model • Differences with maps, vectors and files: • in .Net, they belong to the BCL (performance overhead) • in Python, they are part of the language • In both Python and .Net, arrays (matrix) are part of the language int arith. double arith. long arith. trigonometric io array exception hashmap hashmaps heapsort vector matrix loops StringBuilder 100% 80% 60% CPython 40% ЯRotor 20% 0% Features included in the Python PL

  28. Contents • Introduction • Reflection • Structural Reflection in Rotor • Implementation • Assessment • Conclusions

  29. Conclusions Major Conclusions • JIT compilation is a suitable technique to optimize reflective primitives of dynamic languages • 9 times faster when executing non-reflective code • 5.74 times faster when executing reflective code • To make the CLI a platform to directly support reflection • Semantics of the abstract machine should support reflective primitives • Extra code generation produces performance overhead (e.g., Jython and IronPython) • Structural Reflection is properly represented by an internal prototype-based model plus a lazy schema evolution for classes • Both models could be supported (interaction) • Statically typed programs (legacy code) could be dynamically adapted • After many optimizations, static (non-reflective) member accesses performance cost has been reduced from 350% to 60% • Probably they can be reduced even more

  30. Extending Rotor with Structural Reflection to support Reflective Languages

More Related