comparison mx/mx_graal.py @ 21613:60154926b513

replaced use of javap with a small Java utility for refining service class list to only those implementing com.oracle.jvmci.service.Service
author Doug Simon <doug.simon@oracle.com>
date Sun, 31 May 2015 12:32:15 +0200
parents 71b338926f2e
children 838f005f9aec
comparison
equal deleted inserted replaced
21612:f2a6088ddebc 21613:60154926b513
545 shutil.copyfile(src, tmp) 545 shutil.copyfile(src, tmp)
546 os.close(fd) 546 os.close(fd)
547 shutil.move(tmp, dstLib) 547 shutil.move(tmp, dstLib)
548 os.chmod(dstLib, permissions) 548 os.chmod(dstLib, permissions)
549 549
550 def _eraseGenerics(className): 550 def _filterJVMCIServices(serviceImplNames, classpath):
551 if '<' in className: 551 """
552 return className[:className.index('<')] 552 Filters and returns the names in 'serviceImplNames' that denote
553 return className 553 types available in 'classpath' implementing or extending
554 554 com.oracle.jvmci.service.Service.
555 def _classifyJVMCIServices(classNames, jvmciJars): 555 """
556 classification = {} 556 _, binDir = mx._compile_mx_class('FilterTypes', os.pathsep.join(classpath), myDir=dirname(__file__))
557 if not classNames: 557 cmd = [mx.java().java, '-cp', mx._cygpathU2W(os.pathsep.join([binDir] + classpath)), 'FilterTypes', 'com.oracle.jvmci.service.Service'] + serviceImplNames
558 return classification 558 return subprocess.check_output(cmd, stderr=subprocess.PIPE).split('|')
559 for className in classNames: 559
560 classification[className] = None 560 def _extractJVMCIFiles(jdkJars, jvmciJars, servicesDir, optionsDir, cleanDestination=True):
561 javap = mx.java().javap
562 output = subprocess.check_output([javap, '-cp', os.pathsep.join(jvmciJars)] + classNames, stderr=subprocess.STDOUT)
563 lines = output.split(os.linesep)
564 for line in lines:
565 if line.startswith('public interface '):
566 declLine = line[len('public interface '):].strip()
567 for className in classNames:
568 if declLine.startswith(className):
569 assert classification[className] is None
570 afterName = declLine[len(className):]
571 if not afterName.startswith(' extends '):
572 classification[className] = False
573 break
574 superInterfaces = afterName[len(' extends '):-len(' {')].split(',')
575 if 'com.oracle.jvmci.service.Service' in superInterfaces:
576 classification[className] = True
577 break
578 maybe = [_eraseGenerics(superInterface) for superInterface in superInterfaces]
579 classification[className] = maybe
580 break
581 for className, v in classification.items():
582 if v is None:
583 mx.abort('Could not find interface for service ' + className + ':\n' + output)
584 return classification
585
586 def _extractMaybes(classification):
587 maybes = set()
588 for v in classification.values():
589 if isinstance(v, list):
590 maybes.update(v)
591 return list(maybes)
592
593 def _mergeClassification(classification, newClassification):
594 for className, value in classification.items():
595 if isinstance(value, list):
596 classification[className] = None
597 for superInterface in value:
598 if newClassification[superInterface] is True:
599 classification[className] = True
600 break
601 elif newClassification[superInterface] is False:
602 if classification[className] is None:
603 classification[className] = False
604 else:
605 if not classification[className]:
606 classification[className] = []
607 classification[className].extend(newClassification[superInterface])
608
609 def _filterJVMCIService(classNames, jvmciJars):
610 classification = _classifyJVMCIServices(classNames, jvmciJars)
611 needClassification = _extractMaybes(classification)
612 while needClassification:
613 _mergeClassification(classification, _classifyJVMCIServices(needClassification, jvmciJars))
614 needClassification = _extractMaybes(classification)
615 filtered = []
616 for className in classNames:
617 if classification[className] is True:
618 filtered.append(className)
619 return filtered
620
621 def _extractJVMCIFiles(jvmciJars, servicesDir, optionsDir, cleanDestination=True):
622 if cleanDestination: 561 if cleanDestination:
623 if exists(servicesDir): 562 if exists(servicesDir):
624 shutil.rmtree(servicesDir) 563 shutil.rmtree(servicesDir)
625 if exists(optionsDir): 564 if exists(optionsDir):
626 shutil.rmtree(optionsDir) 565 shutil.rmtree(optionsDir)
651 targetpath = join(optionsDir, filename) 590 targetpath = join(optionsDir, filename)
652 optionsFiles.append(filename) 591 optionsFiles.append(filename)
653 with zf.open(member) as optionsFile, \ 592 with zf.open(member) as optionsFile, \
654 file(targetpath, "wb") as target: 593 file(targetpath, "wb") as target:
655 shutil.copyfileobj(optionsFile, target) 594 shutil.copyfileobj(optionsFile, target)
656 jvmciServices = _filterJVMCIService(servicesMap.keys(), jvmciJars) 595 jvmciServices = _filterJVMCIServices(servicesMap.keys(), jdkJars)
657 for serviceName in jvmciServices: 596 for serviceName in jvmciServices:
658 serviceImpls = servicesMap[serviceName] 597 serviceImpls = servicesMap[serviceName]
659 fd, tmp = tempfile.mkstemp(prefix=serviceName) 598 fd, tmp = tempfile.mkstemp(prefix=serviceName)
660 f = os.fdopen(fd, 'w+') 599 f = os.fdopen(fd, 'w+')
661 for serviceImpl in serviceImpls: 600 for serviceImpl in serviceImpls:
670 def _updateJVMCIFiles(jdkDir): 609 def _updateJVMCIFiles(jdkDir):
671 jreJVMCIDir = join(jdkDir, 'jre', 'lib', 'jvmci') 610 jreJVMCIDir = join(jdkDir, 'jre', 'lib', 'jvmci')
672 jvmciJars = [join(jreJVMCIDir, e) for e in os.listdir(jreJVMCIDir) if e.endswith('.jar')] 611 jvmciJars = [join(jreJVMCIDir, e) for e in os.listdir(jreJVMCIDir) if e.endswith('.jar')]
673 jreGraalServicesDir = join(jreJVMCIDir, 'services') 612 jreGraalServicesDir = join(jreJVMCIDir, 'services')
674 jreGraalOptionsDir = join(jreJVMCIDir, 'options') 613 jreGraalOptionsDir = join(jreJVMCIDir, 'options')
675 _extractJVMCIFiles(jvmciJars, jreGraalServicesDir, jreGraalOptionsDir) 614 _extractJVMCIFiles(_getJdkDeployedJars(jdkDir), jvmciJars, jreGraalServicesDir, jreGraalOptionsDir)
676 615
677 def _patchGraalVersionConstant(dist): 616 def _patchGraalVersionConstant(dist):
678 """ 617 """
679 Patches the constant "@@graal.version@@" in the constant pool of Graal.class 618 Patches the constant "@@graal.version@@" in the constant pool of Graal.class
680 with the computed Graal version string. 619 with the computed Graal version string.
729 if dist.sourcesPath: 668 if dist.sourcesPath:
730 _copyToJdk(dist.sourcesPath, jdkDir) 669 _copyToJdk(dist.sourcesPath, jdkDir)
731 if deployableDist.usesJVMCIClassLoader: 670 if deployableDist.usesJVMCIClassLoader:
732 # deploy service files 671 # deploy service files
733 _updateJVMCIFiles(jdkDir) 672 _updateJVMCIFiles(jdkDir)
673
674 def _getJdkDeployedJars(jdkDir):
675 """
676 Gets jar paths for all deployed distributions in the context of
677 a given JDK directory.
678 """
679 jreLibDir = join(jdkDir, 'jre', 'lib')
680 jars = []
681 for dist in _jdkDeployedDists:
682 jar = basename(mx.distribution(dist.name).path)
683 if dist.isExtension:
684 jars.append(join(jreLibDir, 'ext', jar))
685 elif dist.usesJVMCIClassLoader:
686 jars.append(join(jreLibDir, 'jvmci', jar))
687 else:
688 jars.append(join(jreLibDir, jar))
689 return jars
690
734 691
735 # run a command in the windows SDK Debug Shell 692 # run a command in the windows SDK Debug Shell
736 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None): 693 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None):
737 if respondTo is None: 694 if respondTo is None:
738 respondTo = {} 695 respondTo = {}
890 847
891 defsPath = join(_graal_home, 'make', 'defs.make') 848 defsPath = join(_graal_home, 'make', 'defs.make')
892 with open(defsPath) as fp: 849 with open(defsPath) as fp:
893 defs = fp.read() 850 defs = fp.read()
894 jvmciJars = [] 851 jvmciJars = []
852 jdkJars = []
895 for jdkDist in _jdkDeployedDists: 853 for jdkDist in _jdkDeployedDists:
896 dist = mx.distribution(jdkDist.name) 854 dist = mx.distribution(jdkDist.name)
855 jdkJars.append(join(_graal_home, dist.path))
897 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/' + basename(dist.path) 856 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/' + basename(dist.path)
898 if jdkDist.isExtension: 857 if jdkDist.isExtension:
899 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_EXT_DIR)/' + basename(dist.path) 858 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_EXT_DIR)/' + basename(dist.path)
900 elif jdkDist.usesJVMCIClassLoader: 859 elif jdkDist.usesJVMCIClassLoader:
901 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/' + basename(dist.path) 860 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/' + basename(dist.path)
903 else: 862 else:
904 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/' + basename(dist.path) 863 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/' + basename(dist.path)
905 if defLine not in defs: 864 if defLine not in defs:
906 mx.abort('Missing following line in ' + defsPath + '\n' + defLine) 865 mx.abort('Missing following line in ' + defsPath + '\n' + defLine)
907 shutil.copy(dist.path, opts2.export_dir) 866 shutil.copy(dist.path, opts2.export_dir)
908 services, optionsFiles = _extractJVMCIFiles(jvmciJars, join(opts2.export_dir, 'services'), join(opts2.export_dir, 'options')) 867 services, optionsFiles = _extractJVMCIFiles(jdkJars, jvmciJars, join(opts2.export_dir, 'services'), join(opts2.export_dir, 'options'))
909 for service in services: 868 for service in services:
910 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/' + service 869 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/' + service
911 if defLine not in defs: 870 if defLine not in defs:
912 mx.abort('Missing following line in ' + defsPath + ' for service from ' + dist.name + '\n' + defLine) 871 mx.abort('Missing following line in ' + defsPath + ' for service from ' + dist.name + '\n' + defLine)
913 for optionsFile in optionsFiles: 872 for optionsFile in optionsFiles: