sub-method reflection

22
© Marcus Denker Sub-Method Reflection Marcus Denker Stéphane Ducasse Adrian Lienhard Philippe Marschall

Upload: marcus-denker

Post on 11-May-2015

662 views

Category:

Technology


0 download

DESCRIPTION

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.

TRANSCRIPT

Page 1: Sub-Method Reflection

© Marcus Denker

Sub-Method Reflection

Marcus DenkerStéphane DucasseAdrian LienhardPhilippe Marschall

Page 2: Sub-Method Reflection

© Marcus Denker

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

Page 3: Sub-Method Reflection

© Marcus Denker

Structural Reflection

> Structure modeled as objects

— e.g. Classes, methods— Causally connected

> Uses:— Development environments— Language extensions and experiments

Page 4: Sub-Method Reflection

© Marcus Denker

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

Page 5: Sub-Method Reflection

© Marcus Denker

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

Page 6: Sub-Method Reflection

© Marcus Denker

Existing Method Representations

> Existing representations for Methods

— Text

— Bytecode

— AST

Page 7: Sub-Method Reflection

© Marcus Denker

Requirements

> Causal Connection

> Abstraction Level

> Extensibility

> Persistency

> Size and Performance

Page 8: Sub-Method Reflection

© Marcus Denker

Text

> Low level abstraction— String of Characters

> Not causally connected— Need to call compiler

Page 9: Sub-Method Reflection

© Marcus Denker

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

Page 10: Sub-Method Reflection

© Marcus Denker

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

Page 11: Sub-Method Reflection

© Marcus Denker

Solution: Reflective Methods

> Annotated, persistent AST> Bytecode generated on demand and cached

:ReflectiveMethod

annotation

#(12 13 45 38 98 128 84 72 42 77 22 28 59

32 7 49 51 87 64)

:CompiledMethod

compiledMethod

reflectiveMethodannotation

Tools VM

Page 12: Sub-Method Reflection

© Marcus Denker

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

Page 13: Sub-Method Reflection

© Marcus Denker

Requirements revisited

> Abstraction Level OK

> Causal Connection OK

> Extensibility OK

> Persistency OK

> Size and Performance OK

Page 14: Sub-Method Reflection

© Marcus Denker

Reflective Methods: Annotations

> Source visible annotations— extended Smalltalk syntax

> Source invisible annotations— Reflective API— Can reference any object

> Every node can be annotated> Semantics: Compiler Plugins

(9 raisedTo: 10000) <:evaluateAtCompiletime:>

Page 15: Sub-Method Reflection

© Marcus Denker

Example I: Instrumentation

Original Code Instrumented Code

a := 1 max: 3 a := 1 max: 3.

AssignmentCounter inc.

> Goal: Code Instrumentation — Similar to Javassist, but at runtime— Insert code before/after, replace— Access to runtime data (e.g. receiver of send)

Page 16: Sub-Method Reflection

© Marcus Denker

Instrumentation using Annotations

after

#[10 125 55 33 55 00 80 90 33]

#[10 125 55 00 80 90]originalbytecode

instrumentedbytecode

ASTAnnotation

> On demand code generation— Faster!

> Better code— No preamble

code to access data on stack

> Annotations are metadata— Original code

untouched

Page 17: Sub-Method Reflection

© Marcus Denker

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

Page 18: Sub-Method Reflection

© Marcus Denker

Performance

Caching scheme Runtime

unmodified Squeak 6.9 seconds

Persephone, no cache >1 hour

Persephone, cache 6.9 seconds

Squeak tinyBenchmarks

Page 19: Sub-Method Reflection

© Marcus Denker

Memory

number of classes memory

Squeak 3.9 2040 15.7 MB

Persephoneno reflective methods

2224 20 MB

Persephonereflective methods

2224 123 MB

Page 20: Sub-Method Reflection

© Marcus Denker

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

Page 21: Sub-Method Reflection

© Marcus Denker

Conclusion

> Motivated the need for Reflective Methods> Implementation: Persephone> Examples

— Instrumentation framework— Pluggable type-system

> Benchmarks / Memory

Page 22: Sub-Method Reflection

© Marcus Denker

Conclusion

> Motivated the need for Reflective Methods> Implementation: Persephone> Examples

— Instrumentation framework— Pluggable type-system

> Benchmarks / Memory

Questions?