Runtime metaprogramming enables many useful applications and is often a convenient solution to solve problems in a generic way, which makes it widely used in frameworks, middleware, and domain-specific languages. However, powerful metaobject protocols are rarely supported and even common concepts such as reflective method invocation or dynamic proxies are not optimized. Solutions proposed in literature either restrict the metaprogramming capabilities or require application or library developers to apply performance improving techniques.
For overhead-free runtime metaprogramming, we demonstrate that dispatch chains, a generalized form of polymorphic inline caches common to self-optimizing interpreters, are a simple optimization at the language-implementation level. Our evaluation with self-optimizing interpreters shows that unrestricted metaobject protocols can be realized for the first time without runtime overhead, and that this optimization is applicable for just-in-time compilation of interpreters based on meta-tracing as well as partial evaluation. In this context, we also demonstrate that optimizing common reflective operations can lead to significant performance improvements for existing applications.
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and without Compromises (PLDI 2015)
1. Zero-Overhead Metaprogramming
Using Self-Optimizing Interpreters to Remove the
Runtime Cost of Reflective Programming
Stefan Marr, INRIA Lille
Research collaboration with Chris Seaton, Oracle Labs
and Stéphane Ducasse, INRIA Lille___
PLDI, June 17, 2015
3. Zero-Overhead Metaprogramming
Using Self-Optimizing Interpreters to Remove the
Runtime Cost of Reflective Programming
Stefan Marr, INRIA Lille
Research collaboration with Chris Seaton, Oracle Labs
and Stéphane Ducasse, INRIA Lille___
PLDI, June 17, 2015
4. Runtime Metaprogramming
4
class Proxy
def method_missing(name, *args, &block)
target.send(name, *args, &block)
end
end
obj.invoke('foo', [])
obj.getField(idx)
obj.setField(idx, val)
Powerful and Useful
Frameworks, Domain-Specific Languages, …
5. Metaobject Protocol Example
Building a Safe Actor Framework
class ActorDomain : Domain {
fn writeToField(obj, fieldIdx, value) {
if (Domain.current() == this) {
obj.setField(fieldIdx, value);
} else {
throw new IsolationError(obj);
}
}
/* ... */
}
5
http://stefan-marr.de/research/omop/
10. Optimize Direct Invocation
10
cnt + 1
Hölzle, Chambers, Ungar, ’91.
cnt.+(1)
is polymorphic
-> Cache at Send Site
Solution: Polymorphic Inline Cache
• Avoids lookup
• Enables JIT to
inline
11. Generalize Polymorphic Inline Caches
to Dispatch Chains
11
cnt 1
invocation
read var literal
+
dispatch chain
dispatch
method
cnt.+(1)
Common Place in Self-Optimizing Interpreters:
Würthinger et al. [2012], Humer et al. [2014], Wöß et al. [2014]
Chain Nodes can have
arbitrary behavior
12. Dispatch Chain for Method Invocation
12
Un
Init
cnt: 0 (Integer object)
+ int ++
check class==int
true
false
Un
Init
Cache
Node
cnt.+(1)
• Avoids lookup
• Enables inlining
int
19. Dispatch Chains to Resolve Variability
19
field write
UnIn
dispatch chain
on metaobject
CacheMObj.fieldA := ActorDomain.
writeToField()
Intercession
handler
20. Dispatch Chains to Resolve Variability
20
field write
UnIn
dispatch chain
on metaobject
CacheMObj.fieldA :=
Shortcut for standard semantics
ActorDomain.
writeToField()
Intercession
handler
StdDomain StdWrite
Standard
direct write
26. Open Research Questions
• Do programs with MOPs have classic trimodal
distribution of send-site polymorphism?
– i.e. does basic PIC hypothesis apply?
– Same polymorphism degree, inlining limits, …
• How to implement dispatch chains efficiently
in classic tier JIT compilers?
26
27. Dispatch Chains: A Generalization of PICs
• Complete removal of reflective overhead
–Simple and sufficient
–For meta-tracing and partial evaluation
• Enables
–Zero-Overhead Metaprogramming
–efficient MOPs for smarter DSLs
27
dispatch chain
dispatch
method
28. Runtime Metaprogramming
==
Just Another Form of Late Binding
Optimized as Such
28
+Truffle
http://stefan-marr.de/papers/pldi-marr-et-al-zero-overhead-metaprogramming/
Hinweis der Redaktion
- back????
- back????
- Perhaps change reference, other Kalibra?
-- UnIn not clear
-- whitespace
SOM: depending on the variant: only 2x to 3x slow than Java, and the benchmarks we optimized within 3% range
Use of runtime programming sneaks into all kind of places, including performance sensitive parts.
This here is a ruby library to process photoshop files, we chose a number of kernels that do layer composition to show that optimizing reflective operations gives major benefits.
This library is not artificial, it is widely used, and arguably, layer composition can be performance critical.
It has more than 500 forks on GitHub…