changeset 3607:de066dcbf607

Added Python scripts in new 'shell' project. The shell/commands.py script should replace all the existing run*.sh scripts in the top level Graal directory and is where new commands should go.
author Doug Simon <doug.simon@oracle.com>
date Mon, 31 Oct 2011 21:06:04 +0100
parents f2fd47582524
children 5a1a05d3a30b
files pytools/.project pytools/.pydevproject pytools/commands.py pytools/gl.py
diffstat 4 files changed, 433 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pytools/.project	Mon Oct 31 21:06:04 2011 +0100
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>shell</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pytools/.pydevproject	Mon Oct 31 21:06:04 2011 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?>
+
+<pydev_project>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/shell</path>
+</pydev_pathproperty>
+
+</pydev_project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pytools/commands.py	Mon Oct 31 21:06:04 2011 +0100
@@ -0,0 +1,184 @@
+#
+# commands.py - the default commands available to gl.py
+#
+# ----------------------------------------------------------------------------------------------------
+#
+# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+# ----------------------------------------------------------------------------------------------------
+
+import os
+from os.path import join, exists
+from collections import Callable
+
+def clean(env, args):
+    """cleans the Graal+HotSpot source tree"""
+    os.environ.update(ARCH_DATA_MODEL='64', LANG='C', HOTSPOT_BUILD_JOBS='16')
+    env.run(['gmake', 'clean'], cwd=join(env.graal_home, 'make'))
+
+def bootstrap(env, args):
+    return env.run_vm(args + ['-version'])
+
+def avrora(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '20', 'avrora'])
+
+def batik(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '20', 'batik'])
+
+def eclipse(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '20', 'eclipse'])
+
+def fop(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '100', 'fop'])
+
+def h2(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '10', 'h2'])
+
+def jython(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '10', 'jython'])
+
+def lusearch(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '5', 'lusearch'])
+
+def pmd(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '10', 'pmd'])
+
+def tradebeans(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '20', 'tradebeans'])
+
+def xalan(env, args):
+    return env.run_dacapo(args + ['Harness', '--preserve', '-n', '20', 'xalan'])
+
+def tests(env, args):
+    """run a selection of the Maxine JTT tests in Graal"""
+    
+    def jtt(name):
+        return join(env.maxine_home, 'com.oracle.max.vm', 'test', 'jtt', name)
+    
+    return env.run_vm(args + ['-ea', '-esa', '-Xcomp', '-XX:+PrintCompilation', '-XX:CompileOnly=jtt'] + args +
+                       ['-Xbootclasspath/p:' + join(env.maxine_home, 'com.oracle.max.vm', 'bin'), 
+                        '-Xbootclasspath/p:' + join(env.maxine_home, 'com.oracle.max.base', 'bin'),
+                        'test.com.sun.max.vm.compiler.JavaTester',
+                        '-verbose=1', '-gen-run-scheme=false', '-run-scheme-package=all',
+                        jtt('bytecode'),
+                        jtt('except'), 
+                        jtt('jdk'), 
+                        jtt('hotpath'), 
+                        jtt('jdk'), 
+                        jtt('lang'), 
+                        jtt('loop'), 
+                        jtt('micro'), 
+                        jtt('optimize'), 
+                        jtt('reflect'), 
+                        jtt('threads'), 
+                        jtt('hotspot')])
+
+def help_(env, args):
+    """show help for a given command
+
+With no arguments, print a list of commands and short help for each command.
+
+Given a command name, print help for that command."""
+    if len(args) == 0:
+        env.print_help()
+        return
+    
+    name = args[0]
+    if not table.has_key(name):
+        env.error('unknown command: ' + name)
+    
+    value = table[name]
+    (func, usage) = value[:2]
+    doc = func.__doc__
+    if len(value) > 2:
+        docArgs = value[2:]
+        fmtArgs = []
+        for d in docArgs:
+            if isinstance(d, Callable):
+                fmtArgs += [d(env)]
+            else:
+                fmtArgs += [str(d)]
+        doc = doc.format(*fmtArgs)
+    print 'gl {0} {1}\n\n{2}\n'.format(name, usage, doc)
+
+def make(env, args):
+    """builds the Graal+HotSpot binary"""
+
+    
+    jvmCfg = join(env.jdk7, 'jre', 'lib', 'amd64', 'jvm.cfg')
+    found = False
+    with open(jvmCfg) as f:
+        for line in f:
+            if '-graal KNOWN' in line:
+                found = True
+                break
+            
+    if not found:
+        env.log('Appending "-graal KNOWN" to ' + jvmCfg)
+        with open(jvmCfg, 'a') as f:
+            f.write('-graal KNOWN\n')
+
+    if env.get_os() != 'windows':
+        javaLink = join(env.graal_home, 'graal', 'hotspot', 'java')
+        if not exists(javaLink):
+            javaExe = join(env.jdk7, 'jre', 'bin', 'java')
+            env.log('Creating link: ' + javaLink + ' -> ' + javaExe)
+            os.symlink(javaExe, javaLink)
+
+    graalVmDir = join(env.jdk7, 'jre', 'lib', 'amd64', 'graal')
+    if not exists(graalVmDir):
+        env.log('Creating Graal directory in JDK7: ' + graalVmDir)
+        os.makedirs(graalVmDir)
+
+    graalVmDbgDir = join(env.jdk7g, 'jre', 'lib', 'amd64', 'graal')
+    if not exists(graalVmDbgDir):
+        env.log('Creating Graal directory in JDK7G: ' + graalVmDbgDir)
+        os.makedirs(graalVmDbgDir)
+
+
+    os.environ.update(ARCH_DATA_MODEL='64', LANG='C', HOTSPOT_BUILD_JOBS='4', ALT_BOOTDIR=env.jdk7g, INSTALL='y')
+    env.run(['gmake', 'jvmggraal'], cwd=join(env.graal_home, 'make'))
+
+    os.environ.update(ARCH_DATA_MODEL='64', LANG='C', HOTSPOT_BUILD_JOBS='4', ALT_BOOTDIR=env.jdk7, INSTALL='y')
+    env.run(['gmake', 'productgraal'], cwd=join(env.graal_home, 'make'))
+    
+# Table of commands in alphabetical order.
+# Keys are command names, value are lists: [<function>, <usage msg>, <format args to doc string of function>...]
+# If any of the format args are instances of Callable, then they are called with an 'env' are before being
+# used in the call to str.format().  
+# Extensions should update this table directly
+table = {
+    'avrora': [avrora, ''],
+    'batik': [batik, ''],
+    'bootstrap': [bootstrap, ''],
+    'clean': [clean, ''],
+    'fop': [fop, ''],
+    'h2': [h2, ''],
+    'jython': [jython, ''],
+    'lusearch': [lusearch, ''],
+    'pmd': [pmd, ''],
+    'tradebeans': [tradebeans, ''],
+    'tests': [tests, ''],
+    'help': [help_, '[command]'],
+    'make': [make, ''],
+    'xalan': [xalan, ''],
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pytools/gl.py	Mon Oct 31 21:06:04 2011 +0100
@@ -0,0 +1,221 @@
+#!/usr/bin/python
+#
+# gl.py - shell interface for Graal source code
+#
+# ----------------------------------------------------------------------------------------------------
+#
+# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+# ----------------------------------------------------------------------------------------------------
+#
+# A launcher for Graal executables and tools.
+#
+
+import subprocess
+from threading import Thread
+from argparse import ArgumentParser, REMAINDER
+from os.path import join, dirname, abspath, exists, isfile, isdir
+import commands
+import types
+import sys
+import os
+
+class Env(ArgumentParser):
+
+    # Override parent to append the list of available commands
+    def format_help(self):
+        msg = ArgumentParser.format_help(self) + '\navailable commands:\n\n'
+        for cmd in sorted(commands.table.iterkeys()):
+            c, _ = commands.table[cmd][:2]
+            doc = c.__doc__
+            if doc is None:
+                doc = ''
+            msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0])
+        return msg + '\n'
+    
+    def __init__(self):
+        self.dacapo = os.getenv('DACAPO')
+        self.jdk7 = os.getenv('JDK7')
+        self.jdk7g = os.getenv('JDK7G')
+        self.maxine_home = os.getenv('MAXINE')
+        
+        ArgumentParser.__init__(self, prog='gl')
+    
+        self.add_argument('-v', action='store_true', dest='verbose', help='enable verbose output')
+        self.add_argument('--dacapo', help='path to DaCapo 91.12 jar file')
+        self.add_argument('--jdk7', help='JDK7 installation in which the GraalVM binary is installed', metavar='<path>')
+        self.add_argument('--jdk7g', help='JDK7G installation in which the GraalVM binary is installed', metavar='<path>')
+        self.add_argument('-M', '--maxine', dest='maxine_home', help='path to Maxine code base', metavar='<path>')
+        
+    def parse_cmd_line(self):
+        
+        self.add_argument('commandAndArgs', nargs=REMAINDER, metavar='command args...')
+        
+        self.parse_args(namespace=self)
+
+        if not isdir(self.jdk7):
+            self.log('JDK7 is required. Use --jdk7 option or set JDK7 environment variable')
+            self.abort(1)
+
+        if not isdir(self.jdk7g):
+            self.log('JDK7G is required. Use --jdk7g option or set JDK7G environment variable')
+            self.abort(1)
+
+        self.graal_home = dirname(abspath(dirname(sys.argv[0])))
+    
+    def load_config_file(self, configFile):
+        """ adds attributes to this object from a file containing key=value lines """
+        if exists(configFile):
+            with open(configFile) as f:
+                self.log('[loading vars from ' + configFile + ']')
+                for line in f:
+                    kv = line.split('=', 1)
+                    if len(kv) == 2:
+                        k = kv[0].strip().lower()
+                        setattr(self, k, os.path.expandvars(kv[1].strip()))
+
+    def get_os(self):
+        if sys.platform.startswith('darwin'):
+            return 'darwin'
+        elif sys.platform.startswith('linux'):
+            return 'linux'
+        elif sys.platform.startswith('sunos'):
+            return 'solaris'
+        elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
+            return 'windows'
+        else:
+            print 'Supported operating system could not be derived from', sys.platform
+            self.abort(1)
+
+        
+    def exe(self, name):
+        if self.get_os() == 'windows':
+            return name + '.exe'
+        return name
+
+    def run_dacapo(self, args):
+        if not isfile(self.dacapo) or not self.dacapo.endswith('.jar'):
+            self.log('Specified DaCapo jar file does not exist or is not a jar file: ' + self.dacapo)
+            self.abort(1)
+        return self.run_vm(['-Xms1g', '-Xmx2g', '-esa', '-XX:-GraalBailoutIsFatal', '-G:-QuietBailout', '-cp', self.dacapo] + args)
+
+    def run_vm(self, args):
+        if self.maxine_home is None:
+            self.log('Path to Maxine code base must be specified with -M option of MAXINE environment variable')
+            self.abort(1)
+        if not exists(join(self.maxine_home, 'com.oracle.max.graal.hotspot', 'bin', 'com', 'oracle', 'max', 'graal', 'hotspot', 'VMEntriesNative.class')):
+            self.log('Maxine code base path specified -M option or MAXINE environment variable does not contain com.oracle.max.graal.hotspot/bin/com/oracle/max/graal/hotspot/VMEntriesNative.class: ' + self.maxine_home)
+            self.abort(1)
+            
+        os.environ['MAXINE'] = self.maxine_home
+        exe = join(self.jdk7, 'bin', self.exe('java'))
+        return self.run([exe, '-graal'] + args)
+
+    def run(self, args, nonZeroIsFatal=True, out=None, err=None, cwd=None):
+        """
+        
+        Run a command in a subprocess, wait for it to complete and return the exit status of the process.
+        If the exit status is non-zero and `nonZeroIsFatal` is true, then the program is exited with
+        the same exit status.
+        Each line of the standard output and error streams of the subprocess are redirected to the
+        provided out and err functions if they are not None.
+        
+        """
+        
+        assert isinstance(args, types.ListType), "'args' must be a list: " + str(args)
+        for arg in args:
+            if not isinstance(arg, types.StringTypes):
+                self.log('argument is not a string: ' + str(arg))
+                self.abort(1)
+        
+        if self.verbose:
+            self.log(' '.join(args))
+            
+        try:
+            if out is None and err is None:
+                retcode = subprocess.call(args, cwd=cwd)
+            else:
+                def redirect(stream, f):
+                    for line in iter(stream.readline, ''):
+                        f(line)
+                    stream.close()
+                p = subprocess.Popen(args, stdout=None if out is None else subprocess.PIPE, stderr=None if err is None else subprocess.PIPE)
+                if out is not None:
+                    t = Thread(target=redirect, args=(p.stdout, out))
+                    t.daemon = True # thread dies with the program
+                    t.start()
+                if err is not None:
+                    t = Thread(target=redirect, args=(p.stderr, err))
+                    t.daemon = True # thread dies with the program
+                    t.start()
+                retcode = p.wait()
+        except OSError as e:
+            self.log('Error executing \'' + ' '.join(args) + '\': ' + str(e))
+            if self.verbose:
+                raise e
+            self.abort(e.errno)
+        
+
+        if retcode and nonZeroIsFatal:
+            if self.verbose:
+                raise subprocess.CalledProcessError(retcode, ' '.join(args))
+            self.abort(retcode)
+            
+        return retcode
+
+    
+    def log(self, msg=None):
+        if msg is None:
+            print
+        else:
+            print msg
+           
+    def abort(self, code):
+        """ raises a SystemExit exception with the provided exit code """
+        raise SystemExit(code)
+
+def main(env):
+    configFile = join(dirname(sys.argv[0]), 'glrc')
+    env.load_config_file(configFile)
+    env.parse_cmd_line()
+    
+    if len(env.commandAndArgs) == 0:
+        env.print_help()
+        return
+    
+    env.command = env.commandAndArgs[0]
+    env.command_args = env.commandAndArgs[1:]
+    
+    if not commands.table.has_key(env.command):
+        env.error('unknown command "' + env.command + '"')
+        
+    c, _ = commands.table[env.command][:2]
+    try:
+        retcode = c(env, env.command_args)
+        if retcode is not None and retcode != 0:
+            env.abort(retcode)
+    except KeyboardInterrupt:
+        env.abort(1)
+        
+#This idiom means the below code only runs when executed from command line
+if __name__ == '__main__':
+    main(Env())