Sub-Method Reflection

831 views

Published on

Reflection has proved to be a powerful feature to support the design of development environments and to extend languages. However, the granularity of structural reflection stops at the method level. This is a problem since without sub-method reflection developers have to duplicate efforts, for example to introduce transparently pluggable type-checkers or fine-grained profilers. In this paper we present Persephone, an efficient implementation of a sub-method meta-object protocol (MOP) based on AST annotations and dual methods (a compiled method and its meta-object) that reconcile AST expressiveness with bytecode execution. We validate the MOP by presenting TreeNurse, a method instrumentation framework and TypePlug, an optional, pluggable type system which is based on Persephone.

Published in: Technology, Health & Medicine
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
831
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Sub-Method Reflection

  1. 1. Sub-Method Reflection Marcus Denker Stéphane Ducasse Adrian Lienhard Philippe Marschall © Marcus Denker
  2. 2. Roadmap > Structural Reflection and Sub-Method Reflection > Persephone: Sub-Method Reflection for Smalltalk > Example I: Instrumentation Framework > Example II: Pluggable Type-System > Benchmarks + Memory > Future Work © Marcus Denker
  3. 3. Structural Reflection > Structure modeled as objects — e.g. Classes, methods — Causally connected > Uses: — Development environments — Language extensions and experiments © Marcus Denker
  4. 4. Methods and Reflection > Method are Objects — e.g in Smalltalk > No high-level model for sub-method elements — Message sends — Assignments — Variable access > Structural reflection stops at the granularity of methods © Marcus Denker
  5. 5. Sub-Method Reflection > Many tools work on sub method level — Profiler, Refactoring Tool, Debugger, Type Checker > Communication between tools needed — example: Code coverage > All tools use different representations — Tools are harder to build — Communication not possible © Marcus Denker
  6. 6. Existing Method Representations > Existing representations for Methods — Text — Bytecode — AST © Marcus Denker
  7. 7. Requirements > Causal Connection > Abstraction Level > Extensibility > Persistency > Size and Performance © Marcus Denker
  8. 8. Text > Low level abstraction — String of Characters > Not causally connected — Need to call compiler © Marcus Denker
  9. 9. Bytecode > Low level abstraction — Array of Integers > Missing extensibility — e.g. for tools > Mix of base- and meta-level code — Problems with synthesized code when changing code — Examples: AOP point-cut residues, reflection hooks © Marcus Denker
  10. 10. Abstract Syntax Tree > Not causally connected — Need to call compiler > Not extensible — Fixed set of codes, no way to store meta data > Not persistent — Generated by compiler from text, never stored © Marcus Denker
  11. 11. Solution: Reflective Methods > Annotated, persistent AST > Bytecode generated on demand and cached :ReflectiveMethod :CompiledMethod annotation compiledMethod #(12 13 45 38 98 128 annotation reflectiveMethod 84 72 42 77 22 28 59 32 7 49 51 87 64) Tools VM © Marcus Denker
  12. 12. Persephone > Implementation of Reflective Methods for Squeak Smalltalk > Smalltalk Compiler generates Reflective Methods — Translated to Bytecode on demand > Open Compiler: Plugins — Called before code generation — Transform a copy of the AST © Marcus Denker
  13. 13. Requirements revisited > Abstraction Level OK > Causal Connection OK > Extensibility OK > Persistency OK > Size and Performance OK © Marcus Denker
  14. 14. Reflective Methods: Annotations > Source visible annotations — extended Smalltalk syntax (9 raisedTo: 10000) <:evaluateAtCompiletime:> > Source invisible annotations — Reflective API — Can reference any object > Every node can be annotated > Semantics: Compiler Plugins © Marcus Denker
  15. 15. Example I: Instrumentation > Goal: Code Instrumentation — Similar to Javassist, but at runtime — Insert code before/after, replace — Access to runtime data (e.g. receiver of send) a := 1 max: 3 a := 1 max: 3. AssignmentCounter inc. Original Code Instrumented Code © Marcus Denker
  16. 16. Instrumentation using Annotations > On demand code generation Annotation — Faster! AST after > Better code — No preamble code to access original data on stack #[10 125 55 00 80 90] bytecode > Annotations are instrumented #[10 125 55 33 55 00 80 90 33] metadata bytecode — Original code untouched © Marcus Denker
  17. 17. Example II: Pluggable Type-System > Example for textual annotations bitFromBoolean: aBoolean <:type: Boolean :> ^ (aBoolean ifTrue: [1] ifFalse: [0]) <:type: Integer :> > Optional, pluggable type-system > Types stored as annotations in the Reflective Methods © Marcus Denker
  18. 18. Performance Squeak tinyBenchmarks Caching scheme Runtime unmodified Squeak 6.9 seconds Persephone, no cache >1 hour Persephone, cache 6.9 seconds © Marcus Denker
  19. 19. Memory number of classes memory Squeak 3.9 2040 15.7 MB Persephone 2224 20 MB no reflective methods Persephone 2224 123 MB reflective methods © Marcus Denker
  20. 20. Future Work > Optimize Size of AST Representation — Simpler AST — AST Compression > Behavioral Reflection — Implement Reflex model of partial behavioral reflection > Beyond Text — Store only AST (no text) — Build text from annotated AST © Marcus Denker
  21. 21. Conclusion > Motivated the need for Reflective Methods > Implementation: Persephone > Examples — Instrumentation framework — Pluggable type-system > Benchmarks / Memory © Marcus Denker
  22. 22. Conclusion > Motivated the need for Reflective Methods > Implementation: Persephone > Examples — Instrumentation framework — Pluggable type-system > Benchmarks / Memory Questions? © Marcus Denker

×