Virtual Machines and Interpretation Techniques 2

Virtual Machines and Interpretation Techniques 2

Virtual Machines Virtual machines (VMs) provide an intermediate stage for Virtual Machines and the compilation of programming languages Interpretation Techniques • VMs are machines because they permit a step-by-step execution of programs • VMs are virtual (abstract ) because typically they – are not implemented in hardware Kostis Sagonas – omit many details of real (hardware) machines [email protected] • VMs are tailored to the particular operations required to implement a particular (class of) source language(s) Virtual Machines and Interpretation Techniques 2 Virtual Machines: Pros Virtual Machines: Cons • Bridge the gap between the high level of a programming language • Inferior performance of VM interpreters compared and the low level of a real machine. with a native code compiler for the same language • Require less implementation effort – Overhead of interpretation • Easier to experiment and modify (crucial for new PLs) – Significantly more difficult to take advantage of modern hardware features (e.g. hardware-based branch prediction) • Portability is enhanced – VM interpreters are typically implemented in C – VM code can be transferred over the net and run in most machines – VM code is (often significantly) smaller than object code • Easier to be formally proven correct • Various safety features of VM code can be verified • Profiling and debugging are easier to implement Virtual Machines and Interpretation Techniques 3 Virtual Machines and Interpretation Techniques 4 Some History of VM Development VM Design Choices • VMs have been built and studied since the late 1950’s • Some design choices are similar to the choices when designing • The first Lisp implementations (1958) used virtual machines with the intermediate code format of a compiler: garbage collection, sandboxing, reflection, and an interactive – Should the machine be used on several different physical architectures and operating systems? (JVM) shell – Should the machine be used for several different source languages? • Forth (early 70’s) used a very small and easy to implement VM (CLI/CLR (.NET)) with high level of reflection • Some other design choices are similar to those of the compiler • Smalltalk (late 70’s) allowed changing code on the fly (first truly backend: – Is performance more important than portability? interactive OO system) – Is reliability more important than performance? • USCD Pascal (late 70’s) popularized the idea of using pseudocode – Is (smaller) code size more important than performance? to improve portability • And some design choices are similar to those in an OS: • Self (late 80’s), a language with a Smalltalk flavor, had an – How to implement memory management, concurrency, exceptions, I/O, … implementation that pushed the limits of VM – Is low memory consumption, scalability, or security more important • Java (early 90s) made VMs popular and well known than performance? Virtual Machines and Interpretation Techniques 5 Virtual Machines and Interpretation Techniques 6 1 VM Components VM Implementation • The components of a VM vary depending on several • Virtual machines are usually written in “portable” factors: programming languages such as C or C++. – Is the language (environment) interactive? – Does the language support reflection and or dynamic loading? • For performance critical components, assembly – Is performance paramount? language is often used. – Is concurrency support required? – Is sandboxing required? • VMs for some languages (Lisp, Forth, Smalltalk) are largely written in the language itself. • Many VMs are written specifically for GNU CC, for reasons that will become apparent in later slides. (In this lecture we will only talk about the interpreter of the VM.) Virtual Machines and Interpretation Techniques 7 Virtual Machines and Interpretation Techniques 8 Forms of Interpreters Implementation of Interpreters • Programming language implementations often use two There are various ways to implement interpreters: distinct kinds of interpreters: 1. Direct string interpretation – Command-line interpreter • Reads and parses language constructs in source form Source level interpreters are very slow because they spend much of their time in doing lexical analysis • Used in interactive systems – Virtual machine instruction interpreter 2. Compilation into a (typically abstract syntax) tree and • Reads and executes instructions in some intermediate form such as VM bytecode interpretation of that tree Such interpreters avoid lexical analysis costs, but they still have to do much list scanning ( e.g. when implementing a ‘goto’ or ‘call’) 3. Compilation into a virtual machine and interpretation of the VM code Virtual Machines and Interpretation Techniques 9 Virtual Machines and Interpretation Techniques 10 Virtual Machine Instruction Interpreters Components of Virtual Machine Implementations • By compiling the program to the instruction set of a • Program store (code area) virtual machine and adding a table that maps names – Program is a sequence of instructions – Loader and labels to addresses in this program, some of the interpretation overhead can be reduced • State (of execution) – Stack • For convenience, most VM instruction sets use – Heap integral numbers of bytes to represent everything – Registers – opcodes, register numbers, stack slot numbers, indices into • Special register ( program counter ) pointing to the next the function or constant table, etc. instruction to be executed • Runtime system component Opcode Reg # CONSTANT – Memory allocator Example: The GET_CONST2 instruction – Garbage collector Virtual Machines and Interpretation Techniques 11 Virtual Machines and Interpretation Techniques 12 2 Basic Structure of a Bytecode Interpreter To align or to not align VM instructions? byte * pc = &byte_program[0]; On a 32-bit machine while (TRUE) { opcode = pc [0]; switch (opcode) { Opcode … case GET_CONST2 : Jump Address source_reg_num = pc [1]; const_num_to_match = get_2_bytes(& pc [2]); … // get_const2 code pc += 4; break ; Opcode … case JUMP : Unused Bytes Jump Address jump_addr = get_4_bytes(& pc [1]); pc = &byte_program[jump_addr]; break ; NOTE: Padding of instructions can be done by the loader. … } The size of the bytecode files need not be affected. } Virtual Machines and Interpretation Techniques 13 Virtual Machines and Interpretation Techniques 14 Bytecode Interpreter with Aligned Instructions Interpreter with Abstracted Instruction Encoding byte * pc = &byte_program[0]; byte * pc = &byte_program[0]; while (TRUE) { while (TRUE) { #define GET_CONST2_SIZEOF 4 #define JUMP_SIZEOF 8 opcode = pc [0]; opcode = pc [0]; #define #define GET_CONST2_ARG1 1 switch (opcode) { switch (opcode) { #define GET_CONST2_ARG2 2 … … #define JUMP_ARG1 4 case GET_CONST2 : case GET_CONST2 : source_reg_num = pc [1]; source_reg_num = pc [GET_CONST2_ARG1 ]; const_num_to_match = get_2_bytes(& pc [2]); const_num_to_match = get_2_bytes(& pc [GET_CONST2_ARG2 ]); … // get_const2 code … // get_const2 code pc += 4; pc += GET_CONST2_SIZEOF ; break ; break ; … … case JUMP : // aligned version case JUMP : // aligned version jump_addr = get_4_bytes(& pc [4]); jump_addr = get_4_bytes(& pc [JUMP_ARG1 ]); pc = &byte_program[jump_addr]; pc = &byte_program[jump_addr]; break ; break ; … … } } } } Virtual Machines and Interpretation Techniques 15 Virtual Machines and Interpretation Techniques 16 Interpreter with Abstracted Control Indirectly Threaded Interpreters byte * pc = &byte_program[0]; • In an indirectly threaded interpreter we do not switch on the while (TRUE) { #define NEXT_INSTRUCTION \ next_instruction: goto next_instruction opcode encoding. Instead we use the bytecodes as indices into a opcode = pc [0]; table containing the addresses of the VM instruction switch (opcode) { … implementations case GET_CONST2 : source_reg_num = pc [GET_CONST2_ARG1 ]; • The term threaded code refers to a code representation where const_num_to_match = get_2_bytes(& pc [GET_CONST2_ARG2 ]); every instruction is implicitly a function call to the next … // get_const2 code pc += GET_CONST2_SIZEOF ; instruction NEXT_INSTRUCTION ; • A threaded interpreter can be very efficiently implemented in … case JUMP : // aligned version assembly jump_addr = get_4_bytes(& pc [JUMP_ARG1 ]); pc = &byte_program[jump_addr]; • In GNU CC, we can use the labels as values C language extension NEXT_INSTRUCTION ; and take the address of a label with &&labelname … } • We can actually write the interpreter in such a way that it uses } indirectly threaded code if compiled with GNU CC and a switch for compatibility Virtual Machines and Interpretation Techniques 17 Virtual Machines and Interpretation Techniques 18 3 Structure of Indirectly Threaded Interpreter Directly Threaded Interpreter byte * pc = &byte_program[0]; static void ***label_tab[] * {{{ while (TRUE) { … • In a directly threaded interpreter, we do not use the &&get_const2_label; next_instruction: … opcode = pc [0]; &&jump_label; bytecode instruction encoding at all during runtime switch (opcode) { … … }}} #define NEXT_INSTRUCTION \ • Instead, the loader replaces each bytecode case GET_CONST2 : #define goto **(void **)**)(label_tab[****pc ]) get_const2_label: instruction encoding (opcode) with the address of the source_reg_num = pc [GET_CONST2_ARG1 ]; const_num_to_match = get_2_bytes(& pc [GET_CONST2_ARG2 ]); implementation of the instruction … // get_const2 code pc += GET_CONST2_SIZEOF ; • This means that we need one word for the opcode, NEXT_INSTRUCTION ; … which slightly increases the VM code size case JUMP : // aligned version jump_label:

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    5 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us