# HG changeset patch # User Doug Simon # Date 1376396638 -7200 # Node ID 4e943a311d9c17b0171ce1fe954cee8394557781 # Parent bb70a309a7cfc41d415809cc9dedcbaee24c3ca0 mx presents a command line dialogue to select the default VM if it is not configured (GRAAL-416) added prompt to build missing VM the first time it is executed cleaner support using 'with' statement for switching the configured VM within a scope diff -r bb70a309a7cf -r 4e943a311d9c mx/commands.py --- a/mx/commands.py Tue Aug 13 11:07:08 2013 +0200 +++ b/mx/commands.py Tue Aug 13 14:23:58 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')