14 research outputs found

    Garbage Collection and Efficiency in Dynamic Metacircular Runtimes

    Get PDF
    In dynamic object-oriented languages, low-level mechanisms such as just-in-time compilation, object allocation, garbage collection (GC) and method dispatch are often handled by virtual machines (VMs). VMs are typically implemented using static languages, allowing only few changes at run time. In such systems, the VM is not part of the language and interfaces to memory management or method dispatch are fixed, not allowing for arbitrary adaptation. Furthermore, the implementation can typically not be inspected or debugged with standard tools used to work on application code. This paper reports on our experience building Bee, a dynamic Smalltalk runtime, written in Smalltalk. Bee is a Dynamic Metacircular Runtime (DMR) and seamlessly integrates the VM into the application and thereby overcomes many restrictions of classic VMs, for instance by allowing arbitrary code modifications of the VM at run time. Furthermore, the approach enables developers to use their standard tools for application code also for the VM, allowing them to inspect, debug, understand, and modify a DMR seamlessly. We detail our experience of implementing GC, compilation, and optimizations in a DMR. We discuss examples where we found that DMRs can improve understanding of the system, provide tighter control of the software stack, and facilitate research. We also show that in high-level benchmarks the Bee DMR performance is close to that of a widely used Smalltalk VM

    Waterfall: Primitives Generation on the Fly

    No full text
    Modern languages are typically supported by managed runtimes (Virtual Machines). Since VMs have to deal with many concepts such as memory management, abstract execution model and scheduling, they tend to be very complex. Additionally, VMs have to meet strong performance requirements. This demand of performance is one of the main reasons why many VMs are built statically. Thus, design decisions are frozen at compile time preventing changes at runtime. One clear example is the impossibility to dynamically adapt or change primitives of the VM once it has been compiled. In this work we present a toolchain that allows for altering and configuring components such as primitives and plug-ins at runtime. The main contribution is Waterfall, a dynamic and reflective translator from Slang, a restricted subset of Smalltalk, to native code. Waterfall generates primitives on demand and executes them on the fly. We validate our approach by implementing dynamic primitive modification and runtime customization of VM plug-ins

    Remarkable Challenges of High-Performance Language Virtual Machines

    Get PDF
    Language Virtual Machines (VMs) are pervasive in every laptop, server, and smartphone, as is the case with Java or Javascript. They allow application portability between different platforms and better usage of resources. They are used in critical applications such as stock exchange, banking, insurance, and health [25]. Virtual machines are an important asset in companies because they allow the efficient execution of high-level programming languages. Nowadays, they even attract investments from large non-system companies, e.g., Netflix 1 , Meta 2 , Shopify 3 and Amazon 4. VMs achieve high-performance thanks to aggressive optimization techniques that observe and adapt the execution dynamically, either by doing just-in-time compilation [5] or by adapting the memory management strategies at runtime [90, 91]. For all these reasons Virtual Machines are highly-complex engineering pieces, often handcrafted by experts, that mix state-of-the-art compilation techniques with complex memory management that collaborate with the underlying operating systems and hardware. However, besides some well-known techniques that are published in research venues, most knowledge and technology around virtual machines are highly concentrated in large companies such as Microsoft, Google, and Oracle, making Virtual Machine construction difficult, and experiments difficult to reproduce and replicate. Language VMs present many multidisciplinary scientific challenges that appear at the intersection of fields such as hardware, system software, compiler, and software language engineering. This document aims to give a brief overview of the current challenges the VM community faces. To keep this document short, we selected remarkable challenges in managed execution, managed memory, performance evaluation, software engineering and security

    Bridging the Gap between Machine and Language using First-Class Building Blocks

    Get PDF
    High-performance virtual machines (VMs) are increasingly reused for programming languages for which they were not initially designed. Unfortunately, VMs are usually tailored to specific languages, offer only a very limited interface to running applications, and are closed to extensions. As a consequence, extensions required to support new languages often entail the construction of custom VMs, thus impacting reuse, compatibility and performance. Short of building a custom VM, the language designer has to choose between the expressiveness and the performance of the language. In this dissertation we argue that the best way to open the VM is to eliminate it. We present Pinocchio, a natively compiled Smalltalk, in which we identify and reify three basic building blocks for object-oriented languages. First we define a protocol for message passing similar to calling conventions, independent of the actual message lookup mechanism. The lookup is provided by a self-supporting runtime library written in Smalltalk and compiled to native code. Since it unifies the meta- and base-level we obtain a metaobject protocol (MOP). Then we decouple the language-level manipulation of state from the machine-level implementation by extending the structural reflective model of the language with object layouts, layout scopes and slots. Finally we reify behavior using AST nodes and first-class interpreters separate from the low-level language implementation. We describe the implementations of all three first-class building blocks. For each of the blocks we provide a series of examples illustrating how they enable typical extensions to the runtime, and we provide benchmarks validating the practicality of the approaches

    Bridging the Gap between Machine and Language using First-Class Building Blocks

    Get PDF
    High-performance virtual machines (VMs) are increasingly reused for programming languages for which they were not initially designed. Unfortunately, VMs are usually tailored to specific languages, offer only a very limited interface to running applications, and are closed to extensions. As a consequence, extensions required to support new languages often entail the construction of custom VMs, thus impacting reuse, compatibility and performance. Short of building a custom VM, the language designer has to choose between the expressiveness and the performance of the language. In this dissertation we argue that the best way to open the VM is to eliminate it. We present Pinocchio, a natively compiled Smalltalk, in which we identify and reify three basic building blocks for object-oriented languages. First we define a protocol for message passing similar to calling conventions, independent of the actual message lookup mechanism. The lookup is provided by a self-supporting runtime library written in Smalltalk and compiled to native code. Since it unifies the meta- and base-level we obtain a metaobject protocol (MOP). Then we decouple the language-level manipulation of state from the machine-level implementation by extending the structural reflective model of the language with object layouts, layout scopes and slots. Finally we reify behavior using AST nodes and first-class interpreters separate from the low-level language implementation. We describe the implementations of all three first-class building blocks. For each of the blocks we provide a series of examples illustrating how they enable typical extensions to the runtime, and we provide benchmarks validating the practicality of the approaches

    Towards Fully Reflective Environments

    Get PDF
    Modern development environments promote live programming (LP) mechanisms because it enhances the development experience by providing instantaneous feed- back 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

    Virtualisation pour Specialisation et Extension d'Environnements d'Execution

    Get PDF
    An application runtime is the set of software elements that represent an application during its execution. Application runtimes should be adaptable todifferent contexts. Advances in computing technology both in hardware and software indeed demand it. For example, on one hand we can think aboutextending a programming language to enhance the developers’ productivity.On the other hand we can also think about transparently reducing the memory footprint of applications to make them fit in constrained resourcescenarios e.g., low networks or limited memory availability. We propose Espell, a virtualization infrastructure for object-oriented high-level language runtimes. Espell provides a general purpose infrastructure to control and manipulate object-oriented runtimes in different situations. A first-class representation of an object-oriented runtime provides a high-level API for the manipulation of such runtime. A hypervisor uses this first-class object and manipulates it either directly or by executing arbitrary expressions into it. We show with our prototype that this infrastructure supports language bootstrapping and application runtime tailoring. Using bootstrapping we describe an object-oriented high-level language initialization in terms of itself. A bootstrapped language takes advantage of its own abstractions and is easier to extend. With application runtime tailoring we generate specialized applications by extracting the elements of a program that are used during execution. A tailored application encompasses only the classes and methods it needs and avoids the code bloat that appears from the usage of third-party libraries and frameworks.Un environnement d’exĂ©cution est l’ensemble des Ă©lĂ©ments logiciels qui reprĂ©sentent une application pendant son exĂ©cution. Les environnements d’exĂ©cution doivent ĂȘtre adaptables Ă  diffĂ©rents contextes. Les progrĂšs des technologies de l’information, tant au niveau logiciel qu’au niveau matĂ©riel, rendent ces adaptations nĂ©cessaires. Par exemple, nous pouvons envisager d’étendre un language de programmation pour amĂ©liorer la productivitĂ© des developpeurs. Aussi, nous pouvons envisager de rĂ©duire la consommation memoire des applications de maniĂšre transparente afin de les adapter Ă  certaines contraintes d’exĂ©cution e.g., des rĂ©seaux lents ou de la mĂ©moire limitĂ©s.Nous proposons Espell, une infrastructure pour la virtualisation d’environnement d’execution de langages orientĂ©-objets haut-niveau. Espell fournit une infrastructure gĂ©nĂ©raliste pour le contrĂŽle et la manipulation d’environnements d’exĂ©cution pour diffĂ©rentes situations. Une reprĂ©sentation de ’premier-ordre’ de l’environnement d’exĂ©cution orientĂ© objet fournit une interface haut-niveau qui permet la manipulation de ces environnements. Un hyperviseur est client de cette reprĂ©sentation de ’premier-ordre’ et le manipule soit directement, soit en y exĂ©cutant des expressions arbitraires. Nous montrons au travers de notre prototype que cet infrastructure supporte le bootstrapping (i.e., l’amorçage ou initialisation circulaire) des languages et le tailoring (i.e., la construction sur-mesure ou ’taille’) d’environnement d’exĂ©cution. En utilisant l’amorçage nous initialisons un language orientĂ©-objet haut-niveau qui est auto-dĂ©crit. Un langage amorcĂ© profite des ses propres abstractions se montrant donc plus simple Ă  Ă©tendre. La taille d’environnements d’exĂ©cution est une technique qui gĂ©nĂšre une application spĂ©cialisĂ© en extrayant seulement le code utilisĂ© pendant l’exĂ©cution d’un programme. Une application taillĂ©e inclut seulement les classes et mĂ©thodes qu’elle nĂ©cessite, et Ă©vite que des librairies et desframeworks externes surchargent inutilement la base de code

    An assembler and disassembler framework for Javaℱ programmers

    Get PDF
    AbstractThe Javaℱ programming language is primarily used for platform-independent programming. Yet it also offers many productivity, maintainability and performance benefits for platform-specific functions, such as the generation of machine code.We have created reliable assemblers for SPARCℱ , AMD64, IA32 and PowerPC which support all user mode and privileged instructions and with 64 bit mode support for all but the latter. These assemblers are generated as Java source code by our extensible assembler framework, which itself is written in the Java language. The assembler generator also produces javadoc comments that precisely specify the legal values for each operand.Our design is based on the Klein Assembler System written in Self. Assemblers are generated from a specification, as are table-driven disassemblers and unit tests. The specifications that drive the generators are expressed as Java language objects. Thus no extra parsers are needed and developers do not need to learn any new syntax to extend the framework for additional ISAs.Every generated assembler is tested against a preexisting assembler by comparing the output of both. Each instruction’s test cases are derived from the cross product of its potential operand values. The majority of tests are positive (i.e., result in a legal instruction encoding). The framework also generates negative tests, which are expected to cause an error detection by an assembler. As with the Klein Assembler System, we have found bugs in the external assemblers as well as in ISA reference manuals.Our framework generates tens of millions of tests. For symbolic operands, our tests include all applicable predefined constants. For integral operands, the important boundary values, such as the respective minimum, maximum, 0, 1 and −1, are tested. Full testing can take hours to run but gives us a high degree of confidence regarding correctness

    Heap Fuzzing: Automatic Garbage Collection Testing with Expert-Guided Random Events

    Get PDF
    International audienceProducing robust memory manager implementations is a challenging task. Defects in garbage collection algorithms produce subtle effects that are revealed later in program execution as memory corruptions. This problem is exacerbated by the fact that garbage collection algorithms deal with low-level implementation details to be efficient. Finding, reproducing, and debugging such bugs is complex and time-consuming. In this article, we propose to fuzz heaps by generating large sequences of random heap events guided by virtual machine experts. Randomly generated events exercise the garbage collection algorithm with the objective of crashing the virtual machine and finding bugs. Once a bug is found, we use a test case reduction algorithm to find the smaller subset of events that reproduces the issue. We implemented our approach on top of the virtual machine simulator of the Pharo Virtual Machine, to test its sequential stopthe-world generational scavenger. Experts guided our fuzzing toward the ephemeron finalization mechanism, corner allocation cases, and the heap compaction algorithm. Our prototype found 6 bugs: 3 in Pharo's ephemeron implementation which is not yet in production, 2 bugs in the default compactor which has been in production for 8 years, and 1 bug in the VM simulator used daily by VM developers. We show how such test cases were automatically reduced to trivial sequences that were easy to debug

    A pattern-based foundation for language-driven software engineering

    Get PDF
    This work brings together two fundamental ideas for modelling, programming and analysing software systems. The first idea is of a methodological nature: engineering software by systematically creating and relating languages. The second idea is of a technical nature: using patterns as a practical foundation for computing. The goal is to show that the systematic creation and layering of languages can be reduced to the elementary operations of pattern matching and instantiation and that this pattern-based approach provides a formal and practical foundation for language-driven modelling, programming and analysis. The underpinning of the work is a novel formalism for recognising, deconstructing, creating, searching, transforming and generally manipulating data structures. The formalism is based on typed sequences, a generic structure for representing trees. It defines basic pattern expressions for matching and instantiating atomic values and variables. Horizontal, vertical, diagonal and hierarchical operators are different ways of combining patterns. Transformations combine matching and instantiating patterns and they are patterns themselves. A quasiquotation mechanism allows arbitrary levels of meta-pattern functionality and forms the basis of pattern abstraction. Path polymorphic operators are used to specify fine-grained search of structures. A range of core concepts such as layering, parsing and pattern-based computing can naturally be defined through pattern expressions. Three language-driven tools that utilise the pattern formalism showcase the applicability of the pattern-approach. Concat is a self-sustaining (meta-)programming system in which all computations are expressed by matching and instantiation. This includes parsing, executing and optimising programs. By applying its language engineering tools to its own meta-language, Concat can extend itself from within. XMF (XML Modeling Framework) is a browser-based modelling- and meta-modelling framework that provides flexible means to create and relate modelling languages and to query and validate models. The pattern functionality that makes this possible is partly exposed as a schema language and partly as a JavaScript library. CFR (Channel Filter Rule Language) implements a language-driven approach for layered analysis of communication in complex networked systems. The communication on each layer is visible in the language of an “abstract protocol” that is defined by communication patterns.EThOS - Electronic Theses Online ServiceGBUnited Kingdo
    corecore