comparison mx/commands.py @ 5729:dab877fe7c31

prevented error during mx site from corrupting an existing site
author Doug Simon <doug.simon@oracle.com>
date Thu, 28 Jun 2012 15:36:28 +0200
parents 1c7852e6a39a
children 30876d0bb92d b30cced39597
comparison
equal deleted inserted replaced
5728:956217932b8c 5729:dab877fe7c31
35 import json 35 import json
36 36
37 _graal_home = dirname(dirname(__file__)) 37 _graal_home = dirname(dirname(__file__))
38 38
39 """ Used to distinguish an exported GraalVM (see 'mx export'). """ 39 """ Used to distinguish an exported GraalVM (see 'mx export'). """
40 _vmSourcesAvailable = exists(join(_graal_home, 'make')) and exists(join(_graal_home, 'src')) 40 _vmSourcesAvailable = exists(join(_graal_home, 'make')) and exists(join(_graal_home, 'src'))
41 41
42 """ The VM that will be run by the 'vm' command: graal(default), client or server. 42 """ The VM that will be run by the 'vm' command: graal(default), client or server.
43 This can be set via the global '--vm' option. """ 43 This can be set via the global '--vm' option. """
44 _vm = 'graal' 44 _vm = 'graal'
45 45
71 * 71 *
72 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 72 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
73 * or visit www.oracle.com if you need additional information or have any 73 * or visit www.oracle.com if you need additional information or have any
74 * questions. 74 * questions.
75 */ 75 */
76 76
77 """ 77 """
78 78
79 def clean(args): 79 def clean(args):
80 """cleans the GraalVM source tree""" 80 """cleans the GraalVM source tree"""
81 opts = mx.clean(args, parser=ArgumentParser(prog='mx clean')) 81 opts = mx.clean(args, parser=ArgumentParser(prog='mx clean'))
86 if exists(jdks): 86 if exists(jdks):
87 shutil.rmtree(jdks) 87 shutil.rmtree(jdks)
88 88
89 def export(args): 89 def export(args):
90 """create a GraalVM zip file for distribution""" 90 """create a GraalVM zip file for distribution"""
91 91
92 parser = ArgumentParser(prog='mx export'); 92 parser = ArgumentParser(prog='mx export');
93 parser.add_argument('--omit-vm-build', action='store_false', dest='vmbuild', help='omit VM build step') 93 parser.add_argument('--omit-vm-build', action='store_false', dest='vmbuild', help='omit VM build step')
94 parser.add_argument('--omit-dist-init', action='store_false', dest='distInit', help='omit class files and IDE configurations from distribution') 94 parser.add_argument('--omit-dist-init', action='store_false', dest='distInit', help='omit class files and IDE configurations from distribution')
95 parser.add_argument('zipfile', nargs=REMAINDER, metavar='zipfile') 95 parser.add_argument('zipfile', nargs=REMAINDER, metavar='zipfile')
96 96
97 args = parser.parse_args(args) 97 args = parser.parse_args(args)
98 98
99 tmp = tempfile.mkdtemp(prefix='tmp', dir=_graal_home) 99 tmp = tempfile.mkdtemp(prefix='tmp', dir=_graal_home)
100 if args.vmbuild: 100 if args.vmbuild:
101 # Make sure the product VM binary is up to date 101 # Make sure the product VM binary is up to date
102 build(['product']) 102 build(['product'])
103 103
104 mx.log('Copying Java sources and mx files...') 104 mx.log('Copying Java sources and mx files...')
105 mx.run(('hg archive -I graal -I mx -I mxtool -I mx.sh ' + tmp).split()) 105 mx.run(('hg archive -I graal -I mx -I mxtool -I mx.sh ' + tmp).split())
106 106
107 # Copy the GraalVM JDK 107 # Copy the GraalVM JDK
108 mx.log('Copying GraalVM JDK...') 108 mx.log('Copying GraalVM JDK...')
109 src = _jdk() 109 src = _jdk()
110 dst = join(tmp, basename(src)) 110 dst = join(tmp, basename(src))
111 shutil.copytree(src, dst) 111 shutil.copytree(src, dst)
121 if args.distInit: 121 if args.distInit:
122 mx.log('Creating class files...') 122 mx.log('Creating class files...')
123 mx.run('mx build'.split(), cwd=tmp) 123 mx.run('mx build'.split(), cwd=tmp)
124 mx.log('Creating IDE configurations...') 124 mx.log('Creating IDE configurations...')
125 mx.run('mx ideinit'.split(), cwd=tmp) 125 mx.run('mx ideinit'.split(), cwd=tmp)
126 126
127 # clean up temp directory 127 # clean up temp directory
128 mx.log('Cleaning up...') 128 mx.log('Cleaning up...')
129 shutil.rmtree(tmp) 129 shutil.rmtree(tmp)
130 130
131 mx.log('Created distribution in ' + zfName) 131 mx.log('Created distribution in ' + zfName)
132 132
133 def example(args): 133 def example(args):
134 """run some or all Graal examples""" 134 """run some or all Graal examples"""
135 examples = { 135 examples = {
138 } 138 }
139 139
140 def run_example(verbose, project, mainClass): 140 def run_example(verbose, project, mainClass):
141 cp = mx.classpath(project) 141 cp = mx.classpath(project)
142 sharedArgs = ['-Xcomp', '-XX:CompileOnly=Main', mainClass] 142 sharedArgs = ['-Xcomp', '-XX:CompileOnly=Main', mainClass]
143 143
144 res = [] 144 res = []
145 mx.log("=== Server VM ===") 145 mx.log("=== Server VM ===")
146 printArg = '-XX:+PrintCompilation' if verbose else '-XX:-PrintCompilation' 146 printArg = '-XX:+PrintCompilation' if verbose else '-XX:-PrintCompilation'
147 res.append(vm(['-cp', cp, printArg] + sharedArgs, vm='server')) 147 res.append(vm(['-cp', cp, printArg] + sharedArgs, vm='server'))
148 mx.log("=== Graal VM ===") 148 mx.log("=== Graal VM ===")
149 printArg = '-G:+PrintCompilation' if verbose else '-G:-PrintCompilation' 149 printArg = '-G:+PrintCompilation' if verbose else '-G:-PrintCompilation'
150 res.append(vm(['-cp', cp, printArg, '-G:-Extend', '-G:-Inline'] + sharedArgs)) 150 res.append(vm(['-cp', cp, printArg, '-G:-Extend', '-G:-Inline'] + sharedArgs))
151 mx.log("=== Graal VM with extensions ===") 151 mx.log("=== Graal VM with extensions ===")
152 res.append(vm(['-cp', cp, printArg, '-G:+Extend', '-G:-Inline'] + sharedArgs)) 152 res.append(vm(['-cp', cp, printArg, '-G:+Extend', '-G:-Inline'] + sharedArgs))
153 153
154 if len([x for x in res if x != 0]) != 0: 154 if len([x for x in res if x != 0]) != 0:
155 return 1 155 return 1
156 return 0 156 return 0
157 157
158 verbose = False 158 verbose = False
171 project, mainClass = config 171 project, mainClass = config
172 run_example(verbose, project, mainClass) 172 run_example(verbose, project, mainClass)
173 173
174 def dacapo(args): 174 def dacapo(args):
175 """run one or all DaCapo benchmarks 175 """run one or all DaCapo benchmarks
176 176
177 DaCapo options are distinguished from VM options by a '@' prefix. 177 DaCapo options are distinguished from VM options by a '@' prefix.
178 For example, '@-n @5' will pass '-n 5' to the 178 For example, '@-n @5' will pass '-n 5' to the
179 DaCapo harness.""" 179 DaCapo harness."""
180 180
181 numTests = {} 181 numTests = {}
194 assert len(args) > 1 and args[1][0] not in ['-', '@'] and not args[1].isdigit() 194 assert len(args) > 1 and args[1][0] not in ['-', '@'] and not args[1].isdigit()
195 bm = args[1] 195 bm = args[1]
196 del args[0] 196 del args[0]
197 else: 197 else:
198 bm = args[0] 198 bm = args[0]
199 199
200 del args[0] 200 del args[0]
201 if bm not in sanitycheck.dacapoSanityWarmup.keys(): 201 if bm not in sanitycheck.dacapoSanityWarmup.keys():
202 mx.abort('unknown benchmark: ' + bm + '\nselect one of: ' + str(sanitycheck.dacapoSanityWarmup.keys())) 202 mx.abort('unknown benchmark: ' + bm + '\nselect one of: ' + str(sanitycheck.dacapoSanityWarmup.keys()))
203 numTests[bm] = n 203 numTests[bm] = n
204 204
205 if len(numTests) is 0: 205 if len(numTests) is 0:
206 for bench in sanitycheck.dacapoSanityWarmup.keys(): 206 for bench in sanitycheck.dacapoSanityWarmup.keys():
207 numTests[bench] = 1 207 numTests[bench] = 1
208 208
209 # Extract DaCapo options 209 # Extract DaCapo options
210 dacapoArgs = [(arg[1:]) for arg in args if arg.startswith('@')] 210 dacapoArgs = [(arg[1:]) for arg in args if arg.startswith('@')]
211 211
212 # The remainder are VM options 212 # The remainder are VM options
213 vmOpts = [arg for arg in args if not arg.startswith('@')] 213 vmOpts = [arg for arg in args if not arg.startswith('@')]
214 vm = _vm 214 vm = _vm
215 215
216 failed = [] 216 failed = []
217 for (test, n) in numTests.items(): 217 for (test, n) in numTests.items():
218 if not sanitycheck.getDacapo(test, n, dacapoArgs).test(vm, opts=vmOpts): 218 if not sanitycheck.getDacapo(test, n, dacapoArgs).test(vm, opts=vmOpts):
219 failed.append(test) 219 failed.append(test)
220 220
221 if len(failed) != 0: 221 if len(failed) != 0:
222 mx.abort('DaCapo failures: ' + str(failed)) 222 mx.abort('DaCapo failures: ' + str(failed))
223 223
224 def intro(args): 224 def intro(args):
225 """run a simple program and visualize its compilation in the Graal Visualizer""" 225 """run a simple program and visualize its compilation in the Graal Visualizer"""
226 # Start the visualizer in a separate thread 226 # Start the visualizer in a separate thread
227 t = Thread(target=gv, args=([[]])) 227 t = Thread(target=gv, args=([[]]))
228 t.start() 228 t.start()
229 229
230 # Give visualizer time to start 230 # Give visualizer time to start
231 mx.log('Waiting 5 seconds for visualizer to start') 231 mx.log('Waiting 5 seconds for visualizer to start')
232 time.sleep(5) 232 time.sleep(5)
233 233
234 vm(['-G:Dump=', '-G:MethodFilter=greet', '-Xcomp', '-XX:CompileOnly=HelloWorld::greet', '-cp', mx.classpath('com.oracle.graal.examples')] + args + ['examples.HelloWorld']) 234 vm(['-G:Dump=', '-G:MethodFilter=greet', '-Xcomp', '-XX:CompileOnly=HelloWorld::greet', '-cp', mx.classpath('com.oracle.graal.examples')] + args + ['examples.HelloWorld'])
235 235
236 def scaladacapo(args): 236 def scaladacapo(args):
237 """run one or all Scala DaCapo benchmarks 237 """run one or all Scala DaCapo benchmarks
238 238
239 Scala DaCapo options are distinguished from VM options by a '@' prefix. 239 Scala DaCapo options are distinguished from VM options by a '@' prefix.
240 For example, '@--iterations @5' will pass '--iterations 5' to the 240 For example, '@--iterations @5' will pass '--iterations 5' to the
241 DaCapo harness.""" 241 DaCapo harness."""
242 242
243 numTests = {} 243 numTests = {}
244 244
245 if len(args) > 0: 245 if len(args) > 0:
246 level = getattr(sanitycheck.SanityCheckLevel, args[0], None) 246 level = getattr(sanitycheck.SanityCheckLevel, args[0], None)
247 if level is not None: 247 if level is not None:
248 del args[0] 248 del args[0]
249 for (bench, ns) in sanitycheck.dacapoScalaSanityWarmup.items(): 249 for (bench, ns) in sanitycheck.dacapoScalaSanityWarmup.items():
257 assert len(args) > 1 and args[1][0] not in ['-', '@'] and not args[1].isdigit() 257 assert len(args) > 1 and args[1][0] not in ['-', '@'] and not args[1].isdigit()
258 bm = args[1] 258 bm = args[1]
259 del args[0] 259 del args[0]
260 else: 260 else:
261 bm = args[0] 261 bm = args[0]
262 262
263 del args[0] 263 del args[0]
264 if bm not in sanitycheck.dacapoScalaSanityWarmup.keys(): 264 if bm not in sanitycheck.dacapoScalaSanityWarmup.keys():
265 mx.abort('unknown benchmark: ' + bm + '\nselect one of: ' + str(sanitycheck.dacapoScalaSanityWarmup.keys())) 265 mx.abort('unknown benchmark: ' + bm + '\nselect one of: ' + str(sanitycheck.dacapoScalaSanityWarmup.keys()))
266 numTests[bm] = n 266 numTests[bm] = n
267 267
268 if len(numTests) is 0: 268 if len(numTests) is 0:
269 for bench in sanitycheck.dacapoScalaSanityWarmup.keys(): 269 for bench in sanitycheck.dacapoScalaSanityWarmup.keys():
270 numTests[bench] = 1 270 numTests[bench] = 1
271 271
272 # Extract DaCapo options 272 # Extract DaCapo options
273 dacapoArgs = [(arg[1:]) for arg in args if arg.startswith('@')] 273 dacapoArgs = [(arg[1:]) for arg in args if arg.startswith('@')]
274 274
275 # The remainder are VM options 275 # The remainder are VM options
276 vmOpts = [arg for arg in args if not arg.startswith('@')] 276 vmOpts = [arg for arg in args if not arg.startswith('@')]
277 vm = _vm; 277 vm = _vm;
278 278
279 failed = [] 279 failed = []
280 for (test, n) in numTests.items(): 280 for (test, n) in numTests.items():
281 if not sanitycheck.getScalaDacapo(test, n, dacapoArgs).test(vm, opts=vmOpts): 281 if not sanitycheck.getScalaDacapo(test, n, dacapoArgs).test(vm, opts=vmOpts):
282 failed.append(test) 282 failed.append(test)
283 283
284 if len(failed) != 0: 284 if len(failed) != 0:
285 mx.abort('Scala DaCapo failures: ' + str(failed)) 285 mx.abort('Scala DaCapo failures: ' + str(failed))
286 286
287 def _vmLibDirInJdk(jdk): 287 def _vmLibDirInJdk(jdk):
288 """ 288 """
289 Get the directory within a JDK where the server and client 289 Get the directory within a JDK where the server and client
290 subdirectories are located. 290 subdirectories are located.
291 """ 291 """
292 if platform.system() == 'Darwin': 292 if platform.system() == 'Darwin':
293 return join(jdk, 'jre', 'lib') 293 return join(jdk, 'jre', 'lib')
294 if platform.system() == 'Windows': 294 if platform.system() == 'Windows':
320 src = join(srcJdk, d) 320 src = join(srcJdk, d)
321 dst = join(jdk, d) 321 dst = join(jdk, d)
322 if not exists(src): 322 if not exists(src):
323 mx.abort('Host JDK directory is missing: ' + src) 323 mx.abort('Host JDK directory is missing: ' + src)
324 shutil.copytree(src, dst) 324 shutil.copytree(src, dst)
325 325
326 # Make a copy of the default VM so that this JDK can be 326 # Make a copy of the default VM so that this JDK can be
327 # reliably used as the bootstrap for a HotSpot build. 327 # reliably used as the bootstrap for a HotSpot build.
328 jvmCfg = _vmCfgInJdk(jdk) 328 jvmCfg = _vmCfgInJdk(jdk)
329 if not exists(jvmCfg): 329 if not exists(jvmCfg):
330 mx.abort(jvmCfg + ' does not exist') 330 mx.abort(jvmCfg + ' does not exist')
331 331
332 lines = [] 332 lines = []
333 defaultVM = None 333 defaultVM = None
334 with open(jvmCfg) as f: 334 with open(jvmCfg) as f:
335 for line in f: 335 for line in f:
336 if line.startswith('-') and defaultVM is None: 336 if line.startswith('-') and defaultVM is None:
341 lines.append('-' + defaultVM + '0 KNOWN\n') 341 lines.append('-' + defaultVM + '0 KNOWN\n')
342 lines.append(line) 342 lines.append(line)
343 343
344 assert defaultVM is not None, 'Could not find default VM in ' + jvmCfg 344 assert defaultVM is not None, 'Could not find default VM in ' + jvmCfg
345 shutil.copytree(join(_vmLibDirInJdk(jdk), defaultVM), join(_vmLibDirInJdk(jdk), defaultVM + '0')) 345 shutil.copytree(join(_vmLibDirInJdk(jdk), defaultVM), join(_vmLibDirInJdk(jdk), defaultVM + '0'))
346 346
347 with open(jvmCfg, 'w') as f: 347 with open(jvmCfg, 'w') as f:
348 for line in lines: 348 for line in lines:
349 f.write(line) 349 f.write(line)
350 350
351 # Install a copy of the disassembler library 351 # Install a copy of the disassembler library
352 try: 352 try:
353 hsdis([], copyToDir=_vmLibDirInJdk(jdk)) 353 hsdis([], copyToDir=_vmLibDirInJdk(jdk))
354 except SystemExit: 354 except SystemExit:
355 pass 355 pass
356 else: 356 else:
357 if not exists(jdk): 357 if not exists(jdk):
358 mx.abort('The ' + build + ' VM has not been created - run \'mx clean; mx build ' + build + '\'') 358 mx.abort('The ' + build + ' VM has not been created - run \'mx clean; mx build ' + build + '\'')
359 return jdk 359 return jdk
360 360
361 # run a command in the windows SDK Debug Shell 361 # run a command in the windows SDK Debug Shell
362 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo={}): 362 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo={}):
363 newLine = os.linesep 363 newLine = os.linesep
364 STARTTOKEN = 'RUNINDEBUGSHELL_STARTSEQUENCE' 364 STARTTOKEN = 'RUNINDEBUGSHELL_STARTSEQUENCE'
365 ENDTOKEN = 'RUNINDEBUGSHELL_ENDSEQUENCE' 365 ENDTOKEN = 'RUNINDEBUGSHELL_ENDSEQUENCE'
366 366
367 winSDK = mx.get_env('WIN_SDK', 'C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\') 367 winSDK = mx.get_env('WIN_SDK', 'C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\')
368 368
369 p = subprocess.Popen('cmd.exe /E:ON /V:ON /K ""' + winSDK + '/Bin/SetEnv.cmd" & echo ' + STARTTOKEN + '"', \ 369 p = subprocess.Popen('cmd.exe /E:ON /V:ON /K ""' + winSDK + '/Bin/SetEnv.cmd" & echo ' + STARTTOKEN + '"', \
370 shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) 370 shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
371 stdout = p.stdout 371 stdout = p.stdout
400 break; 400 break;
401 stdin.write('exit' + newLine) 401 stdin.write('exit' + newLine)
402 if logFile: 402 if logFile:
403 log.close() 403 log.close()
404 return ret 404 return ret
405 405
406 def jdkhome(args, vm=None): 406 def jdkhome(args, vm=None):
407 """prints the JDK directory selected for the 'vm' command""" 407 """prints the JDK directory selected for the 'vm' command"""
408 408
409 build = _vmbuild if _vmSourcesAvailable else 'product' 409 build = _vmbuild if _vmSourcesAvailable else 'product'
410 print join(_graal_home, 'jdk' + mx.java().version, build) 410 print join(_graal_home, 'jdk' + mx.java().version, build)
411 411
412 def build(args, vm=None): 412 def build(args, vm=None):
413 """build the VM binary 413 """build the VM binary
414 414
415 The global '--vm' option selects which VM to build. This command also 415 The global '--vm' option selects which VM to build. This command also
416 compiles the Graal classes irrespective of what VM is being built. 416 compiles the Graal classes irrespective of what VM is being built.
417 The optional last argument specifies what build level is to be used 417 The optional last argument specifies what build level is to be used
418 for the VM binary.""" 418 for the VM binary."""
419 419
420 # Call mx.build to compile the Java sources 420 # Call mx.build to compile the Java sources
421 opts2 = mx.build(['--source', '1.7'] + args, parser=ArgumentParser(prog='mx build')) 421 opts2 = mx.build(['--source', '1.7'] + args, parser=ArgumentParser(prog='mx build'))
422 422
423 if not _vmSourcesAvailable or not opts2.native: 423 if not _vmSourcesAvailable or not opts2.native:
424 return 424 return
425 425
427 if len(builds) == 0: 427 if len(builds) == 0:
428 builds = ['product'] 428 builds = ['product']
429 429
430 if vm is None: 430 if vm is None:
431 vm = _vm 431 vm = _vm
432 432
433 if vm == 'server': 433 if vm == 'server':
434 buildSuffix = '' 434 buildSuffix = ''
435 elif vm == 'client': 435 elif vm == 'client':
436 buildSuffix = '1' 436 buildSuffix = '1'
437 else: 437 else:
438 assert vm == 'graal', vm 438 assert vm == 'graal', vm
439 buildSuffix = 'graal' 439 buildSuffix = 'graal'
440 440
441 for build in builds: 441 for build in builds:
442 if build == 'ide-build-target': 442 if build == 'ide-build-target':
443 build = os.environ.get('IDE_BUILD_TARGET', 'product') 443 build = os.environ.get('IDE_BUILD_TARGET', 'product')
444 if len(build) == 0: 444 if len(build) == 0:
445 mx.log('[skipping build from IDE as IDE_BUILD_TARGET environment variable is ""]') 445 mx.log('[skipping build from IDE as IDE_BUILD_TARGET environment variable is ""]')
446 continue 446 continue
447 447
448 jdk = _jdk(build, create=True) 448 jdk = _jdk(build, create=True)
449 449
450 vmDir = join(_vmLibDirInJdk(jdk), vm) 450 vmDir = join(_vmLibDirInJdk(jdk), vm)
451 if not exists(vmDir): 451 if not exists(vmDir):
452 mx.log('Creating VM directory in JDK7: ' + vmDir) 452 mx.log('Creating VM directory in JDK7: ' + vmDir)
453 os.makedirs(vmDir) 453 os.makedirs(vmDir)
454 454
455 def filterXusage(line): 455 def filterXusage(line):
456 if not 'Xusage.txt' in line: 456 if not 'Xusage.txt' in line:
457 sys.stderr.write(line + os.linesep) 457 sys.stderr.write(line + os.linesep)
458 458
459 # Check that the declaration of graal_projects in arguments.cpp is up to date 459 # Check that the declaration of graal_projects in arguments.cpp is up to date
460 argumentsCpp = join(_graal_home, 'src', 'share', 'vm', 'runtime', 'arguments.cpp') 460 argumentsCpp = join(_graal_home, 'src', 'share', 'vm', 'runtime', 'arguments.cpp')
461 assert exists(argumentsCpp), 'File does not exist: ' + argumentsCpp 461 assert exists(argumentsCpp), 'File does not exist: ' + argumentsCpp
462 with open(argumentsCpp) as fp: 462 with open(argumentsCpp) as fp:
463 source = fp.read(); 463 source = fp.read();
476 mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': remove projects from declaration:\n ' + '\n '.join(extra)) 476 mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': remove projects from declaration:\n ' + '\n '.join(extra))
477 477
478 # Check if a build really needs to be done 478 # Check if a build really needs to be done
479 timestampFile = join(vmDir, '.build-timestamp') 479 timestampFile = join(vmDir, '.build-timestamp')
480 if opts2.force or not exists(timestampFile): 480 if opts2.force or not exists(timestampFile):
481 mustBuild = True 481 mustBuild = True
482 else: 482 else:
483 mustBuild = False 483 mustBuild = False
484 timestamp = os.path.getmtime(timestampFile) 484 timestamp = os.path.getmtime(timestampFile)
485 sources = [] 485 sources = []
486 for d in ['src', 'make']: 486 for d in ['src', 'make']:
487 for root, dirnames, files in os.walk(join(_graal_home, d)): 487 for root, dirnames, files in os.walk(join(_graal_home, d)):
488 # ignore <graal>/src/share/tools 488 # ignore <graal>/src/share/tools
491 sources += [join(root, name) for name in files] 491 sources += [join(root, name) for name in files]
492 for f in sources: 492 for f in sources:
493 if len(f) != 0 and os.path.getmtime(f) > timestamp: 493 if len(f) != 0 and os.path.getmtime(f) > timestamp:
494 mustBuild = True 494 mustBuild = True
495 break 495 break
496 496
497 if not mustBuild: 497 if not mustBuild:
498 mx.log('[all files in src and make directories are older than ' + timestampFile[len(_graal_home) + 1:] + ' - skipping native build]') 498 mx.log('[all files in src and make directories are older than ' + timestampFile[len(_graal_home) + 1:] + ' - skipping native build]')
499 continue 499 continue
500 500
501 if platform.system() == 'Windows': 501 if platform.system() == 'Windows':
508 winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + jdk + r'& set JAVA_HOME=' + jdk + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' +_graal_home + r'\make\windows"& call create.bat ' + _graal_home 508 winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + jdk + r'& set JAVA_HOME=' + jdk + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' +_graal_home + r'\make\windows"& call create.bat ' + _graal_home
509 print(winCompileCmd) 509 print(winCompileCmd)
510 winCompileSuccess = re.compile(r"^Writing \.vcxproj file:") 510 winCompileSuccess = re.compile(r"^Writing \.vcxproj file:")
511 if not _runInDebugShell(winCompileCmd, _graal_home, compilelogfile, winCompileSuccess): 511 if not _runInDebugShell(winCompileCmd, _graal_home, compilelogfile, winCompileSuccess):
512 mx.log('Error executing create command') 512 mx.log('Error executing create command')
513 return 513 return
514 winBuildCmd = 'msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcxproj /p:Configuration=' + project_config + ' /p:Platform=x64' 514 winBuildCmd = 'msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcxproj /p:Configuration=' + project_config + ' /p:Platform=x64'
515 if not _runInDebugShell(winBuildCmd, _graal_home, compilelogfile): 515 if not _runInDebugShell(winBuildCmd, _graal_home, compilelogfile):
516 mx.log('Error building project') 516 mx.log('Error building project')
517 return 517 return
518 else: 518 else:
519 cpus = multiprocessing.cpu_count() 519 cpus = multiprocessing.cpu_count()
520 if build == 'debug': 520 if build == 'debug':
521 build = 'jvmg' 521 build = 'jvmg'
522 env = os.environ 522 env = os.environ
523 env.setdefault('ARCH_DATA_MODEL', '64') 523 env.setdefault('ARCH_DATA_MODEL', '64')
524 env.setdefault('LANG', 'C') 524 env.setdefault('LANG', 'C')
525 env.setdefault('HOTSPOT_BUILD_JOBS', str(cpus)) 525 env.setdefault('HOTSPOT_BUILD_JOBS', str(cpus))
526 env['ALT_BOOTDIR'] = jdk 526 env['ALT_BOOTDIR'] = jdk
527 env.setdefault('INSTALL', 'y') 527 env.setdefault('INSTALL', 'y')
528 528
529 # Clear these 2 variables as having them set can cause very confusing build problems 529 # Clear these 2 variables as having them set can cause very confusing build problems
530 env.pop('LD_LIBRARY_PATH', None) 530 env.pop('LD_LIBRARY_PATH', None)
531 env.pop('CLASSPATH', None) 531 env.pop('CLASSPATH', None)
532 532
533 mx.run([mx.gmake_cmd(), build + buildSuffix], cwd=join(_graal_home, 'make'), err=filterXusage) 533 mx.run([mx.gmake_cmd(), build + buildSuffix], cwd=join(_graal_home, 'make'), err=filterXusage)
534 534
535 jvmCfg = _vmCfgInJdk(jdk) 535 jvmCfg = _vmCfgInJdk(jdk)
536 found = False 536 found = False
537 if not exists(jvmCfg): 537 if not exists(jvmCfg):
538 mx.abort(jvmCfg + ' does not exist') 538 mx.abort(jvmCfg + ' does not exist')
539 539
540 prefix = '-' + vm 540 prefix = '-' + vm
541 vmKnown = prefix + ' KNOWN\n' 541 vmKnown = prefix + ' KNOWN\n'
542 lines = [] 542 lines = []
543 with open(jvmCfg) as f: 543 with open(jvmCfg) as f:
544 for line in f: 544 for line in f:
570 def vm(args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, vmbuild=None): 570 def vm(args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, vmbuild=None):
571 """run the VM selected by the '--vm' option""" 571 """run the VM selected by the '--vm' option"""
572 572
573 if vm is None: 573 if vm is None:
574 vm = _vm 574 vm = _vm
575 575
576 build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product' 576 build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product'
577 jdk = _jdk(build) 577 jdk = _jdk(build)
578 mx.expand_project_in_args(args) 578 mx.expand_project_in_args(args)
579 if _make_eclipse_launch: 579 if _make_eclipse_launch:
580 mx.make_eclipse_launch(args, 'graal-' + build, name=None, deps=mx.project('com.oracle.graal.hotspot').all_deps([], True)) 580 mx.make_eclipse_launch(args, 'graal-' + build, name=None, deps=mx.project('com.oracle.graal.hotspot').all_deps([], True))
648 def containsAny(c, substrings): 648 def containsAny(c, substrings):
649 for s in substrings: 649 for s in substrings:
650 if s in c: 650 if s in c:
651 return True 651 return True
652 return False 652 return False
653 653
654 for p in mx.projects(): 654 for p in mx.projects():
655 if getattr(p, 'testHarness', None) == harnessName: 655 if getattr(p, 'testHarness', None) == harnessName:
656 classes = [] 656 classes = []
657 _find_classes_with_annotations(classes, p, None, ['@Test']) 657 _find_classes_with_annotations(classes, p, None, ['@Test'])
658 658
659 if len(pos) != 0: 659 if len(pos) != 0:
660 classes = [c for c in classes if containsAny(c, pos)] 660 classes = [c for c in classes if containsAny(c, pos)]
661 if len(neg) != 0: 661 if len(neg) != 0:
662 classes = [c for c in classes if not containsAny(c, neg)] 662 classes = [c for c in classes if not containsAny(c, neg)]
663 663
664 if len(classes) != 0: 664 if len(classes) != 0:
665 mx.log('running tests in ' + p.name) 665 mx.log('running tests in ' + p.name)
666 harness(p, vmArgs, classes) 666 harness(p, vmArgs, classes)
667 667
668 def unittest(args): 668 def unittest(args):
669 """run the Graal Compiler Unit Tests in the GraalVM 669 """run the Graal Compiler Unit Tests in the GraalVM
670 670
671 If filters are supplied, only tests whose fully qualified name 671 If filters are supplied, only tests whose fully qualified name
672 include a filter as a substring are run. Negative filters are 672 include a filter as a substring are run. Negative filters are
673 those with a '-' prefix. VM args should have a @ prefix.""" 673 those with a '-' prefix. VM args should have a @ prefix."""
674 674
675 def harness(p, vmArgs, classes): 675 def harness(p, vmArgs, classes):
676 vm(['-XX:-BootstrapGraal', '-esa'] + vmArgs + ['-cp', mx.classpath(p.name), 'org.junit.runner.JUnitCore'] + classes) 676 vm(['-XX:-BootstrapGraal', '-esa'] + vmArgs + ['-cp', mx.classpath(p.name), 'org.junit.runner.JUnitCore'] + classes)
677 _run_tests(args, 'unittest', harness) 677 _run_tests(args, 'unittest', harness)
678 678
679 def jtt(args): 679 def jtt(args):
680 """run the Java Tester Tests in the GraalVM 680 """run the Java Tester Tests in the GraalVM
681 681
682 If filters are supplied, only tests whose fully qualified name 682 If filters are supplied, only tests whose fully qualified name
683 include a filter as a substring are run. Negative filters are 683 include a filter as a substring are run. Negative filters are
684 those with a '-' prefix. VM args should have a @ prefix.""" 684 those with a '-' prefix. VM args should have a @ prefix."""
685 685
686 def harness(p, vmArgs, classes): 686 def harness(p, vmArgs, classes):
687 vm(['-XX:-BootstrapGraal', '-XX:CompileOnly=com/oracle/graal/jtt', '-XX:CompileCommand=compileonly,java/lang/Object::<init>', '-XX:CompileCommand=quiet', '-Xcomp', '-esa'] + vmArgs + ['-cp', mx.classpath(p.name), 'org.junit.runner.JUnitCore'] + classes) 687 vm(['-XX:-BootstrapGraal', '-XX:CompileOnly=com/oracle/graal/jtt', '-XX:CompileCommand=compileonly,java/lang/Object::<init>', '-XX:CompileCommand=quiet', '-Xcomp', '-esa'] + vmArgs + ['-cp', mx.classpath(p.name), 'org.junit.runner.JUnitCore'] + classes)
688 _run_tests(args, 'jtt', harness) 688 _run_tests(args, 'jtt', harness)
689 689
690 def buildvms(args): 690 def buildvms(args):
691 """build one or more VMs in various configurations""" 691 """build one or more VMs in various configurations"""
692 692
693 parser = ArgumentParser(prog='mx buildvms'); 693 parser = ArgumentParser(prog='mx buildvms');
694 parser.add_argument('--vms', help='a comma separated list of VMs to build (default: server,client,graal)', default='server,client,graal') 694 parser.add_argument('--vms', help='a comma separated list of VMs to build (default: server,client,graal)', default='server,client,graal')
695 parser.add_argument('--builds', help='a comma separated list of build types (default: product,fastdebug,debug)', default='product,fastdebug,debug') 695 parser.add_argument('--builds', help='a comma separated list of build types (default: product,fastdebug,debug)', default='product,fastdebug,debug')
696 696
697 args = parser.parse_args(args) 697 args = parser.parse_args(args)
698 vms = args.vms.split(',') 698 vms = args.vms.split(',')
699 builds = args.builds.split(',') 699 builds = args.builds.split(',')
700 700
701 allStart = time.time() 701 allStart = time.time()
702 for v in vms: 702 for v in vms:
703 for vmbuild in builds: 703 for vmbuild in builds:
704 logFile = join(v + '-' + vmbuild + '.log') 704 logFile = join(v + '-' + vmbuild + '.log')
705 log = open(join(_graal_home, logFile), 'wb') 705 log = open(join(_graal_home, logFile), 'wb')
715 def gate(args): 715 def gate(args):
716 """run the tests used to validate a push 716 """run the tests used to validate a push
717 717
718 If this command exits with a 0 exit code, then the source code is in 718 If this command exits with a 0 exit code, then the source code is in
719 a state that would be accepted for integration into the main repository.""" 719 a state that would be accepted for integration into the main repository."""
720 720
721 class Task: 721 class Task:
722 def __init__(self, title): 722 def __init__(self, title):
723 self.start = time.time() 723 self.start = time.time()
724 self.title = title 724 self.title = title
725 self.end = None 725 self.end = None
734 self.end = time.time() 734 self.end = time.time()
735 self.duration = datetime.timedelta(seconds=self.end - self.start) 735 self.duration = datetime.timedelta(seconds=self.end - self.start)
736 mx.log(time.strftime('gate: %d %b %Y %H:%M:%S: ABORT: ') + self.title + ' [' + str(self.duration) + ']') 736 mx.log(time.strftime('gate: %d %b %Y %H:%M:%S: ABORT: ') + self.title + ' [' + str(self.duration) + ']')
737 mx.abort(codeOrMessage) 737 mx.abort(codeOrMessage)
738 return self 738 return self
739 739
740 parser = ArgumentParser(prog='mx gate'); 740 parser = ArgumentParser(prog='mx gate');
741 parser.add_argument('-j', '--omit-java-clean', action='store_false', dest='cleanJava', help='omit cleaning Java native code') 741 parser.add_argument('-j', '--omit-java-clean', action='store_false', dest='cleanJava', help='omit cleaning Java native code')
742 parser.add_argument('-n', '--omit-native-build', action='store_false', dest='buildNative', help='omit cleaning and building native code') 742 parser.add_argument('-n', '--omit-native-build', action='store_false', dest='buildNative', help='omit cleaning and building native code')
743 parser.add_argument('-g', '--only-build-graalvm', action='store_false', dest='buildNonGraal', help='only build the Graal VM') 743 parser.add_argument('-g', '--only-build-graalvm', action='store_false', dest='buildNonGraal', help='only build the Graal VM')
744 parser.add_argument('--jacocout', help='specify the output directory for jacoco report') 744 parser.add_argument('--jacocout', help='specify the output directory for jacoco report')
746 args = parser.parse_args(args) 746 args = parser.parse_args(args)
747 747
748 global _vmbuild 748 global _vmbuild
749 global _vm 749 global _vm
750 global _jacoco 750 global _jacoco
751 751
752 tasks = [] 752 tasks = []
753 total = Task('Gate') 753 total = Task('Gate')
754 try: 754 try:
755 755
756 t = Task('Clean') 756 t = Task('Clean')
757 cleanArgs = [] 757 cleanArgs = []
758 if not args.buildNative: 758 if not args.buildNative:
759 cleanArgs.append('--no-native') 759 cleanArgs.append('--no-native')
760 if not args.cleanJava: 760 if not args.cleanJava:
761 cleanArgs.append('--no-java') 761 cleanArgs.append('--no-java')
762 clean(cleanArgs) 762 clean(cleanArgs)
763 tasks.append(t.stop()) 763 tasks.append(t.stop())
764 764
765 t = Task('BuildJava') 765 t = Task('BuildJava')
766 build(['--no-native']) 766 build(['--no-native'])
767 tasks.append(t.stop()) 767 tasks.append(t.stop())
768 for vmbuild in ['fastdebug', 'product']: 768 for vmbuild in ['fastdebug', 'product']:
769 _vmbuild = vmbuild 769 _vmbuild = vmbuild
770 770
771 if args.buildNative: 771 if args.buildNative:
772 t = Task('BuildHotSpotGraal:' + vmbuild) 772 t = Task('BuildHotSpotGraal:' + vmbuild)
773 buildvms(['--vms', 'graal', '--builds', vmbuild]) 773 buildvms(['--vms', 'graal', '--builds', vmbuild])
774 tasks.append(t.stop()) 774 tasks.append(t.stop())
775 775
776 t = Task('BootstrapWithSystemAssertions:' + vmbuild) 776 t = Task('BootstrapWithSystemAssertions:' + vmbuild)
777 vm(['-esa', '-version']) 777 vm(['-esa', '-version'])
778 tasks.append(t.stop()) 778 tasks.append(t.stop())
779 779
780 if vmbuild == 'product' and args.jacocout is not None: 780 if vmbuild == 'product' and args.jacocout is not None:
781 _jacoco = 'on' 781 _jacoco = 'on'
782 782
783 t = Task('UnitTests:' + vmbuild) 783 t = Task('UnitTests:' + vmbuild)
784 unittest([]) 784 unittest([])
785 tasks.append(t.stop()) 785 tasks.append(t.stop())
786 786
787 if vmbuild == 'product' and args.jacocout is not None: 787 if vmbuild == 'product' and args.jacocout is not None:
788 _jacoco = 'append' 788 _jacoco = 'append'
789 789
790 t = Task('JavaTesterTests:' + vmbuild) 790 t = Task('JavaTesterTests:' + vmbuild)
791 jtt(['@-XX:CompileCommand=exclude,*::run*'] if vmbuild == 'product' else []) 791 jtt(['@-XX:CompileCommand=exclude,*::run*'] if vmbuild == 'product' else [])
792 tasks.append(t.stop()) 792 tasks.append(t.stop())
793 793
794 if vmbuild == 'product' and args.jacocout is not None: 794 if vmbuild == 'product' and args.jacocout is not None:
795 _jacoco = 'off' 795 _jacoco = 'off'
796 796
797 for test in sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Gate, gateBuildLevel=vmbuild): 797 for test in sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Gate, gateBuildLevel=vmbuild):
798 t = Task(str(test) + ':' + vmbuild) 798 t = Task(str(test) + ':' + vmbuild)
799 if not test.test('graal'): 799 if not test.test('graal'):
800 t.abort(test.name + ' Failed') 800 t.abort(test.name + ' Failed')
801 tasks.append(t.stop()) 801 tasks.append(t.stop())
802 802
803 if args.jacocout is not None: 803 if args.jacocout is not None:
804 jacocoreport([args.jacocout]) 804 jacocoreport([args.jacocout])
805 805
806 t = Task('BootstrapWithDeoptALot') 806 t = Task('BootstrapWithDeoptALot')
807 vm(['-XX:+DeoptimizeALot', '-XX:+VerifyOops', '-version'], vmbuild='fastdebug') 807 vm(['-XX:+DeoptimizeALot', '-XX:+VerifyOops', '-version'], vmbuild='fastdebug')
808 tasks.append(t.stop()) 808 tasks.append(t.stop())
809 809
810 t = Task('Checkstyle') 810 t = Task('Checkstyle')
811 if mx.checkstyle([]) != 0: 811 if mx.checkstyle([]) != 0:
812 t.abort('Checkstyle warnings were found') 812 t.abort('Checkstyle warnings were found')
813 tasks.append(t.stop()) 813 tasks.append(t.stop())
814 814
815 t = Task('Canonicalization Check') 815 t = Task('Canonicalization Check')
816 mx.log(time.strftime('%d %b %Y %H:%M:%S - Ensuring mx/projects files are canonicalized...')) 816 mx.log(time.strftime('%d %b %Y %H:%M:%S - Ensuring mx/projects files are canonicalized...'))
817 if mx.canonicalizeprojects([]) != 0: 817 if mx.canonicalizeprojects([]) != 0:
818 t.abort('Rerun "mx canonicalizeprojects" and check-in the modified mx/projects files.') 818 t.abort('Rerun "mx canonicalizeprojects" and check-in the modified mx/projects files.')
819 tasks.append(t.stop()) 819 tasks.append(t.stop())
820 820
821 t = Task('CleanAndBuildGraalVisualizer') 821 t = Task('CleanAndBuildGraalVisualizer')
822 mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-q', 'clean', 'build']) 822 mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-q', 'clean', 'build'])
823 tasks.append(t.stop()) 823 tasks.append(t.stop())
824 824
825 # Prevent Graal modifications from breaking the standard builds 825 # Prevent Graal modifications from breaking the standard builds
834 _vm = theVm 834 _vm = theVm
835 835
836 t = Task('DaCapo_pmd:' + theVm + ':' + vmbuild) 836 t = Task('DaCapo_pmd:' + theVm + ':' + vmbuild)
837 dacapo(['pmd']) 837 dacapo(['pmd'])
838 tasks.append(t.stop()) 838 tasks.append(t.stop())
839 839
840 except KeyboardInterrupt: 840 except KeyboardInterrupt:
841 total.abort(1) 841 total.abort(1)
842 842
843 except BaseException as e: 843 except BaseException as e:
844 import traceback 844 import traceback
845 traceback.print_exc() 845 traceback.print_exc()
846 total.abort(str(e)) 846 total.abort(str(e))
847 847
848 total.stop() 848 total.stop()
849 849
850 mx.log('Gate task times:') 850 mx.log('Gate task times:')
851 for t in tasks: 851 for t in tasks:
852 mx.log(' ' + str(t.duration) + '\t' + t.title) 852 mx.log(' ' + str(t.duration) + '\t' + t.title)
853 mx.log(' =======') 853 mx.log(' =======')
854 mx.log(' ' + str(total.duration)) 854 mx.log(' ' + str(total.duration))
858 with open(join(_graal_home, '.graal_visualizer.log'), 'w') as fp: 858 with open(join(_graal_home, '.graal_visualizer.log'), 'w') as fp:
859 mx.log('[Graal Visualizer log is in ' + fp.name + ']') 859 mx.log('[Graal Visualizer log is in ' + fp.name + ']')
860 if not exists(join(_graal_home, 'visualizer', 'build.xml')): 860 if not exists(join(_graal_home, 'visualizer', 'build.xml')):
861 mx.log('[This initial execution may take a while as the NetBeans platform needs to be downloaded]') 861 mx.log('[This initial execution may take a while as the NetBeans platform needs to be downloaded]')
862 mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-l', fp.name, 'run']) 862 mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-l', fp.name, 'run'])
863 863
864 def igv(args): 864 def igv(args):
865 """run the Ideal Graph Visualizer""" 865 """run the Ideal Graph Visualizer"""
866 with open(join(_graal_home, '.ideal_graph_visualizer.log'), 'w') as fp: 866 with open(join(_graal_home, '.ideal_graph_visualizer.log'), 'w') as fp:
867 mx.log('[Ideal Graph Visualizer log is in ' + fp.name + ']') 867 mx.log('[Ideal Graph Visualizer log is in ' + fp.name + ']')
868 if not exists(join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'nbplatform')): 868 if not exists(join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'nbplatform')):
895 dacapos = [a[7:] for a in args if a.startswith('dacapo:')] 895 dacapos = [a[7:] for a in args if a.startswith('dacapo:')]
896 for dacapo in dacapos: 896 for dacapo in dacapos:
897 if dacapo not in sanitycheck.dacapoSanityWarmup.keys(): 897 if dacapo not in sanitycheck.dacapoSanityWarmup.keys():
898 mx.abort('Unknown dacapo : ' + dacapo) 898 mx.abort('Unknown dacapo : ' + dacapo)
899 benchmarks += [sanitycheck.getDacapo(dacapo, sanitycheck.dacapoSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark])] 899 benchmarks += [sanitycheck.getDacapo(dacapo, sanitycheck.dacapoSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark])]
900 900
901 if ('scaladacapo' in args or 'all' in args): 901 if ('scaladacapo' in args or 'all' in args):
902 benchmarks += sanitycheck.getScalaDacapos(level=sanitycheck.SanityCheckLevel.Benchmark) 902 benchmarks += sanitycheck.getScalaDacapos(level=sanitycheck.SanityCheckLevel.Benchmark)
903 else: 903 else:
904 dacapos = [a[7:] for a in args if a.startswith('scaladacapo:')] 904 dacapos = [a[7:] for a in args if a.startswith('scaladacapo:')]
905 for dacapo in dacapos: 905 for dacapo in dacapos:
906 if dacapo not in sanitycheck.dacapoScalaSanityWarmup.keys(): 906 if dacapo not in sanitycheck.dacapoScalaSanityWarmup.keys():
907 mx.abort('Unknown dacapo : ' + dacapo) 907 mx.abort('Unknown dacapo : ' + dacapo)
908 benchmarks += [sanitycheck.getScalaDacapo(dacapo, sanitycheck.dacapoScalaSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark])] 908 benchmarks += [sanitycheck.getScalaDacapo(dacapo, sanitycheck.dacapoScalaSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark])]
909 909
910 #Bootstrap 910 #Bootstrap
911 if ('bootstrap' in args or 'all' in args): 911 if ('bootstrap' in args or 'all' in args):
912 benchmarks += sanitycheck.getBootstraps() 912 benchmarks += sanitycheck.getBootstraps()
913 #SPECjvm2008 913 #SPECjvm2008
914 if ('specjvm2008' in args or 'all' in args): 914 if ('specjvm2008' in args or 'all' in args):
915 benchmarks += [sanitycheck.getSPECjvm2008([], True, 120, 120)] 915 benchmarks += [sanitycheck.getSPECjvm2008([], True, 120, 120)]
916 else: 916 else:
917 specjvms = [a[12:] for a in args if a.startswith('specjvm2008:')] 917 specjvms = [a[12:] for a in args if a.startswith('specjvm2008:')]
918 for specjvm in specjvms: 918 for specjvm in specjvms:
919 benchmarks += [sanitycheck.getSPECjvm2008([specjvm], True, 120, 120)] 919 benchmarks += [sanitycheck.getSPECjvm2008([specjvm], True, 120, 120)]
920 920
921 for test in benchmarks: 921 for test in benchmarks:
922 for (group, res) in test.bench(vm).items(): 922 for (group, res) in test.bench(vm).items():
923 if not results.has_key(group): 923 if not results.has_key(group):
924 results[group] = {}; 924 results[group] = {};
925 results[group].update(res) 925 results[group].update(res)
926 mx.log(json.dumps(results)) 926 mx.log(json.dumps(results))
927 if resultFile: 927 if resultFile:
928 with open(resultFile, 'w') as f: 928 with open(resultFile, 'w') as f:
929 f.write(json.dumps(results)) 929 f.write(json.dumps(results))
930 930
931 def specjvm2008(args): 931 def specjvm2008(args):
932 """run one or all SPECjvm2008 benchmarks 932 """run one or all SPECjvm2008 benchmarks
933 933
934 All options begining with - will be passed to the vm except for -ikv -wt and -it. 934 All options begining with - will be passed to the vm except for -ikv -wt and -it.
935 Other options are supposed to be benchmark names and will be passed to SPECjvm2008.""" 935 Other options are supposed to be benchmark names and will be passed to SPECjvm2008."""
936 benchArgs = [a for a in args if a[0] != '-'] 936 benchArgs = [a for a in args if a[0] != '-']
937 vmArgs = [a for a in args if a[0] == '-'] 937 vmArgs = [a for a in args if a[0] == '-']
938 wt = None 938 wt = None
960 mx.abort('-it (Iteration time) needs a numeric value (seconds)') 960 mx.abort('-it (Iteration time) needs a numeric value (seconds)')
961 vmArgs.remove('-it') 961 vmArgs.remove('-it')
962 benchArgs.remove(args[itIdx+1]) 962 benchArgs.remove(args[itIdx+1])
963 vm = _vm; 963 vm = _vm;
964 sanitycheck.getSPECjvm2008(benchArgs, skipValid, wt, it).bench(vm, opts=vmArgs) 964 sanitycheck.getSPECjvm2008(benchArgs, skipValid, wt, it).bench(vm, opts=vmArgs)
965 965
966 def hsdis(args, copyToDir=None): 966 def hsdis(args, copyToDir=None):
967 """downloads the hsdis library 967 """downloads the hsdis library
968 968
969 This is needed to support HotSpot's assembly dumping features. 969 This is needed to support HotSpot's assembly dumping features.
970 By default it downloads the Intel syntax version, use the 'att' argument to install AT&T syntax.""" 970 By default it downloads the Intel syntax version, use the 'att' argument to install AT&T syntax."""
975 path = join(_graal_home, 'lib', lib) 975 path = join(_graal_home, 'lib', lib)
976 if not exists(path): 976 if not exists(path):
977 mx.download(path, ['http://lafo.ssw.uni-linz.ac.at/hsdis/' + flavor + "/" + lib]) 977 mx.download(path, ['http://lafo.ssw.uni-linz.ac.at/hsdis/' + flavor + "/" + lib])
978 if copyToDir is not None and exists(copyToDir): 978 if copyToDir is not None and exists(copyToDir):
979 shutil.copy(path, copyToDir) 979 shutil.copy(path, copyToDir)
980 980
981 def hcfdis(args): 981 def hcfdis(args):
982 """disassembles HexCodeFiles embedded in text files 982 """disassembles HexCodeFiles embedded in text files
983 983
984 Run a tool over the input files to convert all embedded HexCodeFiles 984 Run a tool over the input files to convert all embedded HexCodeFiles
985 to a disassembled format.""" 985 to a disassembled format."""
998 if len(args) == 1: 998 if len(args) == 1:
999 out = args[0] 999 out = args[0]
1000 elif len(args) > 1: 1000 elif len(args) > 1:
1001 mx.abort('jacocoreport takes only one argument : an output directory') 1001 mx.abort('jacocoreport takes only one argument : an output directory')
1002 mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out]) 1002 mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out])
1003 1003
1004 def _fix_overview_summary(path, topLink): 1004 def _fix_overview_summary(path, topLink):
1005 """ 1005 """
1006 Processes an "overview-summary.html" generated by javadoc to put the complete 1006 Processes an "overview-summary.html" generated by javadoc to put the complete
1007 summary text above the Packages table. 1007 summary text above the Packages table.
1008 """ 1008 """
1009 1009
1010 # This uses scraping and so will break if the relevant content produced by javadoc changes in any way! 1010 # This uses scraping and so will break if the relevant content produced by javadoc changes in any way!
1011 orig = path + '.orig' 1011 with open(path) as fp:
1012 if exists(orig): 1012 content = fp.read()
1013 with open(orig) as fp: 1013
1014 content = fp.read()
1015 else:
1016 with open(path) as fp:
1017 content = fp.read()
1018 with open(orig, 'w') as fp:
1019 fp.write(content)
1020
1021 class Chunk: 1014 class Chunk:
1022 def __init__(self, content, ldelim, rdelim): 1015 def __init__(self, content, ldelim, rdelim):
1023 lindex = content.find(ldelim) 1016 lindex = content.find(ldelim)
1024 rindex = content.find(rdelim) 1017 rindex = content.find(rdelim)
1025 self.ldelim = ldelim 1018 self.ldelim = ldelim
1026 self.rdelim = rdelim 1019 self.rdelim = rdelim
1027 if lindex != -1 and rindex != -1 and rindex > lindex: 1020 if lindex != -1 and rindex != -1 and rindex > lindex:
1028 self.text = content[lindex + len(ldelim):rindex] 1021 self.text = content[lindex + len(ldelim):rindex]
1029 else: 1022 else:
1030 self.text = None 1023 self.text = None
1031 1024
1032 def replace(self, content, repl): 1025 def replace(self, content, repl):
1033 lindex = content.find(self.ldelim) 1026 lindex = content.find(self.ldelim)
1034 rindex = content.find(self.rdelim) 1027 rindex = content.find(self.rdelim)
1035 old = content[lindex:rindex + len(self.rdelim)] 1028 old = content[lindex:rindex + len(self.rdelim)]
1036 return content.replace(old, repl) 1029 return content.replace(old, repl)
1037 1030
1038 chunk1 = Chunk(content, """<div class="header"> 1031 chunk1 = Chunk(content, """<div class="header">
1039 <div class="subTitle"> 1032 <div class="subTitle">
1040 <div class="block">""", """</div> 1033 <div class="block">""", """</div>
1041 </div> 1034 </div>
1042 <p>See: <a href="#overview_description">Description</a></p> 1035 <p>See: <a href="#overview_description">Description</a></p>
1043 </div>""") 1036 </div>""")
1044 1037
1045 chunk2 = Chunk(content, """<div class="footer"><a name="overview_description"> 1038 chunk2 = Chunk(content, """<div class="footer"><a name="overview_description">
1046 <!-- --> 1039 <!-- -->
1047 </a> 1040 </a>
1048 <div class="subTitle"> 1041 <div class="subTitle">
1049 <div class="block">""", """</div> 1042 <div class="block">""", """</div>
1050 </div> 1043 </div>
1051 </div> 1044 </div>
1052 <!-- ======= START OF BOTTOM NAVBAR ====== -->""") 1045 <!-- ======= START OF BOTTOM NAVBAR ====== -->""")
1053 1046
1054 if not chunk1.text: 1047 assert chunk1.text, 'Could not find header section in ' + path
1055 mx.log('Could not find header section in ' + path) 1048 assert chunk2.text, 'Could not find footer section in ' + path
1056 return
1057
1058 if not chunk2.text:
1059 mx.log('Could not find footer section in ' + path)
1060 return
1061 1049
1062 content = chunk1.replace(content, '<div class="header"><div class="subTitle"><div class="block">' + topLink + chunk2.text +'</div></div></div>') 1050 content = chunk1.replace(content, '<div class="header"><div class="subTitle"><div class="block">' + topLink + chunk2.text +'</div></div></div>')
1063 content = chunk2.replace(content, '') 1051 content = chunk2.replace(content, '')
1064 1052
1065 with open(path, 'w') as fp: 1053 with open(path, 'w') as fp:
1066 fp.write(content) 1054 fp.write(content)
1067 1055
1068 def site(args): 1056 def site(args):
1069 """creates a website containing javadoc and the project dependency graph""" 1057 """creates a website containing javadoc and the project dependency graph"""
1070 1058
1071 parser = ArgumentParser(prog='site') 1059 parser = ArgumentParser(prog='site')
1072 parser.add_argument('-d', '--base', action='store', help='directory for generated site', required=True, metavar='<dir>') 1060 parser.add_argument('-d', '--base', action='store', help='directory for generated site', required=True, metavar='<dir>')
1073 parser.add_argument('-c', '--clean', action='store_true', help='remove existing site in <dir>')
1074 parser.add_argument('-t', '--test', action='store_true', help='omit the Javadoc execution (useful for testing)')
1075 1061
1076 args = parser.parse_args(args) 1062 args = parser.parse_args(args)
1077 1063
1078 args.base = os.path.abspath(args.base) 1064 args.base = os.path.abspath(args.base)
1079 1065 tmpbase = tempfile.mkdtemp(prefix=basename(args.base) + '.', dir=dirname(args.base))
1080 if not exists(args.base): 1066 unified = join(tmpbase, 'all')
1081 os.mkdir(args.base) 1067
1082 elif args.clean: 1068 try:
1083 shutil.rmtree(args.base)
1084 os.mkdir(args.base)
1085
1086 unified = join(args.base, 'all')
1087
1088 if not args.test:
1089 # Create javadoc for each project 1069 # Create javadoc for each project
1090 mx.javadoc(['--base', args.base]) 1070 mx.javadoc(['--base', tmpbase])
1091 1071
1092 # Create unified javadoc for all projects 1072 # Create unified javadoc for all projects
1093 if exists(unified): 1073 mx.javadoc(['--base', tmpbase,
1094 shutil.rmtree(unified)
1095 mx.javadoc(['--base', args.base,
1096 '--unified', 1074 '--unified',
1097 '--arg', '@-windowtitle', '--arg', '@Graal OpenJDK Project Documentation', 1075 '--arg', '@-windowtitle', '--arg', '@Graal OpenJDK Project Documentation',
1098 '--arg', '@-doctitle', '--arg', '@Graal OpenJDK Project Documentation', 1076 '--arg', '@-doctitle', '--arg', '@Graal OpenJDK Project Documentation',
1099 '--arg', '@-overview', '--arg', '@' + join(_graal_home, 'graal', 'overview.html')]) 1077 '--arg', '@-overview', '--arg', '@' + join(_graal_home, 'graal', 'overview.html')])
1100 os.rename(join(args.base, 'javadoc'), unified) 1078 os.rename(join(tmpbase, 'javadoc'), unified)
1101 1079
1102 # Generate dependency graph with Graphviz 1080 # Generate dependency graph with Graphviz
1103 _, tmp = tempfile.mkstemp() 1081 _, tmp = tempfile.mkstemp()
1104 try: 1082 try:
1105 svg = join(args.base, 'all', 'modules.svg') 1083 svg = join(tmpbase, 'all', 'modules.svg')
1106 jpg = join(args.base, 'all', 'modules.jpg') 1084 jpg = join(tmpbase, 'all', 'modules.jpg')
1107 with open(tmp, 'w') as fp: 1085 with open(tmp, 'w') as fp:
1108 print >> fp, 'digraph projects {' 1086 print >> fp, 'digraph projects {'
1109 print >> fp, 'rankdir=BT;' 1087 print >> fp, 'rankdir=BT;'
1110 print >> fp, 'size = "13,13";' 1088 print >> fp, 'size = "13,13";'
1111 print >> fp, 'node [shape=rect, fontcolor="blue"];' 1089 print >> fp, 'node [shape=rect, fontcolor="blue"];'
1112 #print >> fp, 'edge [color="green"];' 1090 #print >> fp, 'edge [color="green"];'
1113 for p in mx.projects(): 1091 for p in mx.projects():
1114 print >> fp, '"' + p.name + '" [URL = "../' + p.name + '/javadoc/index.html", target = "_top"]' 1092 print >> fp, '"' + p.name + '" [URL = "../' + p.name + '/javadoc/index.html", target = "_top"]'
1115 for dep in p.canonical_deps(): 1093 for dep in p.canonical_deps():
1116 if mx.project(dep, False): 1094 if mx.project(dep, False):
1117 print >> fp, '"' + p.name + '" -> "' + dep + '"' 1095 print >> fp, '"' + p.name + '" -> "' + dep + '"'
1118 depths = dict() 1096 depths = dict()
1119 for p in mx.projects(): 1097 for p in mx.projects():
1120 d = p.max_depth() 1098 d = p.max_depth()
1121 depths.setdefault(d, list()).append(p.name) 1099 depths.setdefault(d, list()).append(p.name)
1122 for d, names in depths.iteritems(): 1100 for d, names in depths.iteritems():
1123 print >> fp, '{ rank = same; "' + '"; "'.join(names) + '"; }' 1101 print >> fp, '{ rank = same; "' + '"; "'.join(names) + '"; }'
1124 print >> fp, '}' 1102 print >> fp, '}'
1125 1103
1126 mx.run(['dot', '-Tsvg', '-o' + svg, '-Tjpg', '-o' + jpg, tmp]) 1104 mx.run(['dot', '-Tsvg', '-o' + svg, '-Tjpg', '-o' + jpg, tmp])
1127 1105
1106 finally:
1107 os.remove(tmp)
1108
1109 # Post-process generated SVG to remove title elements which most browsers
1110 # render as redundant (and annoying) tooltips.
1111 with open(svg, 'r') as fp:
1112 content = fp.read()
1113 content = re.sub('<title>.*</title>', '', content)
1114 content = re.sub('xlink:title="[^"]*"', '', content)
1115 with open(svg, 'w') as fp:
1116 fp.write(content)
1117
1118 # Post-process generated overview-summary.html files
1119 top = join(tmpbase, 'all', 'overview-summary.html')
1120 for root, _, files in os.walk(tmpbase):
1121 for f in files:
1122 if f == 'overview-summary.html':
1123 path = join(root, f)
1124 topLink = ''
1125 if top != path:
1126 link = os.path.relpath(join(tmpbase, 'all', 'index.html'), dirname(path))
1127 topLink = '<p><a href="' + link + '", target="_top"><b>[return to the overall Graal documentation]</b></a></p>'
1128 _fix_overview_summary(path, topLink)
1129
1130
1131 if exists(args.base):
1132 shutil.rmtree(args.base)
1133 shutil.move(tmpbase, args.base)
1134
1135 print 'Created website - root is ' + join(args.base, 'all', 'index.html')
1136
1128 finally: 1137 finally:
1129 os.remove(tmp) 1138 if exists(tmpbase):
1130 1139 shutil.rmtree(tmpbase)
1131 # Post-process generated SVG to remove title elements which most browsers 1140
1132 # render as redundant (and annoying) tooltips.
1133 with open(svg, 'r') as fp:
1134 content = fp.read()
1135 content = re.sub('<title>.*</title>', '', content)
1136 content = re.sub('xlink:title="[^"]*"', '', content)
1137 with open(svg, 'w') as fp:
1138 fp.write(content)
1139
1140 # Post-process generated overview-summary.html files
1141 top = join(args.base, 'all', 'overview-summary.html')
1142 for root, _, files in os.walk(args.base):
1143 for f in files:
1144 if f == 'overview-summary.html':
1145 path = join(root, f)
1146 topLink = ''
1147 if top != path:
1148 link = os.path.relpath(join(args.base, 'all', 'index.html'), dirname(path))
1149 topLink = '<p><a href="' + link + '", target="_top">[return to the overall Graal documentation]</a></p>'
1150 _fix_overview_summary(path, topLink)
1151
1152 print 'Created website - root is ' + join(unified, 'index.html')
1153
1154 def mx_init(): 1141 def mx_init():
1155 _vmbuild = 'product' 1142 _vmbuild = 'product'
1156 commands = { 1143 commands = {
1157 'build': [build, '[-options]'], 1144 'build': [build, '[-options]'],
1158 'buildvms': [buildvms, '[-options]'], 1145 'buildvms': [buildvms, '[-options]'],
1175 'site' : [site, '[-options]'], 1162 'site' : [site, '[-options]'],
1176 'vm': [vm, '[-options] class [args...]'], 1163 'vm': [vm, '[-options] class [args...]'],
1177 'vmg': [vmg, '[-options] class [args...]'], 1164 'vmg': [vmg, '[-options] class [args...]'],
1178 'vmfg': [vmfg, '[-options] class [args...]'] 1165 'vmfg': [vmfg, '[-options] class [args...]']
1179 } 1166 }
1180 1167
1181 mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append']) 1168 mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append'])
1182 1169
1183 if (_vmSourcesAvailable): 1170 if (_vmSourcesAvailable):
1184 mx.add_argument('--vm', action='store', dest='vm', default='graal', choices=['graal', 'server', 'client'], help='the VM to build/run (default: graal)') 1171 mx.add_argument('--vm', action='store', dest='vm', default='graal', choices=['graal', 'server', 'client'], help='the VM to build/run (default: graal)')
1185 mx.add_argument('--product', action='store_const', dest='vmbuild', const='product', help='select the product build of the VM') 1172 mx.add_argument('--product', action='store_const', dest='vmbuild', const='product', help='select the product build of the VM')
1186 mx.add_argument('--debug', action='store_const', dest='vmbuild', const='debug', help='select the debug build of the VM') 1173 mx.add_argument('--debug', action='store_const', dest='vmbuild', const='debug', help='select the debug build of the VM')
1187 mx.add_argument('--fastdebug', action='store_const', dest='vmbuild', const='fastdebug', help='select the fast debug build of the VM') 1174 mx.add_argument('--fastdebug', action='store_const', dest='vmbuild', const='fastdebug', help='select the fast debug build of the VM')
1188 mx.add_argument('--ecl', action='store_true', dest='make_eclipse_launch', help='create launch configuration for running VM execution(s) in Eclipse') 1175 mx.add_argument('--ecl', action='store_true', dest='make_eclipse_launch', help='create launch configuration for running VM execution(s) in Eclipse')
1189 1176
1190 commands.update({ 1177 commands.update({
1191 'export': [export, '[-options] [zipfile]'], 1178 'export': [export, '[-options] [zipfile]'],
1192 'build': [build, '[-options] [product|debug|fastdebug]...'] 1179 'build': [build, '[-options] [product|debug|fastdebug]...']
1193 }) 1180 })
1194 1181
1195 mx.commands.update(commands) 1182 mx.commands.update(commands)
1196 1183
1197 def mx_post_parse_cmd_line(opts): 1184 def mx_post_parse_cmd_line(opts):
1198 version = mx.java().version 1185 version = mx.java().version
1199 parts = version.split('.') 1186 parts = version.split('.')
1200 assert len(parts) >= 2 1187 assert len(parts) >= 2
1201 assert parts[0] == '1' 1188 assert parts[0] == '1'
1202 major = int(parts[1]) 1189 major = int(parts[1])
1203 if not major >= 7: 1190 if not major >= 7:
1204 mx.abort('Requires Java version 1.7 or greater, got version ' + version) 1191 mx.abort('Requires Java version 1.7 or greater, got version ' + version)
1205 1192
1206 if (_vmSourcesAvailable): 1193 if (_vmSourcesAvailable):
1207 if hasattr(opts, 'vm') and opts.vm is not None: 1194 if hasattr(opts, 'vm') and opts.vm is not None:
1208 global _vm 1195 global _vm
1209 _vm = opts.vm 1196 _vm = opts.vm
1210 if hasattr(opts, 'vmbuild') and opts.vmbuild is not None: 1197 if hasattr(opts, 'vmbuild') and opts.vmbuild is not None: