changeset 11297:dc4cedf73358

Merge.
author Doug Simon <doug.simon@oracle.com>
date Tue, 13 Aug 2013 14:25:02 +0200
parents 4e943a311d9c (diff) fcff54e1253e (current diff)
children 16dedd5911ea
files
diffstat 2 files changed, 161 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/mx/commands.py	Tue Aug 13 13:26:58 2013 +0200
+++ b/mx/commands.py	Tue Aug 13 14:25:02 2013 +0200
@@ -39,18 +39,28 @@
 """ Used to distinguish an exported GraalVM (see 'mx export'). """
 _vmSourcesAvailable = exists(join(_graal_home, 'make')) and exists(join(_graal_home, 'src'))
 
-""" The VMs that can be built and run - default is first in list """
-_vmChoices = ['graal', 'server', 'client', 'server-nograal', 'client-nograal', 'original']
+""" The VMs that can be built and run along with an optional description. Only VMs with a
+    description are listed in the dialogue for setting the default VM (see _get_vm()). """
+_vmChoices = {
+    'graal' : 'All compilation is performed with Graal. This includes bootstrapping Graal itself unless -XX:-BootstrapGraal is used.',
+    'server' : 'Normal compilation is performed with the tiered system (i.e., client + server), Truffle compilation is performed with Graal. Use this for optimal Truffle performance.',
+    'client' : None, # normal compilation with client compiler, explicit compilation (e.g., by Truffle) with Graal
+    'server-nograal' : None, # all compilation with tiered system (i.e., client + server), Graal omitted
+    'client-nograal' : None, # all compilation with client compiler, Graal omitted
+    'original' : None, # default VM copied from bootstrap JDK
+}
 
 """ The VM that will be run by the 'vm' command and built by default by the 'build' command.
-    This can be set via the global '--vm' option. """
-_vm = _vmChoices[0]
+    This can be set via the global '--vm' option or the DEFAULT_VM environment variable.
+    It can also be temporarily set by using of a VM context manager object in a 'with' statement. """
+_vm = None
 
 """ The VM builds that will be run by the 'vm' command - default is first in list """
 _vmbuildChoices = ['product', 'fastdebug', 'debug', 'optimized']
 
 """ The VM build that will be run by the 'vm' command.
-    This can be set via the global '--product', '--fastdebug' and '--debug' options. """
+    This can be set via the global '--product', '--fastdebug' and '--debug' options.
+    It can also be temporarily set by using of a VM context manager object in a 'with' statement. """
 _vmbuild = _vmbuildChoices[0]
 
 _jacoco = 'off'
@@ -65,6 +75,55 @@
 
 _minVersion = mx.JavaVersion('1.7.0_04')
 
+def _get_vm():
+    """
+    Gets the configured VM, presenting a dialogue if there is no currently configured VM.
+    """
+    global _vm
+    if _vm:
+        return _vm
+    vm = mx.get_env('DEFAULT_VM')
+    if vm is None:
+        if not sys.stdout.isatty():
+            mx.abort('Need to specify VM with --vm option or DEFAULT_VM environment variable')
+        envPath = join(_graal_home, 'mx', 'env')
+        mx.log('Please select the VM to be executed from the following: ')
+        items = [k for k in _vmChoices.keys() if _vmChoices[k] is not None]
+        descriptions = [_vmChoices[k] for k in _vmChoices.keys() if _vmChoices[k] is not None]
+        vm = mx.select_items(items, descriptions, allowMultiple=False)
+        answer = raw_input('Persist this choice by adding "DEFAULT_VM=' + vm + '" to ' + envPath + '? [Yn]: ')
+        if not answer.lower().startswith('n'):
+            with open(envPath, 'a') as fp:
+                print >> fp, 'DEFAULT_VM=' + vm
+    _vm = vm
+    return vm
+
+""" 
+A context manager that can be used with the 'with' statement to set the VM
+used by all VM executions within the scope of the 'with' statement. For example:
+
+    with VM('server'):
+        dacapo(['pmd'])
+"""
+class VM:
+    def __init__(self, vm=None, build=None):
+        assert vm is None or vm in _vmChoices.keys()
+        assert build is None or build in _vmbuildChoices
+        self.vm = vm if vm else _vm
+        self.build = build if build else _vmbuild
+        self.previousVm = _vm
+        self.previousBuild = _vmbuild
+        
+    def __enter__(self):
+        global _vm, _vmbuild
+        _vm = self.vm
+        _vmbuild = self.build
+        
+    def __exit__(self, exc_type, exc_value, traceback):
+        global _vm, _vmbuild
+        _vm = self.previousVm
+        _vmbuild = self.previousBuild
+    
 def _chmodDir(chmodFlags, dirname, fnames):
     os.chmod(dirname, chmodFlags)
     for name in fnames:
@@ -172,7 +231,7 @@
 
     # The remainder are VM options
     vmOpts = [arg for arg in args if not arg.startswith('@')]
-    vm = _vm
+    vm = _get_vm()
 
     failed = []
     for (test, n) in numTests.items():
@@ -223,7 +282,7 @@
 
     # The remainder are VM options
     vmOpts = [arg for arg in args if not arg.startswith('@')]
-    vm = _vm;
+    vm = _get_vm()
 
     failed = []
     for (test, n) in numTests.items():
@@ -271,6 +330,15 @@
 def _jdksDir():
     return os.path.abspath(join(_vmdir if _vmdir else _graal_home, 'jdk' + str(mx.java().version)))
 
+def _handle_missing_VM(bld, vm):
+    mx.log('The ' + bld + ' ' + vm + ' VM has not been created')
+    if sys.stdout.isatty():
+        answer = raw_input('Build it now? [Yn]: ')
+        if not answer.lower().startswith('n'):
+            build([bld], vm=vm)
+            return
+    mx.abort('You need to run "mx --vm ' + vm + ' build ' + bld + '" to build the selected VM')
+
 def _jdk(build='product', vmToCheck=None, create=False, installGraalJar=True):
     """
     Get the JDK into which Graal is installed, creating it first if necessary.
@@ -330,8 +398,7 @@
                 pass
     else:
         if not exists(jdk):
-            vmOption = ' --vm ' + vmToCheck if vmToCheck else ''
-            mx.abort('The ' + build + ' VM has not been created - run "mx' + vmOption + ' build ' + build + '"')
+            _handle_missing_VM(build, vmToCheck if vmToCheck else 'graal')
             
     if installGraalJar:
         _installGraalJarInJdks(mx.distribution('GRAAL'))
@@ -345,7 +412,7 @@
                     found = True
                     break
         if not found:
-            mx.abort('The ' + build + ' ' + vmToCheck + ' VM has not been created - run "mx --vm ' + vmToCheck + ' build ' + build + '"')
+            _handle_missing_VM(build, vmToCheck)
         
     return jdk
 
@@ -483,7 +550,7 @@
         builds = ['product']
 
     if vm is None:
-        vm = _vm
+        vm = _get_vm()
 
     if vm == 'original':
         pass
@@ -649,7 +716,7 @@
     """run the VM selected by the '--vm' option"""
 
     if vm is None:
-        vm = _vm
+        vm = _get_vm()
 
     if cwd is None:
         cwd = _workdir
@@ -759,7 +826,7 @@
     def harness(projectscp, vmArgs):
         if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource):
             subprocess.check_call([mx.java().javac, '-cp', projectscp, '-d', mxdir, javaSource])
-        if not isGraalEnabled(_vm):
+        if not isGraalEnabled(_get_vm()):
             prefixArgs = ['-esa', '-ea']
         else:
             prefixArgs = ['-XX:-BootstrapGraal', '-esa', '-ea']
@@ -824,7 +891,7 @@
 def buildvms(args):
     """build one or more VMs in various configurations"""
 
-    vmsDefault = ','.join(_vmChoices)
+    vmsDefault = ','.join(_vmChoices.keys())
     vmbuildsDefault = ','.join(_vmbuildChoices)
     
     parser = ArgumentParser(prog='mx buildvms');
@@ -852,9 +919,8 @@
                 duration = datetime.timedelta(seconds=time.time() - start)
                 mx.log('END:   ' + v + '-' + vmbuild + '\t[' + str(duration) + ']')
             else:
-                global _vm
-                _vm = v
-                build([vmbuild])
+                with VM(v):
+                    build([vmbuild])
             if not args.no_check:
                 vmargs = ['-version']
                 if v == 'graal':
@@ -896,8 +962,6 @@
 
     args = parser.parse_args(args)
 
-    global _vmbuild
-    global _vm
     global _jacoco
     
     tasks = []
@@ -952,37 +1016,35 @@
         buildvms(['--vms', 'graal,server', '--builds', 'fastdebug,product'])
         tasks.append(t.stop())
 
-        _vmbuild = 'fastdebug'
-        t = Task('BootstrapWithSystemAssertions:fastdebug')
-        vm(['-esa', '-version'])
-        tasks.append(t.stop())
+        with VM('graal', 'fastdebug'):
+            t = Task('BootstrapWithSystemAssertions:fastdebug')
+            vm(['-esa', '-version'])
+            tasks.append(t.stop())
 
-        _vmbuild = 'product'
-        t = Task('BootstrapWithGCVerification:product')
-        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'])
-        tasks.append(t.stop())
+        with VM('graal', 'product'):
+            t = Task('BootstrapWithGCVerification:product')
+            vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'])
+            tasks.append(t.stop())
     
-        _vmbuild = 'product'
-        t = Task('BootstrapWithG1GCVerification:product')
-        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC','-XX:+UseG1GC','-XX:+UseNewCode','-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'])
-        tasks.append(t.stop())
+        with VM('graal', 'product'):
+            t = Task('BootstrapWithG1GCVerification:product')
+            vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC','-XX:+UseG1GC','-XX:+UseNewCode','-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'])
+            tasks.append(t.stop())
 
-        _vmbuild = 'product'
-        t = Task('BootstrapWithRegisterPressure:product')
-        vm(['-G:RegisterPressure=rbx,r11,r10,r14,xmm3,xmm11,xmm14', '-esa', '-version'])
-        tasks.append(t.stop())
+        with VM('graal', 'product'):
+            t = Task('BootstrapWithRegisterPressure:product')
+            vm(['-G:RegisterPressure=rbx,r11,r10,r14,xmm3,xmm11,xmm14', '-esa', '-version'])
+            tasks.append(t.stop())
 
-        _vmbuild = 'product'
-        t = Task('BootstrapWithAOTConfiguration:product')
-        vm(['-G:+AOTCompilation', '-G:+VerifyPhases', '-esa', '-version'])
-        tasks.append(t.stop())
+        with VM('graal', 'product'):
+            t = Task('BootstrapWithAOTConfiguration:product')
+            vm(['-G:+AOTCompilation', '-G:+VerifyPhases', '-esa', '-version'])
+            tasks.append(t.stop())
 
-        originalVm = _vm
-        _vm = 'server' # hosted mode
-        t = Task('UnitTests:hosted-product')
-        unittest([])
-        tasks.append(t.stop())
-        _vm = originalVm
+        with VM('server', 'product'): # hosted mode
+            t = Task('UnitTests:hosted-product')
+            unittest([])
+            tasks.append(t.stop())
 
         for vmbuild in ['fastdebug', 'product']:
             for test in sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Gate, gateBuildLevel=vmbuild):
@@ -1009,17 +1071,15 @@
             tasks.append(t.stop())
 
             for vmbuild in ['product', 'fastdebug']:
-                _vmbuild = vmbuild
                 for theVm in ['client', 'server']:
-                    _vm = theVm
-
-                    t = Task('DaCapo_pmd:' + theVm + ':' + vmbuild)
-                    dacapo(['pmd'])
-                    tasks.append(t.stop())
-
-                    t = Task('UnitTests:' + theVm + ':' + vmbuild)
-                    unittest(['@-XX:CompileCommand=exclude,*::run*', 'graal.api'])
-                    tasks.append(t.stop())
+                    with VM(theVm, vmbuild):
+                        t = Task('DaCapo_pmd:' + theVm + ':' + vmbuild)
+                        dacapo(['pmd'])
+                        tasks.append(t.stop())
+    
+                        t = Task('UnitTests:' + theVm + ':' + vmbuild)
+                        unittest(['@-XX:CompileCommand=exclude,*::run*', 'graal.api'])
+                        tasks.append(t.stop())
 
     except KeyboardInterrupt:
         total.abort(1)
@@ -1086,7 +1146,7 @@
             del args[index]
         else:
             mx.abort('-resultfile must be followed by a file name')
-    vm = _vm
+    vm = _get_vm()
     if len(args) is 0:
         args = ['all']
     
@@ -1190,7 +1250,7 @@
             mx.abort('-it (Iteration time) needs a numeric value (seconds)')
         vmArgs.remove('-it')
         benchArgs.remove(args[itIdx+1])
-    vm = _vm;
+    vm = _get_vm();
     sanitycheck.getSPECjvm2008(benchArgs, skipCheck, skipValid, wt, it).bench(vm, opts=vmArgs)
     
 def specjbb2013(args):
@@ -1199,7 +1259,7 @@
     All options begining with - will be passed to the vm"""
     benchArgs = [a for a in args if a[0] != '-']
     vmArgs = [a for a in args if a[0] == '-']
-    vm = _vm;
+    vm = _get_vm();
     sanitycheck.getSPECjbb2013(benchArgs).bench(vm, opts=vmArgs)
 
 def specjbb2005(args):
@@ -1208,7 +1268,7 @@
         All options begining with - will be passed to the vm"""
     benchArgs = [a for a in args if a[0] != '-']
     vmArgs = [a for a in args if a[0] == '-']
-    vm = _vm;
+    vm = _get_vm();
     sanitycheck.getSPECjbb2005(benchArgs).bench(vm, opts=vmArgs)
 
 def hsdis(args, copyToDir=None):
@@ -1339,7 +1399,7 @@
     mx.add_argument('--vmdir', help='specify where the directory in which the vms should be', default=None)
 
     if (_vmSourcesAvailable):
-        mx.add_argument('--vm', action='store', dest='vm', default='graal', choices=_vmChoices, help='the VM to build/run (default: ' + _vmChoices[0] + ')')
+        mx.add_argument('--vm', action='store', dest='vm', choices=_vmChoices.keys(), help='the VM to build/run')
         for c in _vmbuildChoices:
             mx.add_argument('--' + c, action='store_const', dest='vmbuild', const=c, help='select the ' + c + ' build of the VM')
         mx.add_argument('--ecl', action='store_true', dest='make_eclipse_launch', help='create launch configuration for running VM execution(s) in Eclipse')
--- a/mxtool/mx.py	Tue Aug 13 13:26:58 2013 +0200
+++ b/mxtool/mx.py	Tue Aug 13 14:25:02 2013 +0200
@@ -138,6 +138,7 @@
 """
 
 import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile
+import textwrap
 import xml.parsers.expat
 import shutil, re, xml.dom.minidom
 from collections import Callable
@@ -3279,25 +3280,49 @@
                         log(classname)
     return matches
 
-def select_items(candidates):
+def select_items(items, descriptions=None, allowMultiple=True):
     """
-    Presents a command line interface for selecting one or more items from a sequence.
+    Presents a command line interface for selecting one or more (if allowMultiple is true) items.
+    
     """
-    if len(candidates) == 0:
+    if len(items) == 0:
         return []
-    elif len(candidates) > 1:
-        log('[0] <all>')
-        for i in range(0, len(candidates)):
-            log('[{0}] {1}'.format(i + 1, candidates[i]))
-        s = raw_input('Enter number of selection: ')
-        try:
-            si = int(s)
-        except:
-            si = 0
-        if si == 0 or si not in range(1, len(candidates) + 1):
-            return candidates
-        else:
-            return [candidates[si - 1]]
+    elif len(items) > 1:
+        if allowMultiple:
+            log('[0] <all>')
+        for i in range(0, len(items)):
+            if descriptions is None:
+                log('[{0}] {1}'.format(i + 1, items[i]))
+            else:
+                assert len(items) == len(descriptions)
+                wrapper = textwrap.TextWrapper(subsequent_indent='    ')
+                log('\n'.join(wrapper.wrap('[{0}] {1} - {2}'.format(i + 1, items[i], descriptions[i]))))
+        while True:
+            if allowMultiple:
+                s = raw_input('Enter number(s) of selection (separate multiple choices with spaces): ').split()
+            else:
+                s = [raw_input('Enter number of selection: ')]
+            try:
+                s = [int(x) for x in s]
+            except:
+                log('Selection contains non-numeric characters: "' + ' '.join(s) + '"')
+                continue
+            
+            if allowMultiple and 0 in s:
+                return items
+            
+            indexes = []
+            for n in s:
+                if n not in range(1, len(items) + 1):
+                    log('Invalid selection: ' + str(n))
+                    continue
+                else:
+                    indexes.append(n - 1)
+            if allowMultiple:
+                return [items[i] for i in indexes]
+            if len(indexes) == 1:
+                return items[indexes[0]]
+            return None
 
 def javap(args):
     """disassemble classes matching given pattern with javap"""