information is saved on a history stack, and Reverse, which runs back through a previous conservative execution and undoes its eect. We extend Forth's

Similar documents
Fachhochschule Wedel Technical Report Nr Implementing the Forth Inner Interpreter in High Level Forth

15-122: Principles of Imperative Computation, Fall 2015

Part 7. Stacks. Stack. Stack. Examples of Stacks. Stack Operation: Push. Piles of Data. The Stack

CMa simple C Abstract Machine

CA Compiler Construction

Precept 2: Non-preemptive Scheduler. COS 318: Fall 2018

Problem with Scanning an Infix Expression

Digital Forensics Lecture 3 - Reverse Engineering

Subprograms, Subroutines, and Functions

Threaded Language As a Form of Partial Evaluator

B.V. Patel Institute of Business Management, Computer & Information Technology, Uka Tarsadia University

CIS 1.5 Course Objectives. a. Understand the concept of a program (i.e., a computer following a series of instructions)

Principle of Complier Design Prof. Y. N. Srikant Department of Computer Science and Automation Indian Institute of Science, Bangalore

Computer Organization & Assembly Language Programming

register allocation saves energy register allocation reduces memory accesses.

AC59/AT59/AC110/AT110 OPERATING SYSTEMS & SYSTEMS SOFTWARE DEC 2015

point in worrying about performance. The goal of our work is to show that this is not true. This paper is organised as follows. In section 2 we introd

Programming Languages Third Edition. Chapter 7 Basic Semantics

Motivation was to facilitate development of systems software, especially OS development.

ER E P M S S I TRANSLATION OF CONDITIONAL COMPIL DEPARTMENT OF COMPUTER SCIENCE UNIVERSITY OF TAMPERE REPORT A

Compiler Construction D7011E

Runtime management. CS Compiler Design. The procedure abstraction. The procedure abstraction. Runtime management. V.

Utilizing Linux Kernel Components in K42 K42 Team modified October 2001

Function Calls COS 217. Reading: Chapter 4 of Programming From the Ground Up (available online from the course Web site)

LINUX OPERATING SYSTEM Submitted in partial fulfillment of the requirement for the award of degree of Bachelor of Technology in Computer Science

The York Abstract Machine

Chapter 7 Subroutines. Richard P. Paul, SPARC Architecture, Assembly Language Programming, and C

CS 406/534 Compiler Construction Putting It All Together

COMP 303 Computer Architecture Lecture 3. Comp 303 Computer Architecture

perform. If more storage is required, more can be added without having to modify the processor (provided that the extra memory is still addressable).

CS-201 Introduction to Programming with Java

A Unix process s address space appears to be three regions of memory: a read-only text region (containing executable code); a read-write region

UNIT IV -MACROPROCESSOR

AS-2883 B.Sc.(Hon s)(fifth Semester) Examination,2013 Computer Science (PCSC-503) (System Software) [Time Allowed: Three Hours] [Maximum Marks : 30]

regsim.scm ~/umb/cs450/ch5.base/ 1 11/11/13

Conditional Branching is not Necessary for Universal Computation in von Neumann Computers Raul Rojas (University of Halle Department of Mathematics an

Interrupt Driven Programming in MSP430 Assembly (ESCAPE) *

Figure 1: The evaluation window. ab a b \a.b (\.y)((\.)(\.)) Epressions with nested abstractions such as \.(\y.(\.w)) can be abbreviated as \y.w. v al

Programming and Data Structures Prof. N.S. Narayanaswamy Department of Computer Science and Engineering Indian Institute of Technology, Madras

Computer Science 2500 Computer Organization Rensselaer Polytechnic Institute Spring Topic Notes: MIPS Programming

Today's Topics. CISC 458 Winter J.R. Cordy

The Compositional C++ Language. Denition. Abstract. This document gives a concise denition of the syntax and semantics

! Those values must be stored somewhere! Therefore, variables must somehow be bound. ! How?

A taxonomy of race. D. P. Helmbold, C. E. McDowell. September 28, University of California, Santa Cruz. Santa Cruz, CA

Assembly Language Programming

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

Database Management System Prof. D. Janakiram Department of Computer Science & Engineering Indian Institute of Technology, Madras Lecture No.

What is a Compiler? Compiler Construction SMD163. Why Translation is Needed: Know your Target: Lecture 8: Introduction to code generation

CSE 230 Intermediate Programming in C and C++ Functions

Assembly Language: Function Calls

G Programming Languages - Fall 2012

reply db y prompt db Enter your favourite colour:, 0 colour db 80 dup(?) i db 20 k db? num dw 4000 large dd 50000

UNIT 4 Branch and Bound

by Marina Cholakyan, Hyduke Noshadi, Sepehr Sahba and Young Cha

Lecture 15 Garbage Collection

opt. front end produce an intermediate representation optimizer transforms the code in IR form into an back end transforms the code in IR form into

The role of semantic analysis in a compiler

C Programming SYLLABUS COVERAGE SYLLABUS IN DETAILS

Dual-Mode Garbage Collection. Patrick M Sansom. University of Glasgow, Glasgow, Scotland. December 1991.

CS401 - Computer Architecture and Assembly Language Programming Glossary By

Administration CS 412/413. Why build a compiler? Compilers. Architectural independence. Source-to-source translator

Checking System Rules Using System-Specific, Programmer- Written Compiler Extensions

Algorithmic "imperative" language

Operational Semantics

CS 167 Final Exam Solutions

GAS Tutorial - 7. Directives (2)

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

BEAWebLogic RFID. Enterprise Server. Using the Telemetry Console Extension

A simple correctness proof of the MCS contention-free lock. Theodore Johnson. Krishna Harathi. University of Florida. Abstract

Syntax Analysis, III Comp 412

CS536 Spring 2011 FINAL ID: Page 2 of 11

Computer Architecture Prof. Mainak Chaudhuri Department of Computer Science & Engineering Indian Institute of Technology, Kanpur

Induction and Semantics in Dafny

Machine Language Instructions Introduction. Instructions Words of a language understood by machine. Instruction set Vocabulary of the machine

Visual Profiler. User Guide

Motivation was to facilitate development of systems software, especially OS development.

Chapter 9 :: Subroutines and Control Abstraction

Analyzing File Content History

Code Generation. The Main Idea of Today s Lecture. We can emit stack-machine-style code for expressions via recursion. Lecture Outline.

Functions. Ray Seyfarth. August 4, Bit Intel Assembly Language c 2011 Ray Seyfarth

Chapter 14: Recovery System

We can emit stack-machine-style code for expressions via recursion

header of x code field body dovar code docol code header of foo code field code code body code field ;s code

Problem with Scanning an Infix Expression

Liveness Analysis and Register Allocation. Xiao Jia May 3 rd, 2013

1. Consider the following page reference string: 1, 2, 3, 4, 2, 1, 5, 6, 2, 1, 2, 3, 7, 6, 3, 2, 1, 2, 3, 6.

UNIT 3

Agenda. CSE P 501 Compilers. Java Implementation Overview. JVM Architecture. JVM Runtime Data Areas (1) JVM Data Types. CSE P 501 Su04 T-1

Implementing Subroutines. Outline [1]

UNIVERSITÄT PADERBORN. ComponentTools

Microprocessors and Microcontrollers Prof. Santanu Chattopadhyay Department of E & EC Engineering Indian Institute of Technology, Kharagpur

PROBLEM 1 : (Vocabulary: 8 points) For each of the words/phrases below, circle the denition that is the best description as it pertains in the context

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

CS 6353 Compiler Construction Project Assignments

Programming, numerics and optimization

2 Working with a Database

7. The Virtual Machine II: Flow Control 1

MOSS 7 - User Interface (Mac)

G52CPP Lab Exercise: Hangman Requirements (v1.0)

Parsing II Top-down parsing. Comp 412

Transcription:

A Virtual Machine Architecture for Constraint Based Programming Bill Stoddart October 25, 2000 Abstract We present a Forth style virtual machine architecture designed to provide for constriant based programming. We add?continue and CHOICE commands to allow forchecking constraints and making tentative choice. A choice which is later seen to be incompatible with a constraint provokes backtracking, which isimplemented by reversible execution of the virtual machine. keywords: Forth, Virtual Machines, Constraint Based Programming, Reversible Computation. 1 Introduction In Forth we can use an IF construct to choose which of two sequences of operations to execute. The choice made depends on the value of a ag taken from the stack, and the programmer has to arrange the value of this ag so that the program will make the correct choice. In some cases however, the information needed to make the right choice might not be readily available, and it might be useful to leave the program free to make a tentative choice \for itself" (so to speak), with the possibility of later revising this choice if it turns out to be inappropriate. We call this form of choice \non-deterministic". Consider how this technique could be used to provide predictive character input for a WAP phone, where each key represents up to three letters. To enter the word "love" we use the keys jkl, mno vwx def. When jkl is pressed at the start of a new word, the input routine makes a tentative choice of `j` as the character entered. This is perfectly feasible (for the moment) since there are dictionay entries that begin with 'j'. When the second key is pressed it tries `m` as the letter, then tests whether the dictionary contains any words that begin "jm". This choice is infeasible, since there are no such entries. The program backtracks and makes a dierent choice: "jn". Still infeasible. Another backtrack produces "jo" which is feasible. Carrying on in this way wemightarrive at "jove". Now the user must press a button to provoke further backtracking to obtain "love". The problems that can usefully be tackled with constraint based programming include timetabling, route planning and resource management. The backtracking technique we propose is based on reversible execution. We provide three modes of execution. Normal, Conservative, in which any lost

information is saved on a history stack, and Reverse, which runs back through a previous conservative execution and undoes its eect. We extend Forth's repertoire of basic commands with a new guarded continuation command?continue. In conservative mode it removes a value from the stack, and if this is non zero allows execution to continue. If the value is zero it reverses the direction of execution. This is used in conjunction with a new choice construct, which could have the form: CHOICE <word1> <word2>... <wordn> ENDCHOICE At run time the possible continuation addresses are pushed onto the history stack, and then the top address is selected for execution. If execution returns to this point inreverse, we choose another continuation and run forwards again. If there are no more continuation addresses we continue execution backwards to the previous CHOICE construct. If execution is returned to the beginning of the program the constraints imposed were such that no feasible execution path could be found. The whole program is infeasible, and results in a "ko" message rather than "ok". Execution becomes a search for a feasible path through the program. Tests that provide the ags used by the?continue commands in out program express the constraints a potential solution must satisfy. 2 Virtual Machine Architecture, Outline As a program runs, certain commands discard information whilst others conserve it. + loses information since we cannot recover the values of its arguments x and y (say) from its result. To run it in information conserving mode we must save one of the values, say y, on the history stack. Then, when we re-encounter the same instance of + when running in reverse mode we have x + y on the parameter stack andy on the history stack. To perform the reverse computation we copy y from the history stack (sothe parameter stack contains x + y and y) perform a subtraction (the stack now contains x) and nally move y from the history stack to the parameter stack. Each primitive compiled command of our virtual machine may invoke one of three fragments of machine code of the underlying physical machine, depending on the execution mode in which itisinvoked. These are normal forward mode, N, in which information is not conserved, conservation forward mode C which saves discarded information on the history stack, and reverse mode R which runs backward through the compiled virtual machine code reversing the eect of each command. 3 Execution Modes for Choice Choice There are three execution modes for choice: rst feasible, simultaneous and random. In rst feasible mode, we attempt to execute each choice in turn, consuming the corresponding continuation address on the history stack as we do so. If a choice proves to be infeasible we try another. If no choices are feasible, the whole choice construct is infeasible, and sets the virtual machine into reverse execution

mode so that it will backtrack to the previous non-deterministic choice. This provides a depth rst search for a feasible path through a computation. In simultaneous mode the computation is cloned into as many dopplegangers as there are choices. These run in parallel under a \termination pact". The rst to terminate execution survives. The others die, either committing suicide if their continuation proves infeasible, or killed by a signal from the terminating clone. This provides a breadth rst search for a feasible path through a computation. In random mode a pseudo-random number generator is used to select a choice, and a programmer may weight the probability of each choice. 4 Virtual Machine Implementation Details One requirement of our virtual machine is the ability to interpret the same sequence of virtual machine instructions in three dierent modes, and this prompted us to choose a modied form of \Indirect Threaded Code" which supports Normal, Conservative and Reverse modes of execution through the use of three \code elds" for each word. These point to the code for normal execution, conservative forward execution and backward execution of the operation. For each primitive denition, these three code elds contain pointers to sections of machine code that directly implement the normal, forward and reverse forms of the operation. Each of these sections of machine code has its own version of next, with the reverse code version causing execution to thread backwards through the threaded code. Forahighlevel denition the three code elds contain pointers to sections of machine code that nest into the denition. The reverse version of nest must commence execution of the high level denition from the point that denition previously exited. The conservative codefor EXIT will have left this address on the history stack when the denition last executed in a forward direction. When running backwards through a high level denition we reverse the eect of each virtual machine instruction until we reach the forward entry point of the denition, but what then? Running backwards into the denition's code eld pointers has no meaning. We need to insert an extra virtual machine instruction, which will perform a reverse exit from the denition and go back to the calling location. But where was this location? It can be found on what is generally called the \return stack", but which in the case of reverse execution is more appropriately thought of as the \came from" stack. Fig. 1 shows the threaded code organisation of the virtual machine. 4.1 Reversing Branch Instructions Fig. 2 illustrates the use of a forward branch instruction in the case of a \normal" threaded code machine (on the left) with our virtual machine version which supports reversible execution on the right. First consider forward execution of the normal code. After executing OP1 execution encounters a branch instruction. We assume this to be a conditional branch with some unspecied test on machine state deciding whether the branch will be taken. If taken, the branch is said to be \active", and execution continues at the location indicated by the

S Q U A R E Nmode nest code Cmode nest code Rmode nest code f r D U P code for N mode DUP E X I T code for C mode DUP N next * C next code for R mode DUP Rmode exit code Code for C mode exit: saves reverse entry point on the history stack Code for N mode exit R next Figure 1: Threaded Code Organisation for the Abstract Command Language Architecture OP1 branch destination OP2 OP3 OP1 branch destination departure OP2 arrival OP3 Figure 2: Normal (left) and Reversible Instruction Sequences Containing a Forward Branch.

a: b: c: d: e: f: g: OP1 arrival OP2 branch destination departure OP3 Figure 3: A Reversible Backward Branch destination eld of the branch that is with OP3. If the branch is not taken, OP2 is executed followed by OP3. Now consider an attempt at reverse execution of this code. There are basically two problems. Firstly, after reverse execution has undone the eect of OP3 it will move on to OP2. This is incorrect because we do not know that OP2 was ever executed. And secondly, after OP2, reverse execution will encounter the destination eld of the branch, and try to interpret this as an instruction. We deal with the rst problem by inserting at the destination point of all jumps an additional instruction called arrival. It works in conjunction with a \branch active" ag which forms part of the virtual machine state. This ag is set whenever a branch occurs, and reset by arrival. Its function is to tell arrival whether it received control by a local or remote arrival. For example if arrival in g. 2 is executed immediately after OP2 this constitutes a local arrival. When an active branch occurs, the executing branch instruction pushes the \from" address of the branch onto the history stack. 1 If the branch is inactive (execution of branch instruction but no branch) no history is recorded. Thus when arrival executes there are two possible conditions: either the branch active ag is set and the \from address" of the branch is on the history stack, or, the branch active ag is reset and there is no from address on the history stack. In the second case arrival saves the address of the previous instruction on the history stack, so that reverse execution of arrival can always nd its backwards continuation address on the history stack: The second problem has a simple solution. We insert a virtual machine instruction departure after the destination eld of any branch instruction. This allows reverse execution to step over this eld. The departure instruction is never executed in forward mode, as the branch instruction just steps over it. In g. 3we see these ideas applied to a backward branch. The letters a, b, c.. are used to label the locations of each virtual machine instruction so we can represent some forward and reverse traces. Consider an instance of execution in which the branch is rst active and then inactive, so that OP1, OP2, OP3 are performed in the sequence: 1 More specically it pushes the address of the last instruction executed before the branch, which is OP1 in this case.

OP1, OP2, OP2, OP3 Assuming an empty history stack at the start of execution, we have the following trace of forward execution in C mode, where x is the history recorded by OP1,y 1 and y 2 the histories recorded by the two executions of OP2, and z is the history recorded by OP3. Location Operation BA ag History Stack false hi a OP1 false x b arrive false x hai c OP2 false x hai y 1 d branch true x hai y 1 hci b arrive false x hai y 1 hci c OP2 false x hai y 1 hci y 2 d branch false x hai y 1 hci y 2 g OP3 false x hai y 1 hci y 2 z For the reverse trace the branch active ag is not needed. All jumps in the reverse execution sequence are handled bythereverse execution of arrival which nds its continuation location on the history stack: Location Operation History stack x hai y 1 hci y 2 z g: OP3 x hai y 1 hci y 2 f: depart x hai y 1 hci y 2 c: OP2 x hai y 1 hci b: arrival x hai y 1 c: OP2 x hai b: arrival x a: OP1 empty We nish our discussion of branch instructions with a note on normal (N mode) forward execution. The data in the branch destination eld compiled immediately following each branch instruction is interpreted slightly dierently in N mode and C mode. N mode branch execution jumps to the instruction following the instruction jumped to by C mode execution of the same instruction. This means arrival is never executed in N mode and the mechanism for reverse execution of branches imposes little or no run time penalty on N mode code. 4.2 The Multi-Tasker We have said that for the execution of certain constructs, execution must be cloned. The virtual machine provides multi-tasking with a classical Forth syle non-preemptive round robin scheduler. Creating a clone requires the allocation of memory for its state space, the copying of the existing state space into that of the clone, and linking the clone into the round robin as a task. Killing a task requires unlinking it from the round robin and de-allocating its memory space. Duplicating the compiled program code is not required as this is re-entrant.

5 Optimisation Ways of optimising reversible code are not discussed here, but are supported by some special virtual machine instructions. A simple example is where we have a sequnce of operations which use the stack to calculate a value, and then we store this value in a variable. To undo the eect of this we only need to restore the old value of the variable there is no point inreverse executing every instruction of the sequence. Possible solutions to such problems are left to the readers imagination. 6 Implementation Our implementation environment is Linux running on the i386 architecture, and our nucleus is coded in i386 gnu assembler. We have written a pre-processor which adds macros to this assembler. These deal with word headers, control structures and high level denitions. These macros together with the gnu assembler form a crude and limited meta compiler sucient to create the nucleus of a reversible Forth. 7 Other Work An extensive bibliography of work on reversible computing is available at: ftp://ftp.netcom.com/pub/hb/hbaker/reversegc.html In our own work we use an associated high level language, B-GSL,[1] which has a simple formal semantics which includes non-deterministic choice and backtracking. Direct use of a reversible Forth will let us explore problem solving techniques that are beyond the current scope of GSL and suggest directions for its extension. Acknowledgements Thanks to Andrew Haley of Cygnus Solutions, Cambridge, and Gordon Charlton of the Forth Interest Group for sharing their knowledge of reversible computation. References [1] Stoddart W J. An Execution Architecture for B-GSL. In Bowen J and Dunne S E, editors, ZB2000, Lecture Notes in Computer Science, 2000.