Tag Archives: Metaobject Protocol

Open PostDoc Position on Programming Technology for Complex Concurrent Systems

We, or more specifically our colleagues from the Software Languages Lab in Brussels are looking for a post-doctoral researcher to work on a collaborative research project with us.

Head over to their page for the details.

For a bit more context on the position, have a look at the recently posted preprint titled “Towards Meta-Level Engineering and Tooling for Complex Concurrent Systems“. This position paper outlines some of the research challenges we want to work on.

Towards Meta-Level Engineering and Tooling for Complex Concurrent Systems

Last December, we got a research project proposal accepted for a collaboration between the Software Languages Lab in Brussels and the Institute for System Software here in Linz. Together, we will be working on tooling for complex concurrent systems. And with that I mean systems that use multiple concurrency models in combination to solve different problems, each with the appropriate abstraction. I have been working on these issues already for a while. Some pointers are available here in an earlier post: Why Is Concurrent Programming Hard? And What Can We Do about It?

End of February, I am going to talk about that a little more at the Arbeitstagung Programmiersprachen in Vienna. Below, you can find an abstract and link to the position paper. There is not a lot of concrete material in yet, but it sketches the problems we will try to address in the years to come.

Abstract

With the widespread use of multicore processors, software becomes more and more diverse in its use of parallel computing resources. To address all application requirements, each with the appropriate abstraction, developers mix and match various concurrency abstractions made available to them via libraries and frameworks. Unfortunately, today’s tools such as debuggers and profilers do not support the diversity of these abstractions. Instead of enabling developers to reason about the high-level programming concepts, they used to express their programs, the tools work only on the library’s implementation level. While this is a common problem also for other libraries and frameworks, the complexity of concurrency exacerbates the issue further, and reasoning on the higher levels of the concurrency abstractions is essential to manage the associated complexity.

In this position paper, we identify open research issues and propose to build tools based on a common meta-level interface to enable developers to reasons about their programs based on the high-level concepts they used to implement them.

  • Towards Meta-Level Engineering and Tooling for Complex Concurrent Systems; Stefan Marr, Elisa Gonzalez Boix, Hanspeter Mössenböck; in ‘Proceedings of the 9th Arbeitstagung Programmiersprachen’ (ATPS’ 16).
  • Paper: PDF, HTML
  • BibTex: BibSonomy

JIT Data Structures, Fully Reflective VMs, and Meta-Circular Meta-Tracing

The year leading up to SPLASH has been pretty busy. Beside my own talks on Tracing vs. Partial Evaluation and Optimizing Communicating Event-Loop Languages with Truffle, there are going to be three other presentations on work I was involved in.

Just-In-Time Data Structures

On Thursday, Mattias De Wael is going to present his work on Just-in-Time Data Structures at Onward!. For me this work is exciting, because I hope that this could make programming with standard data structures quite a bit simpler in the long run. Today, ‘scripting’ languages like Ruby and Python provide a small set of very versatile data structures they call lists or arrays that can be used for many many different use cases. But instead of having a one-size-fits-all implementation, a runtime system can ideally identify a specific ‘strategy’ to be used dynamically, and even change it over the course of a program. So, in a nice language, we would merely declare a few fundamental properties such as being ordered, and how to compare items, and the runtime system will figure out whether to use a hash, tree, array, or other kind of implementation. Well, that’s at least my vision. Abstract below:

Today, software engineering practices focus on finding the single right data representation (i.e., data structure) for a program. The right data representation, however, might not exist: relying on a single representation of the data for the lifetime of the program can be suboptimal in terms of performance. We explore the idea of developing data structures for which changing the data representation is an intrinsic property. To this end we introduce Just-in-Time Data Structures, which enable representation changes at runtime, based on declarative input from a performance expert programmer. Just-in-Time Data Structures are an attempt to shift the focus from finding the “right’’ data structure to finding the right sequence of data representations. We present JitDS-Java, an extension to the Java language, to develop Just-in-Time Data Structures. Further, we show two example programs that benefit from changing the representation at runtime.

  • Just-In-Time Data Structures. Mattias De Wael, Stefan Marr, Joeri De Koster, Jennifer B. Sartor, and Wolfgang De Meuter. Proceedings of the 2015 ACM International Symposium on New Ideas, New Paradigms, and Reflections on Programming & Software, ACM, (October 2015)

Towards Fully Reflective Environments

On Friday, Guido Chari is going to present his work Towards Fully Reflective Environments also at Onward!. This is a first step in the direction of bringing all parts of a runtime system to life. While classic systems such as Smalltalk and CLOS go pretty far in reifying language elements and enabling us to interact with them on a meta-level, they typically exclude important aspects of the runtime system such as GC, object representation, interpreter semantics, and JIT compilation. Some of these aspects can be observed via debugging interfaces, but what we have in mind here is to have a complete meta-circular runtime system where each and every aspect is reified and can be adapted at runtime. What Guido is going to present is only a first step, especially since performance is not yet addressed. But, we are working on it.

Modern development environments promote live programming (LP) mechanisms because it enhances the development experience by providing instantaneous feedback and interaction with live objects. LP is typically supported with advanced reflective techniques within dynamic languages. These languages run on top of Virtual Machines (VMs) that are built in a static manner so that most of their components are bound at compile time. As a consequence, VM developers are forced to work using the traditional edit-compile-run cycle, even when they are designing LP-supporting environments. In this paper we explore the idea of bringing LP techniques to the VM domain for improving their observability, evolution and adaptability at run-time. We define the notion of fully reflective execution environments (EEs), systems that provide reflection not only at the application level but also at the level of the VM. We characterize such systems, propose a design, and present Mate v1, a prototypical implementation. Based on our prototype, we analyze the feasibility and applicability of incorporating reflective capabilities into different parts of EEs. Furthermore, the evaluation demonstrates the opportunities such reflective capabilities provide for unanticipated dynamic adaptation scenarios, benefiting thus, a wider range of users.

  • Towards Fully Reflective Environments. Guido Chari, Diego Garbervetsky, Stefan Marr, and Stéphane Ducasse. Proceedings of the 2015 ACM International Symposium on New Ideas, New Paradigms, and Reflections on Programming & Software, ACM, (October 2015)

A Formal Foundation for Trace-Based JIT Compilers

Last but not least, and already on Monday at the WODA workshop, Maarten Vandercammmen is going to present A Formal Foundation for Trace-Based JIT Compilers. The bit that I find most interesting in that work is the meta-circular meta-tracer for a little Scheme, which is hiding in there. The focus of the work changed over time, but initially he was working on identifying the essence of meta-tracing. And he now got a pretty small and manageable framework to experiment with meta-tracing, and even execute multiple levels of interpreters that are all traced through. I’d say that’s a pretty neat foundation for future research, more approachable than a huge practical system such as RPython, but of course, also not without drawbacks. For instance, a proper optimizer is missing so far. But let’s see where this gets us in the future!

Trace-based JIT compilers identify frequently executed program paths at run-time and subsequently record, compile and optimize their execution. In order to improve the performance of the generated machine instructions, JIT compilers heavily rely on dynamic analysis of the code. Existing work treats the components of a JIT compiler as a monolithic whole, tied to particular execution semantics. We propose a formal framework that facilitates the design and implementation of a tracing JIT compiler and its accompanying dynamic analyses by decoupling the tracing, optimization, and interpretation processes. This results in a framework that is more configurable and extensible than existing formal tracing models. We formalize the tracer and interpreter as two abstract state machines that communicate through a minimal, well-defined interface. Developing a tracing JIT compiler becomes possible for arbitrary interpreters that implement this interface. The abstract machines also provide the necessary hooks to plug in custom analyses and optimizations.

  • A Formal Foundation for Trace-Based JIT Compilers Maarten Vandercammen, Jens Nicolay, Stefan Marr, Joeri De Koster, Theo D’Hondt, and Coen De Roover. Proceedings of the 13th International Workshop on Dynamic Analysis. Pittsburgh, PA, USA, ACM, (October 2015)

Zero-Overhead Metaprogramming

Runtime metaprogramming and reflection are slow. That’s a common wisdom. Unfortunately. Using refection for instance with Java’s reflection API, its dynamic proxies, Ruby’s #send or #method_missing, PHP’s magic methods such as __call, Python’s __getattr__, C#’s DynamicObjects, or really any metaprogramming abstraction in modern languages unfortunately comes at a price. The fewest language implementations optimize these operations. For instance, on Java’s HotSpot VM, reflective method invocation and dynamic proxies have an overhead of 6-7x compared to direct operations.

But, does it have to be that way? No it doesn’t!

And actually, a solution is rather simple. In a paper that Chris Seaton, Stéphane Ducasse, and I worked on, and which recently got accepted for presentation at the PLDI conference, we show that a simple generalization of polymorphic inline caches can be used to optimize metaprogramming so that it doesn’t have any performance cost after just-in-time compilation.

You might wonder, why do we care? Since it is slow, people don’t use it in performance sensitive code, right? Well, as it turns out, in Ruby it is used everywhere, because it is convenient and allows for straightforward and general solutions. So, making metaprogramming fast will benefit many applications. But that’s not all. For my own research on concurrency, I proposed the ownership-based metaobject protocol (OMOP) as a foundation for implementing a wide range of different concurrent programming abstractions. Unfortunately, such metaobject protocols have been inherently difficult to optimize. But instead of finding a solution, researchers gave up on it and instead focused on designing aspect-oriented programming languages, which sidestep the performance issues by applying only to a minimal set of program points instead of pervasively throughout the whole program. For my use case, that wasn’t good enough. However, now, by generalizing polymorphic inline caches, we solved the performance issues of metaobject protocols as well.

The abstract of the paper and the PDF/HTML versions, as well as the artifact with all experiments are linked below.

Abstract

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.

  • Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and without Compromises; Stefan Marr, Chris Seaton, Stéphane Ducasse; in ‘Proceedings of the 36th ACM SIGPLAN Conference on Programming Language Design and Implementation’ (PLDI’ 15).
  • Paper: PDF, HTML
  • BibTex: BibSonomy
  • DOI: 10.1145/2737924.2737963
  • Online Appendix: artifacts and experimental setup

Slides

Supporting Concurrency Abstractions in High-level Language Virtual Machines

Last Friday, I defended my PhD dissertation. Finally, after 4 years and a bit, I am done. Finally. I am very grateful to all the people supporting me along the way and of course to my colleagues for their help.

My work focused on how to build VMs with support for all kind of different concurrent programming abstractions. Since you don’t want to put them into a VM just one by one, I was looking for a unifying substrate that’s up to the task. Below, you’ll find the abstract as well as the slides.

In addition to the thesis text itself, the implementations and tools are available. Please see the project page for more details.

Abstract

During the past decade, software developers widely adopted JVM and CLI as multi-language virtual machines (VMs). At the same time, the multicore revolution burdened developers with increasing complexity. Language implementers devised a wide range of concurrent and parallel programming concepts to address this complexity but struggle to build these concepts on top of common multi-language VMs. Missing support in these VMs leads to tradeoffs between implementation simplicity, correctly implemented language semantics, and performance guarantees.

Departing from the traditional distinction between concurrency and parallelism, this dissertation finds that parallel programming concepts benefit from performance-related VM support, while concurrent programming concepts benefit from VM support that guarantees correct semantics in the presence of reflection, mutable state, and interaction with other languages and libraries.

Focusing on these concurrent programming concepts, this dissertation finds that a VM needs to provide mechanisms for managed state, managed execution, ownership, and controlled enforcement. Based on these requirements, this dissertation proposes an ownership-based metaobject protocol (OMOP) to build novel multi-language VMs with proper concurrent programming support.

This dissertation demonstrates the OMOP’s benefits by building concurrent programming concepts such as agents, software transactional memory, actors, active objects, and communicating sequential processes on top of the OMOP. The performance evaluation shows that OMOP-based implementations of concurrent programming concepts can reach performance on par with that of their conventionally implemented counterparts if the OMOP is supported by the VM.

To conclude, the OMOP proposed in this dissertation provides a unifying and minimal substrate to support concurrent programming on top of multi-language VMs. The OMOP enables language implementers to correctly implement language semantics, while simultaneously enabling VMs to provide efficient implementations.

  • Supporting Concurrency Abstractions in High-level Language Virtual Machines, Stefan Marr. Software Languages Lab, Vrije Universiteit Brussel, Pleinlaan 2, B-1050 Brussels, Belgium, PhD Dissertation, January 2013. ISBN 978-90-5718-256-3.
  • Download: PDF.
  • BibTex: BibSonomy

Slides